Каков рекомендуемый шаблон проектирования, чтобы избежать исключений нулевого указателя в ссылках внутри исполняемого файла при вызове removeCallbacks()

Ссылка на код ниже. myRatingBar.setRating и myHandler.postDelayed в runnable время от времени получают исключение нулевого указателя после вызова 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 выполнялся в runnable. Идея в целом та же. Что-то все еще выполняется в runnable, когда stop() устанавливает для него значение null.

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(ValueAnimat or.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(Ac tivityThread.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)


person Captain Kirk    schedule 07.08.2015    source источник
comment
Чего именно вы пытаетесь достичь этим кодом? Трудно предоставить решение, так как проблема не определена.   -  person Egor    schedule 07.08.2015
comment
Добавлена ​​трассировка стека. Я пытаюсь обеспечить, чтобы ссылки обнулялись, когда происходит остановка, чтобы избежать удержания памяти. В основном мне нужно убедиться, что runnables не выполняются, когда я устанавливаю null. Я предполагал, что removeCallback гарантирует это, но это не так.   -  person Captain Kirk    schedule 08.08.2015


Ответы (1)


Я должен представить, что есть лучший способ. Если у кого-то есть лучший ответ, чем то, что я делаю, чтобы действительно «скрыть» проблему, пожалуйста, просветите меня. Вот чем я сейчас позорно занимаюсь.

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;
}
person Captain Kirk    schedule 09.08.2015