【发布时间】:2019-08-31 15:32:19
【问题描述】:
我正在创建一个应用程序,该应用程序具有向用户呈现数据的屏幕。
每个Screen 都有自己的数据和自己的布局,所以它有一个方法可以返回一个int,它表示用来膨胀它的布局,然后这个View 被传递给一个函数来查找特定的视图并用数据填充它。
生命周期是这样的: 主讲人:
screen.getNextScreen ->
screen.getLayout ->
view = inflateScreen ->
screen.populateScreen(view) ->
(wait for time elappsed or click) -> repeat
SettingsActivity 中也需要那些 Screens 来启用\禁用它们。
所以我创建了一个单例ScreenProvider,它初始化一次然后返回列表。
public class ScreenProvider {
private List<Screen> screens;
private static ScreenProvider instance = new ScreenProvider();
public static ScreenProvider getInstance(){
return instance;
}
private ScreenProvider() {
screens = new ArrayList<>();
screens.add(new Welcome());
screens.add(new CompoundScreen());
screens.add(new Times());
screens.add(new Messages());
screens.add(new Weekly());
}
public List<Screen> getScreenList() {
return Lists.newArrayList(screens);
}
}
它的接缝是,当应用程序运行时间过长时会崩溃或因内存泄漏而关闭,所以我添加了leakcanary,这是它的报告示例:
MainActivity has leaked:
D: * static ScreenProvider.!(instance)!
D: * ↳ ScreenProvider.!(screens)!
D: * ↳ ArrayList.!(array)!
D: * ↳ array Object[].!([0])!
D: * ↳ CompoundScreen.!(disposable)!
D: * ↳ LambdaObserver.!(onNext)!
D: * ↳ -$$Lambda$Screen$67KdQ1jl3VSjSvoRred5JqLGY5Q.!(f$1)!
D: * ↳ AppCompatTextView.mContext
D: * ↳ MainActivity
这只是一个例子,但几乎每个屏幕都有这样的泄漏。
LeakCanary 报告显示 TextView 有这个:D: | mAttachInfo = null 所以我认为这不是问题。
此外,每个Screen 都有一个onHide() 来清除一次性用品,当当前Screen 隐藏并在MainActivity.onStop() 中时调用它。
如何解决此泄漏? 我不应该在屏幕上使用单例吗? 如果没有,我如何从其他活动访问屏幕列表?
** 编辑 **
添加一些 Screen 每个屏幕覆盖的主要方法。
public abstract int getLayout();
public boolean shouldShow()
public void populateData(View view)
public void onHide()
public abstract int getScreenIndex();
public boolean shouldCacheView()
public int getDuration()
【问题讨论】:
-
您有什么理由在 MainActivity 中管理所有屏幕吗?这听起来一点都不好。如果你继续添加屏幕,它会如何结束?我会在每个屏幕上使用不同的片段和演示者,具有自己的生命周期、业务逻辑等。
-
屏幕是用于提供视图的接口或包装器,还是视图本身? Welcome 和其他人的同样问题
-
@DavidMiguel 是一个
Activity,带有一个单独的 FrameLayout,它附加一个视图、删除它并附加另一个视图。视图在 MainPresenter 中膨胀。我认为当视图将被删除时,它将被垃圾收集,除了一些我标记为缓存的视图。 @FcoP。它是一个包装器。它有一个获取视图并填充其数据的方法。我将编辑添加Screen代码 smaple。 -
@DavidMiguel 我认为
Fragment有一个不必要的复杂生命周期。
标签: android memory-leaks leakcanary