为啥片段类应该是公开的?
Posted
技术标签:
【中文标题】为啥片段类应该是公开的?【英文标题】:Why fragment class should be public?为什么片段类应该是公开的? 【发布时间】:2018-12-23 20:41:55 【问题描述】:我发现一些线程解释了为什么 Fragment
类应该是 static
(而不是 非静态内部),例如 this。但是无法理解这个错误信息的原因:
这个片段类应该是公共的(...)
我使用 android Studio 3.1.2,这是我的代码的一部分:
public class MainActivity extends android.support.v7.app.AppCompatActivity
// ...
class DefaultFragment extends android.support.v4.app.Fragment
// ...
片段应该只在MainActivity
中使用。
编辑:IDE 消息中还有一些其他信息。但是关于构造函数:
来自片段文档:
每个片段都必须有一个空的构造函数,因此可以在恢复其活动状态时对其进行实例化。强烈建议子类不要有其他带参数的构造函数,因为片段重新实例化时不会调用这些构造函数;相反,参数可以由调用者使用 setArguments(Bundle) 提供,然后由 Fragment 使用 getArguments() 检索。
【问题讨论】:
应该只在 MainActivity 中使用...所以我猜你有答案... 在方向改变时,重新创建 Activity 并且框架在片段上创建新实例(并恢复之前的状态)。所以这里要创建 Fragment 的实例,框架要求提供公共构造函数。 @B001ᛦ;MainActivity
和 DefaultFragment
,两者都在同一个文件中(因此在同一个 package
下)。所以可以在MainActivity
中访问,而不必是public
。
@PankajKumar;谢谢。如果您发表评论作为答案,我会接受。
【参考方案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();
.....
【讨论】:
【参考方案2】:这也是因为内部类持有对其父类的引用,这可能会泄漏 Activity。
非静态内部类确实持有对其父类的引用。使 Fragment 内部类成为非静态的问题在于您始终持有对 Activity 的引用。 GarbageCollector 无法收集您的 Activity。因此,如果例如方向发生变化,您可以“泄漏”活动。因为 Fragment 可能仍然存在并被插入到新的 Activity 中。
检查detailed answer并尝试制作片段
【讨论】:
以上是关于为啥片段类应该是公开的?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的所有 Spring Boot 执行器端点都是公开可用的?