Skip to content

Commit 0ee3c53

Browse files
author
laramaki
committed
Fixing memory leak resulting from nonstatic Handler inner class. When switching contexts, android.os.Message objects sent to previously instantiated handlers were holding references to target handler, hence holding a reference to its outer class, and thus leaking the caller activity.
1 parent b45b7f3 commit 0ee3c53

File tree

1 file changed

+33
-23
lines changed

1 file changed

+33
-23
lines changed

src/cn/trinea/android/view/autoscrollviewpager/AutoScrollViewPager.java

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package cn.trinea.android.view.autoscrollviewpager;
22

3-
import java.lang.reflect.Field;
4-
53
import android.content.Context;
64
import android.os.Handler;
75
import android.os.Message;
@@ -12,6 +10,9 @@
1210
import android.view.MotionEvent;
1311
import android.view.animation.Interpolator;
1412

13+
import java.lang.ref.WeakReference;
14+
import java.lang.reflect.Field;
15+
1516
/**
1617
* Auto Scroll View Pager
1718
* <ul>
@@ -28,7 +29,7 @@
2829
* <li>{@link #setSlideBorderMode(int)} set how to process when sliding at the last or first item</li>
2930
* <li>{@link #setStopScrollWhenTouch(boolean)} set whether stop auto scroll when touching, default is true</li>
3031
* </ul>
31-
*
32+
*
3233
* @author <a href="http://www.trinea.cn" target="_blank">Trinea</a> 2013-12-30
3334
*/
3435
public class AutoScrollViewPager extends ViewPager {
@@ -80,8 +81,8 @@ public AutoScrollViewPager(Context paramContext, AttributeSet paramAttributeSet)
8081
init();
8182
}
8283

83-
private void init() {
84-
handler = new MyHandler();
84+
private void init() {
85+
handler = new MyHandler(this);
8586
setViewPagerScroller();
8687
}
8788

@@ -95,7 +96,7 @@ public void startAutoScroll() {
9596

9697
/**
9798
* start auto scroll
98-
*
99+
*
99100
* @param delayTimeInMills first scroll delay time
100101
*/
101102
public void startAutoScroll(int delayTimeInMills) {
@@ -224,18 +225,27 @@ public boolean dispatchTouchEvent(MotionEvent ev) {
224225
return super.dispatchTouchEvent(ev);
225226
}
226227

227-
private class MyHandler extends Handler {
228+
private static class MyHandler extends Handler {
229+
230+
private final WeakReference<AutoScrollViewPager> autoScrollViewPager;
231+
232+
public MyHandler(AutoScrollViewPager autoScrollViewPager) {
233+
this.autoScrollViewPager = new WeakReference<AutoScrollViewPager>(autoScrollViewPager);
234+
}
228235

229236
@Override
230237
public void handleMessage(Message msg) {
231238
super.handleMessage(msg);
232239

233240
switch (msg.what) {
234241
case SCROLL_WHAT:
235-
scroller.setScrollDurationFactor(autoScrollFactor);
236-
scrollOnce();
237-
scroller.setScrollDurationFactor(swipeScrollFactor);
238-
sendScrollMessage(interval + scroller.getDuration());
242+
AutoScrollViewPager pager = this.autoScrollViewPager.get();
243+
if (pager != null) {
244+
pager.scroller.setScrollDurationFactor(pager.autoScrollFactor);
245+
pager.scrollOnce();
246+
pager.scroller.setScrollDurationFactor(pager.swipeScrollFactor);
247+
pager.sendScrollMessage(pager.interval + pager.scroller.getDuration());
248+
}
239249
default:
240250
break;
241251
}
@@ -244,7 +254,7 @@ public void handleMessage(Message msg) {
244254

245255
/**
246256
* get auto scroll time in milliseconds, default is {@link #DEFAULT_INTERVAL}
247-
*
257+
*
248258
* @return the interval
249259
*/
250260
public long getInterval() {
@@ -253,7 +263,7 @@ public long getInterval() {
253263

254264
/**
255265
* set auto scroll time in milliseconds, default is {@link #DEFAULT_INTERVAL}
256-
*
266+
*
257267
* @param interval the interval to set
258268
*/
259269
public void setInterval(long interval) {
@@ -262,7 +272,7 @@ public void setInterval(long interval) {
262272

263273
/**
264274
* get auto scroll direction
265-
*
275+
*
266276
* @return {@link #LEFT} or {@link #RIGHT}, default is {@link #RIGHT}
267277
*/
268278
public int getDirection() {
@@ -271,7 +281,7 @@ public int getDirection() {
271281

272282
/**
273283
* set auto scroll direction
274-
*
284+
*
275285
* @param direction {@link #LEFT} or {@link #RIGHT}, default is {@link #RIGHT}
276286
*/
277287
public void setDirection(int direction) {
@@ -280,7 +290,7 @@ public void setDirection(int direction) {
280290

281291
/**
282292
* whether automatic cycle when auto scroll reaching the last or first item, default is true
283-
*
293+
*
284294
* @return the isCycle
285295
*/
286296
public boolean isCycle() {
@@ -289,7 +299,7 @@ public boolean isCycle() {
289299

290300
/**
291301
* set whether automatic cycle when auto scroll reaching the last or first item, default is true
292-
*
302+
*
293303
* @param isCycle the isCycle to set
294304
*/
295305
public void setCycle(boolean isCycle) {
@@ -298,7 +308,7 @@ public void setCycle(boolean isCycle) {
298308

299309
/**
300310
* whether stop auto scroll when touching, default is true
301-
*
311+
*
302312
* @return the stopScrollWhenTouch
303313
*/
304314
public boolean isStopScrollWhenTouch() {
@@ -307,7 +317,7 @@ public boolean isStopScrollWhenTouch() {
307317

308318
/**
309319
* set whether stop auto scroll when touching, default is true
310-
*
320+
*
311321
* @param stopScrollWhenTouch
312322
*/
313323
public void setStopScrollWhenTouch(boolean stopScrollWhenTouch) {
@@ -316,7 +326,7 @@ public void setStopScrollWhenTouch(boolean stopScrollWhenTouch) {
316326

317327
/**
318328
* get how to process when sliding at the last or first item
319-
*
329+
*
320330
* @return the slideBorderMode {@link #SLIDE_BORDER_MODE_NONE}, {@link #SLIDE_BORDER_MODE_TO_PARENT},
321331
* {@link #SLIDE_BORDER_MODE_CYCLE}, default is {@link #SLIDE_BORDER_MODE_NONE}
322332
*/
@@ -326,7 +336,7 @@ public int getSlideBorderMode() {
326336

327337
/**
328338
* set how to process when sliding at the last or first item
329-
*
339+
*
330340
* @param slideBorderMode {@link #SLIDE_BORDER_MODE_NONE}, {@link #SLIDE_BORDER_MODE_TO_PARENT},
331341
* {@link #SLIDE_BORDER_MODE_CYCLE}, default is {@link #SLIDE_BORDER_MODE_NONE}
332342
*/
@@ -336,7 +346,7 @@ public void setSlideBorderMode(int slideBorderMode) {
336346

337347
/**
338348
* whether animating when auto scroll at the last or first item, default is true
339-
*
349+
*
340350
* @return
341351
*/
342352
public boolean isBorderAnimation() {
@@ -345,7 +355,7 @@ public boolean isBorderAnimation() {
345355

346356
/**
347357
* set whether animating when auto scroll at the last or first item, default is true
348-
*
358+
*
349359
* @param isBorderAnimation
350360
*/
351361
public void setBorderAnimation(boolean isBorderAnimation) {

0 commit comments

Comments
 (0)