Я столкнулся с необычным исключением NPE в Android с обработчиком и фоновым потоком.
Я знаю, что при уничтожении активности или фрагмента виджет пользовательского интерфейса будет уничтожен, поэтому вы должны отменить все ожидающие сообщения или запускаемые сообщения, отправленные из фона.
Например, в обратном вызове фрагмента onDestroyView
я вызываю обработчик removeCallbacksAndMessages(null)
, чтобы удалить все обратные вызовы. Но в некоторых случаях обратный вызов все же выполнялся, но в это время пользовательский интерфейс уничтожался, NPE выбрасывало.
Ниже приведен образец:
public class SampleFragment extends Fragment {
private Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {
switch (msg.what) {
// do your job
}
}
};
@Nullable @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// create some ui
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
new Thread(new Runnable() {
@Override public void run() {
// after a long running work
mHandler.post(new Runnable() {
@Override public void run() {
// OOPS, the ui widget may null!
}
});
}
}).start();
}
@Override public void onDestroyView() {
mHandler.removeCallbacksAndMessages(null);
super.onDestroyView();
}
}
В какой-то момент я заметил, что в onDestroyView
обработчик удалил все ожидающие сообщения или исполняемые файлы, которые будут прикреплены к потоку пользовательского интерфейса, а представление установлено равным нулю, чтобы быть gc. Но поток может все еще находиться в рабочем состоянии, и обработчик опубликует исполняемый, но представление будет нулевым.
Самый простой способ — проверить null из фрагмента getView()
в runnable, но если во всей этой ситуации нужно проверять null, это было бы утомительно. Есть ли хороший подход к решению такой проблемы?
Спасибо заранее.
onDestroyView
? - person ρяσѕρєя K   schedule 28.01.2015