我正在创建一个应用程序,其中有显示数据给用户的屏幕。
每个Screen
都有自己的数据和布局,因此它有一种方法来返回代表用于填充它的布局的int
,然后将此View
传递给函数以查找特定视图并使用数据填充它。
生命周期如下: MainPresenter:
screen.getNextScreen ->
screen.getLayout ->
view = inflateScreen ->
screen.populateScreen(view) ->
(wait for time elappsed or click) -> repeat
这些Screens
也需要在SettingsActivity
中启用或禁用。
因此,我创建了一个单例的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
,因此我认为这不是问题所在。
此外,每个屏幕都有一个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()
Activity
,它会附加一个视图,然后将其删除并附加另一个视图。该视图是在MainPresenter中填充的。我认为当一个视图被删除时,它会被垃圾回收,除了一些我标记为缓存的视图。@FcoP. 这是一个包装器。它有一个方法来获取视图并填充数据。我将编辑以添加Screen
代码示例。 - Ari MFragment
的生命周期过于复杂了。 - Ari M