我使用 AsyncTaskLoader 从数据库查询中加载游标。我遵循了 Android 开发者示例:http: //developer.android.com/reference/android/content/AsyncTaskLoader.html
但是不知何故,在此片段(使用加载器)之后添加到页面适配器的片段没有附加到活动,并且当它尝试使用需要活动的方法(如 getString())时,会抛出异常并说这个片段没有附加到任何活动。
这是一些代码:
将片段添加到页面适配器。
mAdapter = new PlaceFragmentPagerAdapter(getSupportFragmentManager()); NewFragment newFrag = new NewFragment(); mAdapter.addFragment(newShiftFrag); ListFragment listFrag = new ListFragment(); mAdapter.addFragment(listFrag); SettingsFragment settingsFrag = new SettingsFragment(); mAdapter.addFragment(settingsFrag); mPager = (ViewPager)findViewById(R.id.pager); mPager.setAdapter(mAdapter);
AsyncTaskLoader 实现:
抽象公共类 AbstractCursorLoader 扩展 AsyncTaskLoader {
abstract protected Cursor buildCursor(); Cursor lastCursor=null; public AbstractCursorLoader(Context context) { super(context); } /** * Runs on a worker thread, loading in our data. Delegates * the real work to concrete subclass' buildCursor() method. */ @Override public Cursor loadInBackground() { Cursor cursor=buildCursor(); if (cursor!=null) { // Ensure the cursor window is filled cursor.getCount(); } return(cursor); } /** * Runs on the UI thread, routing the results from the * background thread to whatever is using the Cursor * (e.g., a CursorAdapter). */ @Override public void deliverResult(Cursor cursor) { if (isReset()) { // An async query came in while the loader is stopped if (cursor!=null) { cursor.close(); } return; } Cursor oldCursor=lastCursor; lastCursor=cursor; if (isStarted()) { super.deliverResult(cursor); } if (oldCursor!=null && oldCursor!=cursor && !oldCursor.isClosed()) { oldCursor.close(); } } /** * Starts an asynchronous load of the list data. * When the result is ready the callbacks will be called * on the UI thread. If a previous load has been completed * and is still valid the result may be passed to the * callbacks immediately. * * Must be called from the UI thread. */ @Override protected void onStartLoading() { if (lastCursor!=null) { deliverResult(lastCursor); } if (takeContentChanged() || lastCursor==null) { forceLoad(); } } /** * Must be called from the UI thread, triggered by a * call to stopLoading(). */ @Override protected void onStopLoading() { // Attempt to cancel the current load task if possible. cancelLoad(); } /** * Must be called from the UI thread, triggered by a * call to cancel(). Here, we make sure our Cursor * is closed, if it still exists and is not already closed. */ @Override public void onCanceled(Cursor cursor) { if (cursor!=null && !cursor.isClosed()) { cursor.close(); } } /** * Must be called from the UI thread, triggered by a * call to reset(). Here, we make sure our Cursor * is closed, if it still exists and is not already closed. */ @Override protected void onReset() { super.onReset(); // Ensure the loader is stopped onStopLoading(); if (lastCursor!=null && !lastCursor.isClosed()) { lastCursor.close(); } lastCursor=null; } } private static class ListLoader extends AbstractCursorLoader { private String mName; public ShiftsListLoader(Context context, String name) { super(context); mName = name; } @Override protected Cursor buildCursor() { PlacesHandler wph = new PlacesHandler(this.getContext()); return wph.GetShifts(mName); } }
初始化加载器:
@Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Give some text to display if there is no data. In a real // application this would come from a resource. // TODO change to resource and back setEmptyText("Nothing here.."); // Start out with a progress indicator. setListShown(false); // Prepare the loader. Either re-connect with an existing one, // or start a new one. getLoaderManager().initLoader(0, null, this);
}
@Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new ListLoader(getActivity(), mWorkPlaceName); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // Create an empty adapter we will use to display the loaded data. mAdapter = new ListCursorAdapter(getActivity(), data, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); setListAdapter(mAdapter); } @Override public void onLoaderReset(Loader<Cursor> loader) { // TODO Auto-generated method stub }
我真的不知道为什么会这样。
PS我在评论中制作代码块时遇到了一些问题,我觉得它有一个错误,很抱歉。
在此先感谢,埃拉德。