0

AsyncTaskLoader を使用して、データベース クエリからカーソルをロードしました。私は Android 開発者のサンプルに従いました: http://developer.android.com/reference/android/content/AsyncTaskLoader.html

しかし、どういうわけか、このフラグメント (ローダーを使用する) の後にページ アダプターに追加されるフラグメントは、アクティビティにアタッチされず、アクティビティを必要とするメソッド (getString() など) を使用しようとすると、例外がスローされます。このフラグメントはどのアクティビティにも関連付けられていません。

ここにいくつかのコードがあります:

  1. ページ アダプターにフラグメントを追加します。

    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);
    
  2. AsyncTaskLoader の実装:

    抽象公開クラス AbstractCursorLoader extends 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);
            }
        }
    
  3. ローダーの初期化:

        @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コメントでコードブロックを作成する際に問題が発生しました。バグがあると思います。申し訳ありません。

前もってありがとう、エラド。

4

1 に答える 1