Android- Stackoverflower在导航中的主要细节流程

时间:2016-04-07 11:11:13

标签: android android-fragments

我们有一个master-detail流程,主要和详细信息片段都是通过片段管理器和后台堆栈“添加”的,如下所示,

我们将homefragment中的主片段添加为

getActivity().getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, <masterfragment>, "master")
                    .addToBackStack()
                    .commit();

从master中我们以同样的方式添加子片段,当用户点击一行时,

getActivity().getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, <detailfragment>, "detail")
                    .addToBackStack()
                    .commit();

现在我们得到一个随机stackoverflower错误,用户在主要和细节片段之间来回导航超过100次,

 android.support.v4.app.Fragment.c  

    android.support.v4.app.FragmentManagerImpl.a    

    android.support.v4.app.Fragment.c   

    android.support.v4.app.FragmentManagerImpl.a    

    android.support.v4.app.FragmentActivity.onPreparePanel  

    android.support.v7.internal.view.WindowCallbackWrapper.onPreparePanel   

    android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.onPreparePanel

   android.support.v7.internal.view.WindowCallbackWrapper.onPreparePanel    

    android.support.v7.internal.app.ToolbarActionBar$ToolbarCallbackWrapper.onPreparePanel

    android.support.v7.internal.view.WindowCallbackWrapper.onPreparePanel   

    android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.onPreparePanel

android.support.v7.internal.view.WindowCallbackWrapper.onPreparePanel   

  android.support.v7.internal.app.ToolbarActionBar$ToolbarCallbackWrapper.onPreparePanel    

经过几个小时的分析,我们发现每次我们使用片段中的工具栏设置支持操作栏时(主片段和详细片段都有不同的工具栏)

getActivity().setSupportActionBar(mToolBar);

创建一个新的ToolbarActionBar对象,并使用 new wrappedwindow callback 设置窗口回调,(以下代码片段是从类,AppCompatDelegateImplV7的android源代码复制的)

 ToolbarActionBar tbab = new ToolbarActionBar(toolbar, ((Activity) mContext).getTitle(),
            mWindow);
    setSupportActionBar(tbab);
    mWindow.setCallback(tbab.getWrappedWindowCallback());

在ToolbarActionBar类中创建了一个新的ToolbarCallbackWrapper(以下代码片段是从android源代码复制的),如下面的源代码所示,新的回调包装器将从之前的窗口回调中再次创建。

 public ToolbarActionBar(Toolbar toolbar, CharSequence title, Window window) {
        mDecorToolbar = new ToolbarWidgetWrapper(toolbar, false);
        mWindowCallback = new ToolbarCallbackWrapper(window.getCallback());
        mDecorToolbar.setWindowCallback(mWindowCallback);
        toolbar.setOnMenuItemClickListener(mMenuClicker);
        mDecorToolbar.setWindowTitle(title);

        mWindow = window;
    }

所以对于每次调用设置支持操作栏,它都会创建一个toolbarcallbackwrapper类的嵌套对象,如下面的调试'对象跟踪'所示

this = {ToolbarActionBar$ToolbarCallbackWrapper@5428} 
 this$0 = {ToolbarActionBar@5429} 
 mWrapped = {ToolbarActionBar$ToolbarCallbackWrapper@5423} 
  this$0 = {ToolbarActionBar@5424} 
  mWrapped = {ToolbarActionBar$ToolbarCallbackWrapper@5417} 
   this$0 = {ToolbarActionBar@5418} 
   mWrapped = {ToolbarActionBar$ToolbarCallbackWrapper@5412} 
    this$0 = {ToolbarActionBar@5413} 
    mWrapped = {ToolbarActionBar$ToolbarCallbackWrapper@5382} 
     this$0 = {ToolbarActionBar@5383} 
     mWrapped = {ToolbarActionBar$ToolbarCallbackWrapper@5309} 
      this$0 = {ToolbarActionBar@5310} 
      mWrapped = {ToolbarActionBar$ToolbarCallbackWrapper@5196} 
       this$0 = {ToolbarActionBar@5198} 
       mWrapped = {AppCompatDelegateImplV14$AppCompatWindowCallbackV14@5443} 

所以每当工具栏为片段“准备好”时,就会再次调用回调,导致stackoverflow错误,(因为在大约100次导航之后,嵌套对象的深度已超过100)。

我们如何解决这个问题?

0 个答案:

没有答案