0

J'utilise un chargeur de curseur pour créer les onglets d'une activité. J'utilise des onglets à glisser comme détaillé sur la documentation android View Pager.
http://developer.android.com/reference/android/support/v4/view/ViewPager.htmlAndroid: L'activité FragmentStatePagerAdapter a déjà été détruite - Navigation précédente ou précédente

Jusqu'à présent, je n'ai pas mis en œuvre en mettant l'un de mes pages chargées sur la pile arrière, quand je clique arrière, il saute à l'activité précédente. (Ceci est bien pour le moment.) Cliquer sur le bouton précédent ou suivant entraîne une exception d'exécution java.lang.RuntimeException: Unable to destroy activity: java.lang.IllegalStateException: Activity has been destroyed

Les seules différences que je connaisse entre ce que j'ai et l'exemple sont l'utilisation du curseur, et que l'exemple définit le ViewPager lui-même comme la vue de contenu, alors que j'ai utilisé un fichier de disposition qui contient un ViewPager. J'utilise également un FragmentStatePagerAdapter plutôt que FragmentPagerAdapter, mais la commutation entre ces deux ne fait aucune différence.

Je ne suis pas sûr de ce que dans l'appel andDestroy android essayerait de détruire l'activité deux fois. Mon code est ci-dessous. Toute aide est appréciée, et je serais heureux de fournir plus d'informations. Merci.

public class WorksheetActivity extends FragmentActivity implements android.support.v4.app.LoaderManager.LoaderCallbacks<Cursor> { 
public String user; 
private static final int DAY_LOADER = 0; 
public int program_index; 
public int program_id; 
public int item_id; 
public int type_key; 
ViewPager mViewPager; 
TabsAdapter mTabsAdapter; 
LoaderManager.LoaderCallbacks<Cursor> mCallbacks; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_worksheet); 
    mCallbacks = this; 
    ActionBar bar = getActionBar(); 
    //this sets up to include tabs, and to show the title on each tab 
    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
    bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE); 
    //enables navigation up, when clicked calls on options item selected for home button. 
    bar.setDisplayHomeAsUpEnabled(true); 
    Bundle extras = getIntent().getExtras(); 
    if (!(extras.isEmpty())){ 
     user = extras.getString("user"); 
     //used for moving up to the Program Activity and restoring the selection. 
     program_index = extras.getInt(ProgramActivity.PROGRAM_KEY); 
     program_id = extras.getInt(ProgramActivity.PROGRAM_ID); 
     item_id = extras.getInt(ProgramActivity.ITEM_ID); 
     type_key = extras.getInt(ProgramActivity.TYPE_KEY); 
    } 
    Bundle tabData = new Bundle(); 
    tabData.putAll((extras.isEmpty()? savedInstanceState : extras)); 
    mViewPager = (ViewPager) findViewById(R.id.pager); 
    mTabsAdapter = new TabsAdapter(this, mViewPager, null, tabData); 
    LoaderManager lm = getSupportLoaderManager(); 
    lm.initLoader(0, tabData, mCallbacks); 

} 


@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.activity_worksheet, menu); 
    return true; 
} 

@Override 
public void onSaveInstanceState(Bundle out){ 
    out.putString("user",user); 
    //used for moving up to the Program Activity and restoring the selection. 
    out.putInt(ProgramActivity.PROGRAM_KEY, program_index); 
    out.putInt(ProgramActivity.ITEM_ID, item_id); 
    out.putInt(ProgramActivity.PROGRAM_ID, program_id); 
    out.putInt(ProgramActivity.TYPE_KEY, type_key); 
} 

@Override 
public void onRestoreInstanceState(Bundle in){ 
    user = in.getString("user"); 
    program_index = in.getInt(ProgramActivity.PROGRAM_KEY); 
    program_id = in.getInt(ProgramActivity.PROGRAM_ID); 
    item_id = in.getInt(ProgramActivity.ITEM_ID); 
    type_key = in.getInt(ProgramActivity.TYPE_KEY); 
} 

@SuppressLint("NewApi") 
@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case android.R.id.home: 
      Intent upIntent = new Intent(this, ProgramActivity.class); 
      upIntent.putExtra("user", user); 
      upIntent.putExtra(ProgramActivity.PROGRAM_KEY, program_index); 
      if (NavUtils.shouldUpRecreateTask(this, upIntent)){ 
       TaskStackBuilder.create(this) 
        .addNextIntent(new Intent(this, Marta_QC.class)) 
        .addNextIntent(upIntent).startActivities(); 
       finish(); 
      }else{ 
       NavUtils.navigateUpTo(this, upIntent); 
      } 
      return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 

@Override 
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) { 
    CursorLoader cl = null; 
    switch(id){ 
     case DAY_LOADER: 
      cl = new CursorLoader(getApplicationContext(), Tasks.CONTENT_URI, new String[]{Tasks.DAY_COL},Tasks.PROGRAM_COL+" = ?", 
            new String[]{Integer.toString(program_id)}, Tasks.DAY_COL+" ASC"); 
      break; 
     default: 
    } 
    return cl; 
} 

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor c) { 
    switch(loader.getId()){ 
     case DAY_LOADER: 
      mTabsAdapter.swapCursor(c); 
      break; 
     default: 
    } 
} 

@Override 
public void onLoaderReset(Loader<Cursor> loader) { 
    switch(loader.getId()){ 
    case DAY_LOADER: 
     mTabsAdapter.swapCursor(null); 
     break; 
    default: 
} 

} 

public static class TabsAdapter extends FragmentStatePagerAdapter 
    implements ActionBar.TabListener, ViewPager.OnPageChangeListener { 
    private final Context mContext; 
    private final ActionBar mActionBar; 
    private final ViewPager mViewPager; 
    private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); 
    private Bundle mArgs; 
    private int currentPosition; 

    static final class TabInfo{ 
     private final Class<?> clss; 
     private final Bundle args; 
     public final int position; 
     TabInfo(Class<?> _class, Bundle _args, int _position){ 
      clss = _class; 
      args = _args; 
      position = _position; 
     } 
    } 

    public TabsAdapter (FragmentActivity activity, ViewPager pager, Cursor days, Bundle args){ 
     super(activity.getSupportFragmentManager()); 
     mContext = activity; 
     mActionBar = activity.getActionBar(); 
     mViewPager = pager; 
     mViewPager.setAdapter(this); 
     mViewPager.setOnPageChangeListener(this); 
     mArgs = args; 
    } 

    public void swapCursor(Cursor c){ 
     mActionBar.removeAllTabs(); 
     mViewPager.removeAllViews(); 
     //add the exceptions tab. Always first. 
     ActionBar.Tab tab = mActionBar.newTab(); 
     Bundle tabArgs = new Bundle(); 
     tabArgs.putAll(mArgs); 
     this.addTab(tab, ExceptionsSheet.class, tabArgs); 

     //add each of the day tabs to the set, which stores unique values only 
     LinkedHashSet<String> days = new LinkedHashSet<String>(); 
     if(c.moveToFirst()){ 
      do{ 
       days.add(c.getString(c.getColumnIndex(Tasks.DAY_COL))); 
      }while (c.moveToNext()); 
     } 
     //iterate through the unique days 
     for(String day:days){ 
      ActionBar.Tab dayTab = mActionBar.newTab(); 
      Bundle dayArgs = new Bundle(); 
      dayArgs.putAll(mArgs); 
      dayArgs.putString("day", day); 
      this.addTab(dayTab, Worksheet.class, dayArgs); 
     } 
     //start with the first day 
     mActionBar.setSelectedNavigationItem(1); 
    } 

    public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args){ 
     //implemented adding a position to the tab info class. 
     //gets the current tab count prior to adding this tab. 
     TabInfo info = new TabInfo(clss, args, this.getCount()); 
     tab.setTag(info); 
     tab.setTabListener(this); 
     mTabs.add(info); 
     if (clss.equals(ExceptionsSheet.class)){ 
      //tab.setCustomView(R.layout.exceptions_tab); 
      tab.setText(mContext.getText(R.string.exceptions_tab_title)); 
     }else{ 
      if(clss.equals(Worksheet.class)){ 
       tab.setText("Day "+args.getString("day")); 
      }else{ 
       Log.d("unknown class", clss.toString()); 
      } 

     } 
     mActionBar.addTab(tab); 
     notifyDataSetChanged(); 
    } 

    @Override 
    public void onPageSelected(int pos) { 
     // set the tab to match the page, following a swipe action. 
     currentPosition = pos; 
     mActionBar.setSelectedNavigationItem(pos); 
    } 

    @Override 
    public void onTabSelected(Tab tab, FragmentTransaction ft) { 
     //this will return our tab info 
     TabInfo minfo = (TabInfo) tab.getTag(); 
     int pos = minfo.position; 
     this.getItem(currentPosition); 
     mViewPager.setCurrentItem(pos); 
     currentPosition = pos; 
    } 

    //this is the FragmentPager Adapter main method 
    //here we will use the arguments bundled into the tab to set the 
    //fragment for the page. 
    @Override 
    public Fragment getItem(int pos) { 
     TabInfo tabInfo = mTabs.get(pos); 
     return Fragment.instantiate(mContext, tabInfo.clss.getName(), tabInfo.args); 
    } 


} 




//class for exceptions display 
public static class ExceptionsSheet extends Fragment{ 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ 
     int i = 1; 
     i = i+1; 
     //must include false, since we're attaching to the ViewPager sheet, not the root view. 
     return inflater.inflate(R.layout.exception, container, false); 
    } 
} 

//class for standard worksheet display 
public static class Worksheet extends Fragment{ 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ 

     return inflater.inflate(R.layout.worksheet, container, false); 
    } 

} 

}

Répondre

0

Je trouve le problème. Lorsque l'activité est détruite, la méthode onLoaderReset() est appelée. Ici, j'ai échangé un curseur null pour supprimer les références au curseur (comme avec les adaptateurs non personnalisés), mais ma méthode swapCursor n'a pas vérifié si le curseur était nul. Une fois le problème résolu, le code n'essaie plus de mettre à jour l'interface utilisateur après la destruction de l'activité.

Questions connexes