在调用 removeCallbacks() 时,避免可运行对象内的引用出现空指针异常的推荐设计模式是什么
What is the recommended design pattern to avoid null pointer exceptions on references within a runnable when calling removeCallbacks()
引用下面的代码。 runnable 中的 myRatingBar.setRating 和 myHandler.postDelayed 在调用 stop() 后偶尔会出现空指针异常。我不确定避免这种情况的最佳方法是什么。如果可运行对象包含具有侦听器的对象并且侦听器具有引用,则问题只会变得更糟。
private Handler myHandler;
private Runnable myRunnable;
private RatingBar myRatingBar;
public void start()
{
myRunnable = new Runnable()
{
public void run()
{
myRatingBar.setRating(1);
myHandler.postDelayed(this, 1000);
}
}
myHandler = new Handler();
myHandler.postDelayed(myRunnable, 0);
}
public void stop()
{
if(myHandler != null)
{
myHandler.removeCallbacksAndMessages(null);
myHandler = null;
}
myRunnable = null;
myRatingBar = null;
}
添加堆栈跟踪。在此堆栈跟踪中,ValueAnimator onAnimationUpdate 在可运行对象中执行。总体思路是一样的。当 stop() 将其设置为 null 时,runnable 中仍在执行某些内容。
08-07 13:53:21.161: E/AndroidRuntime(20183): 致命异常: main
08-07 13:53:21.161: E/AndroidRuntime(20183): 进程: com.myprocess.myprocess, PID: 20183
08-07 13:53:21.161: E/AndroidRuntime(20183): java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'void android.widget.RatingBar.setLayoutParams(android.view.ViewGroup$LayoutParams)'
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 com.myprocess.myprocess.MyClass2$6$2.onAnimationUpdate(MyClass.java:487)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.animation.ValueAnimator.animateValue(ValueAnimator.java:1283)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.animation.ValueAnimator.animationFrame(ValueAnimator.java:1207)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1248)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.animation.ValueAnimator$AnimationHandler.doAnimationFrame(ValueAnimator.java:659)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.animation.ValueAnimator$AnimationHandler.run(ValueAnimator.java:682)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.view.Choreographer.doCallbacks(Choreographer.java:590)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.view.Choreographer.doFrame(Choreographer.java:559)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.os.Handler.handleCallback(Handler.java:739)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.os.Handler.dispatchMessage(Handler.java:95)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.os.Looper.loop(Looper.java:145)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.app.ActivityThread.main(ActivityThread.java:6141)
08-07 13:53:21.161:E/AndroidRuntime(20183):在 java.lang.reflect.Method.invoke(本机方法)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 java.lang.reflect.Method.invoke(Method.java:372)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
08-07 13:53:21.161: E/AndroidRuntime(20183): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
我不得不想象有更好的方法。如果有人有比我正在做的更好的答案 "cover up" 这个问题,请赐教。这是我现在可耻地做的事情。
private Handler myHandler;
private Runnable myRunnable;
private RatingBar myRatingBar;
public void start()
{
myRunnable = new Runnable()
{
public void run()
{
try
{
myRatingBar.setRating(1);
if(myHandler != null)
{
myHandler.postDelayed(this, 1000);
}
}
catch(Exception e)
{
// do nothing
}
}
}
myHandler = new Handler();
myHandler.postDelayed(myRunnable, 0);
}
public void stop()
{
if(myHandler != null)
{
myHandler.removeCallbacksAndMessages(null);
myHandler = null;
}
myRunnable = null;
myRatingBar = null;
}
引用下面的代码。 runnable 中的 myRatingBar.setRating 和 myHandler.postDelayed 在调用 stop() 后偶尔会出现空指针异常。我不确定避免这种情况的最佳方法是什么。如果可运行对象包含具有侦听器的对象并且侦听器具有引用,则问题只会变得更糟。
private Handler myHandler;
private Runnable myRunnable;
private RatingBar myRatingBar;
public void start()
{
myRunnable = new Runnable()
{
public void run()
{
myRatingBar.setRating(1);
myHandler.postDelayed(this, 1000);
}
}
myHandler = new Handler();
myHandler.postDelayed(myRunnable, 0);
}
public void stop()
{
if(myHandler != null)
{
myHandler.removeCallbacksAndMessages(null);
myHandler = null;
}
myRunnable = null;
myRatingBar = null;
}
添加堆栈跟踪。在此堆栈跟踪中,ValueAnimator onAnimationUpdate 在可运行对象中执行。总体思路是一样的。当 stop() 将其设置为 null 时,runnable 中仍在执行某些内容。
08-07 13:53:21.161: E/AndroidRuntime(20183): 致命异常: main 08-07 13:53:21.161: E/AndroidRuntime(20183): 进程: com.myprocess.myprocess, PID: 20183 08-07 13:53:21.161: E/AndroidRuntime(20183): java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'void android.widget.RatingBar.setLayoutParams(android.view.ViewGroup$LayoutParams)' 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 com.myprocess.myprocess.MyClass2$6$2.onAnimationUpdate(MyClass.java:487) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.animation.ValueAnimator.animateValue(ValueAnimator.java:1283) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.animation.ValueAnimator.animationFrame(ValueAnimator.java:1207) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1248) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.animation.ValueAnimator$AnimationHandler.doAnimationFrame(ValueAnimator.java:659) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.animation.ValueAnimator$AnimationHandler.run(ValueAnimator.java:682) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.view.Choreographer$CallbackRecord.run(Choreographer.java:777) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.view.Choreographer.doCallbacks(Choreographer.java:590) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.view.Choreographer.doFrame(Choreographer.java:559) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.os.Handler.handleCallback(Handler.java:739) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.os.Handler.dispatchMessage(Handler.java:95) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.os.Looper.loop(Looper.java:145) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 android.app.ActivityThread.main(ActivityThread.java:6141) 08-07 13:53:21.161:E/AndroidRuntime(20183):在 java.lang.reflect.Method.invoke(本机方法) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 java.lang.reflect.Method.invoke(Method.java:372) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) 08-07 13:53:21.161: E/AndroidRuntime(20183): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
我不得不想象有更好的方法。如果有人有比我正在做的更好的答案 "cover up" 这个问题,请赐教。这是我现在可耻地做的事情。
private Handler myHandler;
private Runnable myRunnable;
private RatingBar myRatingBar;
public void start()
{
myRunnable = new Runnable()
{
public void run()
{
try
{
myRatingBar.setRating(1);
if(myHandler != null)
{
myHandler.postDelayed(this, 1000);
}
}
catch(Exception e)
{
// do nothing
}
}
}
myHandler = new Handler();
myHandler.postDelayed(myRunnable, 0);
}
public void stop()
{
if(myHandler != null)
{
myHandler.removeCallbacksAndMessages(null);
myHandler = null;
}
myRunnable = null;
myRatingBar = null;
}