0

我正在使用遊標裝入器在活動中創建選項卡。我正在使用swipable選項卡詳細的android視圖尋呼機文檔。
http://developer.android.com/reference/android/support/v4/view/ViewPager.htmlAndroid:FragmentStatePagerAdapter活動已被銷燬 - 向上或向後導航

到目前爲止,我還沒有實現把我的任何頁面加載到後端堆棧上,所以當我點擊它時跳轉到前一個活動。 (現在很好。)單擊後退或向上按鈕會導致運行時異常java.lang.RuntimeException: Unable to destroy activity: java.lang.IllegalStateException: Activity has been destroyed

我所知道的與示例之間唯一的區別在於使用了遊標,並且示例將ViewPager本身設置爲內容視圖,而我使用了包含ViewPager的佈局文件。我也使用FragmentStatePagerAdapter而不是FragmentPagerAdapter,但在這兩者之間切換沒有任何區別。

我不知道什麼在android onDestroy調用會嘗試兩次銷燬活動。我的代碼如下。任何幫助表示讚賞,我很樂意提供更多信息。謝謝。

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); 
    } 

} 

}

回答

0

我發現這個問題。當Activity被銷燬時,onLoaderReset()方法被調用。在這裏,我交換了空遊標來刪除對遊標的引用(與非自定義適配器一樣),但是我的swapCursor方法沒有檢查遊標是否爲空。一旦我解決了這個問題,代碼不再會在活動被銷燬後嘗試更新UI。

相關問題