为什么片段类应该公开?

时间:2018-07-16 10:14:40

标签: android android-fragments public

我发现一些线程可以解释为什么Fragment类应该像this那样static(不是非静态内部)。但无法理解此错误消息的原因:

  

此片段类应为公共(...)


我使用Android Studio 3.1.2,这是我的代码的一部分:

public class MainActivity extends android.support.v7.app.AppCompatActivity {
    // ...
}

class DefaultFragment extends android.support.v4.app.Fragment {
    // ...
}

该片段只能在MainActivity中使用。


编辑:IDE消息中还有其他信息。但是关于构造函数:

  

来自Fragment文档:

     

每个片段都必须有一个空的构造函数,因此可以在恢复其活动状态时实例化它。强烈建议子类不要使用带有参数的其他构造函数,因为在重新实例化片段时,将不会调用这些构造函数。取而代之的是,参数可以由调用者使用setArguments(Bundle)提供,然后由Fragment使用getArguments()进行检索。

2 个答案:

答案 0 :(得分:1)

更改方向后,将重新创建Activity,框架将在片段上创建新实例(并恢复以前的状态)。 因此,在这里创建Fragment实例时,框架要求提供公共构造函数。


摘自Fragment.Fragment()的文档

Default constructor :

每个片段都必须有一个empty constructor,因此可以在恢复其活动状态时实例化它。强烈建议子类不要使用带有参数的其他构造函数,因为在重新实例化片段时,将不会调用这些构造函数。相反,参数可以由调用者使用setArguments(Bundle)提供,然后由Fragment使用getArguments()检索。


下面是代码形式Activity.java的类,您可以通过查找更多FragmentManager.dispatchMoveToState()的代码来进一步分析

@MainThread
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
    ........
    if (savedInstanceState != null) {
        mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
        mLastAutofillId = savedInstanceState.getInt(LAST_AUTOFILL_ID,
                View.LAST_APP_AUTOFILL_ID);
        if (mAutoFillResetNeeded) {
            getAutofillManager().onCreate(savedInstanceState);
        }
        Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
        mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
                ? mLastNonConfigurationInstances.fragments : null);
    }
    mFragments.dispatchCreate();
    .....
}

答案 1 :(得分:0)

这也是因为内部类持有对其父类的引用,这可能会泄漏Activity。

  

非静态内部类确实拥有对其父类的引用。将Fragment内部类设为非静态的问题在于,您始终持有对Activity的引用。 GarbageCollector无法收集您的活动。因此,如果方向发生变化,您可以“泄漏”活动。因为该片段可能仍然存在并被插入到新的活动中。

检查detailed answer并尝试制作片段