Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/187.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 带有AsyncTaskLoader的片段影响其他片段';附属于活动_Android_Android Fragments_Android Asynctask_Android Cursorloader_Asynctaskloader - Fatal编程技术网

Android 带有AsyncTaskLoader的片段影响其他片段';附属于活动

Android 带有AsyncTaskLoader的片段影响其他片段';附属于活动,android,android-fragments,android-asynctask,android-cursorloader,asynctaskloader,Android,Android Fragments,Android Asynctask,Android Cursorloader,Asynctaskloader,我使用AsyncTaskLoader从数据库查询加载游标。 我遵循了Android开发者的示例: 但不知何故,在此片段(使用加载程序)之后添加到页面适配器的片段没有附加到活动,当它尝试使用需要活动的方法(如getString())时,会引发异常,并表示此片段没有附加到任何活动 下面是一些代码: 将片段添加到页面适配器 mAdapter = new PlaceFragmentPagerAdapter(getSupportFragmentManager()); NewFragment newF

我使用AsyncTaskLoader从数据库查询加载游标。 我遵循了Android开发者的示例:

但不知何故,在此片段(使用加载程序)之后添加到页面适配器的片段没有附加到活动,当它尝试使用需要活动的方法(如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);
    
    }

    @覆盖
    公共加载器onCreateLoader(int-id,Bundle-args){
    返回新的ListLoader(getActivity(),mWorkPlaceName);
    }
    @凌驾
    public void onLoadFinished(加载器、光标数据){
    //创建一个空适配器,用于显示加载的数据。
    mAdapter=newlistCursorAdapter(getActivity(),data,CursorAdapter.FLAG\u REGISTER\u CONTENT\u OBSERVER);
    setListAdapter(mAdapter);
    }
    @凌驾
    公共void onLoaderReset(加载器){
    //TODO自动生成的方法存根
    }
    
  • 我真的不知道为什么会这样

    另外,我在注释中的代码块制作上遇到了一些问题,我认为它有一个bug,非常抱歉


    提前感谢您,Elad。

    简单的回答是,在收到相应的生命周期回调信号之前,您不应该假设片段处于任何特定状态

    您看到的是ViewPager在ICS期间添加的优化。FragmentPagerAdapter特别将屏幕外的片段标记为用户通过调用无法看到。FragmentManager使用此选项来确定加载程序的执行优先级,以便用户首先看到完全加载的可见页面,并且加载侧页不会减慢加载可见页面的过程。具体来说,它会延迟将片段移动到“启动”状态,这也是加载程序开始运行的时候


    如果用户在此过程中滚动到另一个页面,FragmentManager会将片段移动到已启动状态,并作为FragmentPagerAdapter#setPrimaryItem()的一部分立即开始运行其加载程序,由于此方法将当前页面标记为用户可见。

    我理解您的意思,我想我也理解我的问题。我的应用程序中的每个片段都会从我正在使用的TitlePageIndicator(sherlock action bar创建者提供的非常好的库)的参考资料中返回其名称,当我有3个片段时,第三个片段还没有连接到活动,因此它不能使用使用活动资源的getString()。谢谢,我会用另一种方式做的!您可能会对支持库的PagerTitleStrip感兴趣;它从PagerAdapter中检索标题字符串,在这里您可能有一个活动引用,可以用来获取这些字符串。
        @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
    
    }