Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用导航抽屉管理片段生命周期_Android_Performance_Android Fragments_Android Fragmentactivity_Navigation Drawer - Fatal编程技术网

Android 使用导航抽屉管理片段生命周期

Android 使用导航抽屉管理片段生命周期,android,performance,android-fragments,android-fragmentactivity,navigation-drawer,Android,Performance,Android Fragments,Android Fragmentactivity,Navigation Drawer,我的应用程序中有一个架构问题。我使用了一个活动和导航抽屉以及几个片段。现在 假设我有两个片段A和B。导航结构有点: A B 其中A1、A2为A型片段,B1、B2为B型片段。同一类型片段(如A1、A2)之间的唯一区别是数据 我的第一个方法: 每当用户单击A1、A2、B1、B2时。我只是创建一个该类型的新实例并替换片段 Fragment fragment =A.newInstance(); private void replaceFragment(Fragment fragment) {

我的应用程序中有一个架构问题。我使用了一个活动和导航抽屉以及几个片段。现在

假设我有两个片段A和B。导航结构有点:

A

B

其中A1、A2为A型片段,B1、B2为B型片段。同一类型片段(如A1、A2)之间的唯一区别是数据

我的第一个方法:

每当用户单击A1、A2、B1、B2时。我只是创建一个该类型的新实例并替换片段

  Fragment fragment =A.newInstance();

 private void replaceFragment(Fragment fragment) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.content_frame, fragment).commit();
        mDrawerLayout.closeDrawer(rlDrawer);
    }
注意:我不想将它们添加到后堆栈中

后来我意识到这种方法效率低下,因为每次它都会在该片段上装入一个新实例,即使它们是相同类型的。正如我之前所说的,差异只是在数据上。所以,我转到下一种方法

第二种方法:

现在我的活动有片段A和B的数据成员(引用)。现在我将检查它是否为空,然后创建一个新实例,否则只需更改数据:

   if (A == null) {
            a = A.newInstance();
        } else {
            ((A) a).changeData();
        }
        replaceFragment(a);
这种方法的问题是,当我从片段A1切换到B1时,A1片段被破坏,但它的引用仍然保持活动状态。现在,当我从B1切换回A1时,它不会像您在上面的代码中看到的那样创建一个新实例,但同时在片段a上调用onCreate()方法

是否应该在片段上调用onDestroy()后立即从活动中删除引用

我的第二种方法正确吗

有没有更好的方法


提前谢谢

我会稍微修改您的第一种方法

对片段使用字符串标记。 替换片段时,使用带有三个参数的
replace
方法,例如:

  fragmentManager.beginTransaction()
                .replace(R.id.content_frame, fragment, TAG_A1).commit();
其中,
TAG_A1
是唯一的字符串标记

在执行替换之前,可以使用中的方法检查片段是否已创建

FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragmentA1 = fragmentManager.findFragmentByTag(TAG_A1);
if(fragment == null) {
    fragment = A.newInstance();
}
fragmentManager.beginTransaction()
                    .replace(R.id.content_frame, fragment, TAG_A1).commit();

我知道我们可以使用findByTag(),但我听说我们应该避免这种情况,因为根据谷歌I/O的romain guy谈话,这是一种性能下降。我没有看过这场谈话,但我认为这比每次都创建新片段要好。你也不是经常打电话给它。是的,这是真的,它比每次创建新的片段更好,但在我的第二种方法中,我没有这样做。这就是为什么我问有没有更好的方法来实现它。
  fragmentManager.beginTransaction()
                .replace(R.id.content_frame, fragment, TAG_A1).commit();
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragmentA1 = fragmentManager.findFragmentByTag(TAG_A1);
if(fragment == null) {
    fragment = A.newInstance();
}
fragmentManager.beginTransaction()
                    .replace(R.id.content_frame, fragment, TAG_A1).commit();