Я запускаю AsyncTask в методе onStart(), потому что я хочу, чтобы он всегда перезагружал данные из базы данных SQLite, когда пользователь возвращается к этому фрагменту. Это потому, что это ListFragment, и щелчок по элементу приводит к появлению другого фрагмента в двухпанельном макете на планшетах или в Activity, который использует ViewPager для всех элементов в списке. В последнем случае мне нужно перезагрузить элементы, потому что пользователь может удалять элементы из ViewPager.API 8 - AsyncTask NullPointerException после 2 вращений
Теперь я тестирую свои макеты на разных устройствах и API.
На Froyo (API 8) NexusOne AVD, если я поворачиваю экран один раз, он снова запускает AsyncTask и повторно отображает данные. Если я сделаю это снова, я получаю исключение NullPointerException. Этого не происходит, когда я запускаю другой AVD, используя API 10+ (я могу повернуть дисплей, который мне нужен). Я даю ему много времени, чтобы завершить первое вращение, прежде чем делать второе.
Здесь LogCat:
11-14 21:03:46.485: E/AndroidRuntime(326): FATAL EXCEPTION: main
11-14 21:03:46.485: E/AndroidRuntime(326): java.lang.NullPointerException
11-14 21:03:46.485: E/AndroidRuntime(326): at android.widget.ArrayAdapter.init(ArrayAdapter.java:271)
11-14 21:03:46.485: E/AndroidRuntime(326): at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:150)
11-14 21:03:46.485: E/AndroidRuntime(326): at com.android.myapp.MyListFragment$MyAdapter.<init>(MyListFragment.java:279)
11-14 21:03:46.485: E/AndroidRuntime(326): at com.android.myapp.MyListFragment$getMyAsync.onPostExecute(MyListFragment.java:393)
11-14 21:03:46.485: E/AndroidRuntime(326): at com.android.myapp.MyListFragment$getMyAsync.onPostExecute(MyListFragment.java:1)
11-14 21:03:46.485: E/AndroidRuntime(326): at android.os.AsyncTask.finish(AsyncTask.java:417)
11-14 21:03:46.485: E/AndroidRuntime(326): at android.os.AsyncTask.access$300(AsyncTask.java:127)
11-14 21:03:46.485: E/AndroidRuntime(326): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
11-14 21:03:46.485: E/AndroidRuntime(326): at android.os.Handler.dispatchMessage(Handler.java:99)
11-14 21:03:46.485: E/AndroidRuntime(326): at android.os.Looper.loop(Looper.java:123)
11-14 21:03:46.485: E/AndroidRuntime(326): at android.app.ActivityThread.main(ActivityThread.java:4627)
11-14 21:03:46.485: E/AndroidRuntime(326): at java.lang.reflect.Method.invokeNative(Native Method)
11-14 21:03:46.485: E/AndroidRuntime(326): at java.lang.reflect.Method.invoke(Method.java:521)
11-14 21:03:46.485: E/AndroidRuntime(326): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-14 21:03:46.485: E/AndroidRuntime(326): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-14 21:03:46.485: E/AndroidRuntime(326): at dalvik.system.NativeStart.main(Native Method)
MyListFragment.java:279 является призыв к ArrayAdapter .constructor [EDIT]
super(context, 0, myListArray);
onPostExecute (MyListFragment.java:393 это :
mAdapter = new MyAdapter(getActivity(), myListArray);
Вышеупомянутый не получает exe cuted, если myListArray имеет значение null.
Я добавил это выше этой инструкции:
if (getActivity() == null) {
Log.d(TAG, "getActivity() is null");
}
getActivity() возвращает нуль на API 8 устройства!
Это просто ошибка с тестовой средой Eclipse/ADT и/или AVD? Или это произойдет на реальных телефонах тоже?
Спасибо.
РЕДАКТИРОВАТЬ
Метод для запуска AsyncTask:
@Override
public void onStart() {
super.onStart();
mProgressBarLayout.setVisibility(View.VISIBLE);
new getListAsync().execute(mType);
}
AsyncTask (внутренний частный класс ListFragment):
private class getListAsync extends AsyncTask<EFFECT_TYPE, Void, List<Item>> {
@Override
protected List<Item> doInBackground(EFFECT_TYPE... params) {
List<Item> items;
items = DatabaseManager.get(getActivity()).getItems(params[0]);
return items;
}
@Override
protected void onPostExecute(List<Item> result) {
super.onPostExecute(result);
mProgressBarLayout.setVisibility(View.GONE);
mItemList = result;
if (mItemList != null) {
if (getActivity() == null) {
Log.d(TAG, "getActivity() is null"); <---- THIS GETS LOGGED ON THE 2nd ROTATE!
}
393 -----------> mAdapter = new MyAdapter(getActivity(), mItemList);
setListAdapter(mAdapter);
}
}
}
РЕДАКТИРОВАТЬ # 2
Ну, это невозможно.
У меня уже есть onAttach(), так что я сделал это:
Добавить новую переменную MyListFragment:
private Activity mParentActivity = null;
Modified onAttach():
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mCallbacks = (Callbacks) activity;
mParentActivity = activity;
if (mParentActivity == null) {
Log.d(TAG, "onAttach() called with null Activity");
}
}
onPostExecute:
@Override
protected void onPostExecute(List<Item> result) {
super.onPostExecute(result);
mProgressBarLayout.setVisibility(View.GONE);
mItemList = result;
if (mItemList != null) {
if (mParentActivity == null) {
Log.d(TAG, "mParentActivity is null");
}
mAdapter = new MyAdapter(mParentActivity, mItemList);
setListAdapter(mAdapter);
}
}
}
мП arentActivity здесь NULL! Несмотря на то, что onAttach() успешно выполнен с действительным действием до того, как он получил метод onStart().
AsyncTask разбивается на API 8.
Вы узнали, какая переменная имеет значение null .. в вашем обращении к супер ..? – JoxTraex
Да, контекст. См. Нижнюю часть моего сообщения, пожалуйста. –
Вы должны опубликовать больше кода о том, как/при попытке использовать контекст. – JoxTraex