ユーザーが Fragment に戻ったときに常に SQLite データベースからデータをリロードするようにするため、onStart() メソッドで AsyncTask を開始します。これは ListFragment であり、アイテムをクリックすると、タブレットの 2 ペイン レイアウトで別の Fragment が表示されるか、リスト内のすべてのアイテムに ViewPager を使用するアクティビティが表示されるためです。後者の場合、ユーザーは ViewPager からアイテムを削除できるため、アイテムをリロードする必要があります。
現在、さまざまなデバイスと API でレイアウトをテストしています。
Froyo (API 8) NexusOne AVD では、画面を 1 回回転させると、AsyncTask が再び開始され、データが再表示されます。もう一度実行すると、NullPointerException が発生します。これは、API 10+ を使用して別の AVD を開始した場合には発生しません (必要に応じて表示を回転させることができます)。2 回目のローテーションを行う前に、1 回目のローテーションを完了するのに十分な時間を与えます。
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 への呼び出しです[編集]
super(context, 0, myListArray);
onPostExecute(MyListFragment.java:393 は次のとおりです。
mAdapter = new MyAdapter(getActivity(), myListArray);
myListArray が null の場合、上記は実行されません。
その指示の上にこれを追加しました:
if (getActivity() == null) {
Log.d(TAG, "getActivity() is null");
}
getActivity() が API 8 デバイスで null を返しています!
これは、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;
変更された 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);
}
}
}
mParentActivity は NULL です! onAttach() は、onStart() メソッドに到達する前に有効なアクティビティで正常に実行されましたが。
AsyncTask は API 8 で壊れています。