Android AsyncTask контекстное поведение

Я работал с AsyncTasks в Android, и я имею дело с проблемой.

Возьмите простой пример, Activity с одним AsyncTask. Задание на заднем плане не делает ничего впечатляющего, оно просто спит 8 секунд.

В конце AsyncTask в методе onPostExecute () я просто устанавливаю статус видимости кнопки в View.VISIBLE, только чтобы проверить мои результаты.

Теперь это прекрасно работает, пока пользователь не решит изменить ориентацию своих телефонов во время работы AsyncTask (в пределах 8-секундного окна ожидания).

Я понимаю жизненный цикл активности Android и знаю, что активность разрушается и воссоздается.

Вот где возникает проблема. AsyncTask ссылается на кнопку и, очевидно, содержит ссылку на контекст, который первым запустил AsyncTask.

Я ожидаю, что этот старый контекст (поскольку пользователь вызвал изменение ориентации) либо станет нулевым, либо AsyncTask сгенерирует NPE для ссылки на кнопку, которую он пытается сделать видимой.

Вместо этого не генерируется NPE, AsyncTask считает, что ссылка на кнопку не является нулевой, устанавливает его в видимое состояние. Результат? На экране ничего не происходит!

Обновить: Я решил это, сохраняяWeakReference к активности и переключению, когда происходит изменение конфигурации. Это громоздко

Вот код:

public class Main extends Activity {

    private Button mButton = null;
    private Button mTestButton = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mButton = (Button) findViewById(R.id.btnStart);
        mButton.setOnClickListener(new OnClickListener () {
            @Override
            public void onClick(View v) {
                new taskDoSomething().execute(0l);
            }
        });
        mTestButton = (Button) findViewById(R.id.btnTest);   
    }

    private class TaskDoSomething extends AsyncTask<Long, Integer, Integer> 
    {
        @Override
        protected Integer doInBackground(Long... params) {
            Log.i("LOGGER", "Starting...");
            try {
                Thread.sleep(8000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 0;
        }

        @Override
        protected void onPostExecute(Integer result) {
            Log.i("LOGGER", "...Done");
            mTestButton.setVisibility(View.VISIBLE);
        }
    }
}

Попробуйте выполнить его, и пока AsyncTask работает, измените ориентацию вашего телефона.

Ответы на вопрос(4)

Ваш ответ на вопрос