递归进入executePendingTransactions

递归进入executePendingTransactions

问题描述:

我有一个MainDrawer片段活动,其中有一个导航抽屉布局我和我的主要内容,我可以加载新的片段。我加载的一个片段是统计表片段。这个片段包含一个tabhost,每个tab是它自己的listview项目片段。当我点击一个ListView项目,它加载另一个新的片段,并在tabHost我不再和我尝试回去使用navigationdrawer我StatisticsTab片段我得到这个错误:递归进入executePendingTransactions

03-03 10:32:06.884 24185-24185/com.beerportfolio.beerportfoliopro E/AndroidRuntime﹕ FATAL EXCEPTION: main 
    java.lang.IllegalStateException: Recursive entry to executePendingTransactions 
      at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1439) 
      at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:472) 
      at android.support.v4.app.FragmentTabHost.onAttachedToWindow(FragmentTabHost.java:283) 
      at android.view.View.dispatchAttachedToWindow(View.java:12307) 
      at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2457) 
      at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2464) 
      at android.view.ViewGroup.addViewInner(ViewGroup.java:3567) 
      at android.view.ViewGroup.addView(ViewGroup.java:3399) 
      at android.view.ViewGroup.addView(ViewGroup.java:3344) 
      at android.view.ViewGroup.addView(ViewGroup.java:3320) 
      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:938) 
      at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104) 
      at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) 
      at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467) 
      at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440) 
      at android.os.Handler.handleCallback(Handler.java:730) 
      at android.os.Handler.dispatchMessage(Handler.java:92) 
      at android.os.Looper.loop(Looper.java:158) 
      at android.app.ActivityThread.main(ActivityThread.java:5789) 
      at java.lang.reflect.Method.invokeNative(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:525) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:843) 
      at dalvik.system.NativeStart.main(Native Method) 

如果我不点击在我的任何选项卡上,尽管在StatisticsTab片段上,然后通过navdrawer导航到另一个片段,然后返回到StatisticsTab,然后它不会打开FC。当我回到它们时,NavDrawer中的其他任何片段都不会关闭,只有那些带有制表符的片段。

MainDrawer2:

public class MainDrawer2 extends FragmentActivity 
{ 
    private static final String EXTRA_NAV_ITEM = "extraNavItem"; 
    private static final String STATE_CURRENT_NAV = "stateCurrentNav"; 

    private ActionBarDrawerToggle mDrawerToggle; 
    private DrawerLayout mDrawerLayout; 

    private NavDrawerListAdapter mDrawerAdapter; 
    private ListView mDrawerList; 

    private CharSequence mTitle; 
    private CharSequence mDrawerTitle; 

    private MainNavItem mCurrentNavItem; 


    public static Intent createLaunchFragmentIntent(Context context, MainNavItem navItem) 
    { 
     return new Intent(context, MainDrawer2.class) 
       .putExtra(EXTRA_NAV_ITEM, navItem.ordinal()); 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.fragment_main); 

     mTitle = mDrawerTitle = getTitle(); 
     mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout); 
     mDrawerList = (ListView)findViewById(R.id.drawer); 

     getActionBar().setDisplayHomeAsUpEnabled(true); 
     enableHomeButtonIfRequired(); 

     mDrawerAdapter = new NavDrawerListAdapter(getApplicationContext()); 
     mDrawerList.setAdapter(mDrawerAdapter); 
     mDrawerList.setOnItemClickListener(new ListView.OnItemClickListener() 
     { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
      { 
       displayNavFragment((MainNavItem)parent.getItemAtPosition(position)); 
      } 
     }); 

     mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, 
       R.drawable.ic_drawer, R.string.app_name, R.string.app_name) 
     { 
      public void onDrawerClosed(View view) 
      { 
       getActionBar().setTitle(mTitle); 
       invalidateOptionsMenu(); 
      } 

      public void onDrawerOpened(View drawerView) 
      { 
       getActionBar().setTitle(mDrawerTitle); 
       invalidateOptionsMenu(); 
      } 
     }; 

     mDrawerLayout.setDrawerListener(mDrawerToggle); 

     if(getIntent().hasExtra(EXTRA_NAV_ITEM)){ 
      MainNavItem navItem = MainNavItem.values() 
        [getIntent().getIntExtra(EXTRA_NAV_ITEM, 
        MainNavItem.STATISTICS.ordinal())]; 
      displayNavFragment(navItem); 
     } 
     else if(savedInstanceState != null){ 
      mCurrentNavItem = MainNavItem.values() 
        [savedInstanceState.getInt(STATE_CURRENT_NAV)]; 
      setCurrentNavItem(mCurrentNavItem); 
     } 
     else{ 
      displayNavFragment(MainNavItem.STATISTICS); 
     } 
    } 

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 
    private void enableHomeButtonIfRequired() 
    { 
     if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){ 
      getActionBar().setHomeButtonEnabled(true); 
     } 
    } 

    @Override 
    public void setTitle(CharSequence title) 
    { 
     mTitle = title; 
     getActionBar().setTitle(mTitle); 
    } 

    @Override 
    protected void onPostCreate(Bundle savedInstanceState) 
    { 
     super.onPostCreate(savedInstanceState); 
     // Sync the toggle state after onRestoreInstanceState has occurred. 
     mDrawerToggle.syncState(); 
    } 

    @Override 
    public void onConfigurationChanged(Configuration newConfig) 
    { 
     super.onConfigurationChanged(newConfig); 
     // Pass any configuration change to the drawer toggles 
     mDrawerToggle.onConfigurationChanged(newConfig); 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) 
    { 
     super.onSaveInstanceState(outState); 
     outState.putInt(STATE_CURRENT_NAV, mCurrentNavItem.ordinal()); 
    } 

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

    /* 
    @Override 
    public boolean onPrepareOptionsMenu(Menu menu) 
    { 
     // if nav drawer is opened, hide the action items 
     boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); 
     menu.findItem(R.id.action_settings).setVisible(!drawerOpen); 
     return super.onPrepareOptionsMenu(menu); 
    } 
    */ 



    private void displayNavFragment(MainNavItem navItem) 
    { 
     if(navItem == mCurrentNavItem){ 
      return; 
     } 
     Fragment fragment = Fragment.instantiate(this, 
       navItem.getFragClass().getName()); 
     if(fragment != null){ 

      getSupportFragmentManager().beginTransaction() 
        .replace(R.id.main, fragment) 
        .commit(); 
      setCurrentNavItem(navItem); 
     } 
    } 

    private void setCurrentNavItem(MainNavItem navItem) 
    { 
     int position = navItem.ordinal(); 
     // If navItem is in DrawerAdapter 
     if(position >= 0 && position < mDrawerAdapter.getCount()){ 
      mDrawerList.setItemChecked(position, true); 
     } 
     else{ 
      // navItem not in DrawerAdapter, de-select current item 
      if(mCurrentNavItem != null){ 
       mDrawerList.setItemChecked(mCurrentNavItem.ordinal(), false); 
      } 
     } 
     mDrawerLayout.closeDrawer(mDrawerList); 
     setTitle(navItem.getTitleResId()); 
     mCurrentNavItem = navItem; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case android.R.id.home: 
       if(mDrawerLayout.isDrawerOpen(mDrawerList)) { 
        mDrawerLayout.closeDrawer(mDrawerList); 
       } 
       else { 
        mDrawerLayout.openDrawer(mDrawerList); 
       } 
       return true; 
      default: 
       return super.onOptionsItemSelected(item); 
     } 
    } 




    public void goToSearch(MenuItem item){ 

     //go to search page 
     Fragment Fragment_one; 
     FragmentManager man= getSupportFragmentManager(); 
     FragmentTransaction tran = man.beginTransaction(); 
     Fragment_one = new Search(); 

     tran.replace(R.id.main, Fragment_one);//tran. 
     tran.addToBackStack(null); 
     tran.commit(); 

    } 



} 

StatisticsTab:

public class StatisticsTab extends Fragment { 


    private FragmentTabHost mTabHost; 

    //Mandatory Constructor 
    public StatisticsTab() { 
    } 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

    } 

    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 

     View rootView = inflater.inflate(R.layout.fragment_tabs,container, false); 


     mTabHost = (FragmentTabHost)rootView.findViewById(android.R.id.tabhost); 

     mTabHost.setup(getActivity(), getFragmentManager(), R.id.realtabcontent); 

     mTabHost.addTab(mTabHost.newTabSpec("Basic").setIndicator("Basic"), 
       StatisticsPage.class, null); 
     mTabHost.addTab(mTabHost.newTabSpec("Brewery").setIndicator("Brewery"), 
       BreweryStatistics.class, null); 
     mTabHost.addTab(mTabHost.newTabSpec("Style").setIndicator("Style"), 
       StyleStatistics.class, null); 
     mTabHost.addTab(mTabHost.newTabSpec("Taste").setIndicator("Taste"), 
       TasteStatisticsPage.class, null); 



     return rootView; 
    } 




} 

我的一个片段在tabhost标签具有的ListView:

public class BreweryStatistics extends Fragment implements GetBreweryStatisticsJSON.OnArticleSelectedListener { 

    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.brewery_statistics_layout, container, false); 

     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); 
     String userName = prefs.getString("userName", null); 
     String userID = prefs.getString("userID", null); 

     String url = "myURL"; 


     //async task to get beer taste tag percents 
     GetBreweryStatisticsJSON task = new GetBreweryStatisticsJSON(getActivity()); 
     task.setOnArticleSelectedListener(this); 
     task.execute(url); 


     // Inflate the layout for this fragment 
     return v; 

    } 


    @Override 
    public void onArticleSelected(String bID){ 

     //code to execute on click 
     Fragment Fragment_one; 
     FragmentManager man= getFragmentManager(); 
     FragmentTransaction tran = man.beginTransaction(); 
     Fragment_one = new BreweryPage2(); 
     final Bundle bundle = new Bundle(); 
     bundle.putString("breweryIDSent", bID); 
     Fragment_one.setArguments(bundle); 

     tran.replace(R.id.main, Fragment_one);//tran. 
     tran.addToBackStack(null); 
     tran.commit(); 

    } 


} 

我的异步任务上述片段加载列表视图:

public class GetBreweryStatisticsJSON extends AsyncTask<String, Void, String> { 

    Context c; 
    private ProgressDialog Dialog; 


    public GetBreweryStatisticsJSON(Context context) 
    { 
     c = context; 
     Dialog = new ProgressDialog(c); 
    } 

    //***************************code for on click 
    OnArticleSelectedListener listener; 
    public interface OnArticleSelectedListener{ 
     public void onArticleSelected(String myString); 


    } 
    public void setOnArticleSelectedListener(OnArticleSelectedListener listener){ 
     this.listener = listener; 


    } 
    //*****************************end code for onClick 

    protected void onPreExecute() { 
     Dialog.setMessage("Analyzing breweries"); 

     Dialog.setTitle("Loading"); 
     Dialog.setCancelable(false); 
     Dialog.show(); 
    } 


    @Override 
    protected String doInBackground(String... arg0) { 
     // TODO Auto-generated method stub 
     return readJSONFeed(arg0[0]); 
    } 

    protected void onPostExecute(String result){ 
     //decode json here 
     try{ 
      JSONArray jsonArray = new JSONArray(result); 


      //acces listview 
      ListView lv = (ListView) ((Activity) c).findViewById(R.id.yourBreweryStatistics); 

      //make array list for beer 
      final List<BreweryInfo> tasteList = new ArrayList<BreweryInfo>(); 



      for(int i = 0; i < jsonArray.length(); i++) { 

       String brewery = jsonArray.getJSONObject(i).getString("brewery"); 
       String rate = jsonArray.getJSONObject(i).getString("rate"); 
       String breweryID = jsonArray.getJSONObject(i).getString("id"); 

       int count = i + 1; 

       brewery = count + ". " + brewery; 

       Log.d("brewery stats", brewery); 

       //create object 
       BreweryInfo tempTaste = new BreweryInfo(brewery, breweryID, rate); 

       //add to arraylist 
       tasteList.add(tempTaste); 


       //add items to listview 
       BreweryInfoAdapter adapter1 = new BreweryInfoAdapter(c ,R.layout.brewer_stats_listview, tasteList); 
       lv.setAdapter(adapter1); 

       //set up clicks 
       lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
        @Override 
        public void onItemClick(AdapterView<?> arg0, View arg1, 
              int arg2, long arg3) { 
         BreweryInfo o=(BreweryInfo)arg0.getItemAtPosition(arg2); 

         String bID = o.breweryID; 

         Log.d("breweryID" , bID); 

         //todo: add brewery page link 
         //********************* add listener 
         listener.onArticleSelected(bID); 


        } 
       }); 

      } 

     } 
     catch(Exception e){ 

     } 

     Dialog.dismiss(); 

    } 

    public String readJSONFeed(String URL) { 
     StringBuilder stringBuilder = new StringBuilder(); 
     HttpClient httpClient = new DefaultHttpClient(); 
     HttpGet httpGet = new HttpGet(URL); 
     try { 
      HttpResponse response = httpClient.execute(httpGet); 
      StatusLine statusLine = response.getStatusLine(); 
      int statusCode = statusLine.getStatusCode(); 
      if (statusCode == 200) { 
       HttpEntity entity = response.getEntity(); 
       InputStream inputStream = entity.getContent(); 
       BufferedReader reader = new BufferedReader(
         new InputStreamReader(inputStream)); 
       String line; 
       while ((line = reader.readLine()) != null) { 
        stringBuilder.append(line); 
       } 
       inputStream.close(); 
      } else { 
       Log.d("JSON", "Failed to download file"); 
      } 
     } catch (Exception e) { 
      Log.d("readJSONFeed", e.getLocalizedMessage()); 
     } 
     return stringBuilder.toString(); 
    } 



} 
+0

的可能重复的[ViewPager:递归进入executePendingTransactions](http://*.com/questions/7338823/viewpager-recursive-entry-to-executependingtransactions ) – rds

您试图使用嵌套在其他片段中的片段,通过您的FragmentTabHost。

在你StatisticsTab片段,改变这种:

mTabHost.setup(getActivity(), getFragmentManager(), R.id.realtabcontent); 

这样:

mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent); 


然后,确保使用父FragmentManager提交的主要片段的变化,通过改变getFragmentManager()getActivity().getSupportFragmentManager()里面BreweryStatistics.onArticleSelected()


参见:
ViewPager: Recursive entry to executePendingTransactions
Nested Fragments using support library v4 revision 11

+0

我会在哪里更改为getSupportFragmentManager()vs getChildFragmentManager()? – Mike

+0

道歉,误读您的活动代码,您正在使用getSupportFragmentManager()在您的抽屉活动中正确。请参阅我的最新答案以进行澄清。 –

+0

真棒,但那实际上是我最初的,当我尝试从选项卡中的ListView中进行选择时,出现奇数ID错误。我会尽快将其更改并显示错误。 – Mike