0

Я использовал AsyncTaskLoader для загрузки курсора из запроса базы данных. Я последовал Android Developers образца: http://developer.android.com/reference/android/content/AsyncTaskLoader.htmlФрагмент с AsyncTaskLoader влияет на присоединение других фрагментов к активности

Но как-то фрагменты, которые добавляются к адаптеру страницы после этого фрагмента (который использует загрузчик) не привязывается к деятельности и когда он пытается использовать методы, которые нуждаются в (например, 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 расширяет 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. Initializng Загрузчик:

    @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 
    
    } 
    

У меня действительно нет подсказки, почему это происходит

P.S. У меня были некоторые проблемы с созданием блоков кода в комментарии. У меня есть ошибка, так что извините.

Заранее спасибо, Elad.

ответ

2

Короткий ответ заключается в том, что вы никогда не должны предполагать, что фрагмент находится в каком-либо конкретном состоянии, пока он не получит соответствующий обратный вызов жизненного цикла, сигнализирующий об этом.

Что вы видите, это оптимизация, добавленная во время ICS, которую использует ViewPager. FragmentPagerAdapter специально отмечает фрагментарные фрагменты, которые не отображаются пользователем, вызывая setUserVisibleHint. FragmentManager использует это, чтобы определить, как выполняются загрузчики, чтобы пользователь сначала просматривал полностью загруженную видимую страницу, а загружаемые стороны не замедляли процесс загрузки видимой страницы. В частности, он задерживает перемещение фрагмента в «начальное» состояние, которое также происходит при загрузке загрузчиков.

Если пользователь прокручивается на другую страницу во время этого процесса, FragmentManager переместит фрагмент в начальное состояние и сразу начнет запуск своих загрузчиков как часть FragmentPagerAdapter # setPrimaryItem(), так как этот метод отмечает текущую страницу как теперь становится видимым пользователем.

+0

Я понимаю вас, и я думаю, что понимаю свою проблему. Каждый фрагмент в моем приложении возвращает свое имя из ресурсов для TitlePageIndicator, который я использую (очень хорошая библиотека от создателя панели действий sherlock), и когда у меня есть 3 фрагмента, третий не прикреплен к этой активности, но может 't использовать getString(), который использует resorces активности. Спасибо, я сделаю это по-другому! – Elad92

+0

Возможно, вы заинтересованы в поддержке PagerTitleStrip библиотеки поддержки; он извлекает строки заголовков из PagerAdapter, где вы, вероятно, будете иметь ссылку на активность, которую вы можете использовать для извлечения этих строк. – adamp

Смежные вопросы