在调用removeCallbacks()时,建议使用什么设计模式来避免可运行对象中引用的空指针异常?



引用下面的代码。myRatingBar。setRating和myHandler。在调用stop()之后,可运行对象中的postDelayed偶尔会得到空指针异常。我不确定避免这种情况的最好方法是什么。只有当可运行对象包含具有侦听器的对象,并且侦听器有引用时,问题才会恶化。

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()将runnable设置为null时,它仍在执行。

08-07 13:53:21.161: E/AndroidRuntime(20183): FATAL EXCEPTION: main08:07 13:53:21.161: E/AndroidRuntime(20183): Process: com.myprocess。myprocess, PID: 2018308-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): at com.myprocess.myprocess.MyClass2$6$2.onAnimationUpdate(MyClass.java:487)08-07 13:53:21.161: E/AndroidRuntime(20183): at android.animation. valueanimation . animatevalue (valueanimation .java:1283)08-07 13:53:21.161: E/AndroidRuntime(20183): at android.animation. valueanimation . animationframe (valueanimation .java:1207)08-07 13:53:21.161: E/AndroidRuntime(20183): at android.animation. valueanimation . doanimationframe (valueanimation .java:1248)08-07 13:53:21.161: E/AndroidRuntime(20183): at android.animation.ValueAnimator$AnimationHandler.doAnimationFrame(valueanimation .java:659)08-07 13:53:21.161: E/AndroidRuntime(20183): at android.animation.ValueAnimator$AnimationHandler.run(valueanimation .java:682)08-07 13:53:21.161: E/AndroidRuntime(20183): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777)08:07 13:53:21.161: E/AndroidRuntime(20183): at android.view.Choreographer.doCallbacks(Choreographer.java:590)08-07 13:53:21.161: E/AndroidRuntime(20183): at android.view.Choreographer.doFrame(Choreographer.java:559)08-07 13:53:21.161: E/AndroidRuntime(20183): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763)08-07 13:53:21.161: E/AndroidRuntime(20183): at android.os.Handler.handleCallback(Handler.java:739)08-07 13:53:21.161: E/AndroidRuntime(20183): at android.os.Handler.dispatchMessage(Handler.java:95)08-07 13:53:21.161: E/AndroidRuntime(20183): at android.os. loop .loop(loop .java:145)08-07 13:53:21.161: E/AndroidRuntime(20183): at android.app.ActivityThread.main(ActivityThread.java:6141)08-07 13:53:21.161: E/AndroidRuntime(20183): at java.lang.reflect.Method。调用(本地方法)08-07 13:53:21.161: E/AndroidRuntime(20183): at java.lang.reflect.Method.invoke(Method.java:372)08:07 13:53:21.161: E/AndroidRuntime(20183): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)08-07 13:53:21.161: E/AndroidRuntime(20183): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)

我不得不想象有一个更好的方法。如果有人有比我更好的答案来真正"掩盖"问题,请启发我。这就是我现在羞于做的事情。

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;
}

最新更新