Skip to content

Commit 453790a

Browse files
committed
重构框架对于内存泄漏处理的逻辑
1 parent e99b528 commit 453790a

4 files changed

Lines changed: 132 additions & 105 deletions

File tree

README.md

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -204,29 +204,6 @@ public final class WindowLifecycleControl implements Application.ActivityLifecyc
204204
}
205205
```
206206

207-
#### LeakCanary 一直报内存泄漏怎么办?
208-
209-
* 这个问题是 EasyWindow 取消显示之后,没有回收资源才会出现的,目前比较好的解决方案是增加一个取消监听,然后在里面调用 `recycle` 方法即可
210-
211-
```java
212-
EasyWindow.with(this)
213-
.setOnWindowLifecycleCallback(new OnWindowLifecycleCallback() {
214-
215-
@Override
216-
public void onWindowCancel(@NonNull EasyWindow<?> easyWindow) {
217-
// 在窗口消失的时候回收资源,避免 LeakCanary 一直报内存泄漏
218-
easyWindow.recycle();
219-
}
220-
})
221-
.show();
222-
```
223-
224-
* 到这里你可能会有一个疑惑,这样的代码为什么框架不内部进行处理?而是交给外层开发者去处理,这难道不是脱裤子放屁?在这里我觉得有必要解释一下,原因有以下两点:
225-
226-
1. 不是框架不会处理,而是不能处理,因为窗口取消的时候,直接帮你回收窗口资源,如果你在外层持有了 `easyWindow` 对象,并且调用了相关的方法,会导致不会奏效,例如你取消窗口只是暂时的,等下还要恢复显示,你如果复用了 `easyWindow` 对象并且调用了 `easyWindow.show` 方法后窗口是不会显示,这是因为你前面调用了 `easyWindow.recycle`,窗口所有的资源已经被回收了,不能再次展示了,你调用了也是无效,至于要不要在窗口取消的会调用中调用回收窗口资源的办法,这个要取决你在外层有没有复用 `easyWindow` 对象去做什么事,如果没有就可以放心大胆调用 `easyWindow.recycle`,如果有的话,则不行。
227-
228-
2. 框架内部其实有做对窗口资源回收的动作,框架内部会通过 `registerActivityLifecycleCallbacks` 监听 `Activity` 生命周期,发现有 `Activity` 销毁后,会查找这个上下文相关的窗口对象,然后进行调用 `easyWindow.recycle` 对窗口资源进行回收,那这样为什么 `LeakCanary` 还会报内存泄漏?这是因为 `LeakCanary``Activity` 还没有结束的时候就急不可耐地去检查对象是否出现了内存泄漏,所以才出现了这个问题,作为框架作者我表示很受伤,至于处理方案你其实可以参考一下第一点。
229-
230207
#### 框架的 API 介绍
231208

232209
* 对象方法

app/src/main/java/com/hjq/window/demo/MainActivity.java

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,6 @@ public void onClick(View v) {
100100
.setWindowAnim(R.style.TopAnimStyle)
101101
.setImageDrawableByImageView(android.R.id.icon, R.drawable.ic_dialog_tip_finish)
102102
.setTextByTextView(android.R.id.message, "这个动画是不是很骚")
103-
.setOnWindowLifecycleCallback(new OnWindowLifecycleCallback() {
104-
105-
@Override
106-
public void onWindowCancel(@NonNull EasyWindow<?> easyWindow) {
107-
// 如果 EasyWindow 在取消显示后,没有再次使用了,则应该在窗口消失的时候回收资源,
108-
// 避免 LeakCanary 一直报内存泄漏,关于这点框架文档有介绍,详情请看文档
109-
easyWindow.recycle();
110-
}
111-
})
112103
.show();
113104

114105
} else if (viewId == R.id.btn_main_duration) {
@@ -119,15 +110,6 @@ public void onWindowCancel(@NonNull EasyWindow<?> easyWindow) {
119110
.setWindowAnim(R.style.IOSAnimStyle)
120111
.setImageDrawableByImageView(android.R.id.icon, R.drawable.ic_dialog_tip_error)
121112
.setTextByTextView(android.R.id.message, "一秒后自动消失")
122-
.setOnWindowLifecycleCallback(new OnWindowLifecycleCallback() {
123-
124-
@Override
125-
public void onWindowCancel(@NonNull EasyWindow<?> easyWindow) {
126-
// 如果 EasyWindow 在取消显示后,没有再次使用了,则应该在窗口消失的时候回收资源,
127-
// 避免 LeakCanary 一直报内存泄漏,关于这点框架文档有介绍,详情请看文档
128-
easyWindow.recycle();
129-
}
130-
})
131113
.show();
132114

133115
} else if (viewId == R.id.btn_main_overlay) {
@@ -168,9 +150,6 @@ public void onWindowShow(@NonNull EasyWindow<?> easyWindow) {
168150
@Override
169151
public void onWindowCancel(@NonNull EasyWindow<?> easyWindow) {
170152
Snackbar.make(getWindow().getDecorView(), "消失回调", Snackbar.LENGTH_SHORT).show();
171-
// 如果 EasyWindow 在取消显示后,没有再次使用了,则应该在窗口消失的时候回收资源,
172-
// 避免 LeakCanary 一直报内存泄漏,关于这点框架文档有介绍,详情请看文档
173-
easyWindow.recycle();
174153
}
175154
})
176155
.show();
@@ -380,15 +359,6 @@ public void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {
380359
.setWindowDuration(1000)
381360
.setWindowAnim(R.style.ScaleAnimStyle)
382361
.setTextByTextView(android.R.id.message, "就问你溜不溜")
383-
.setOnWindowLifecycleCallback(new OnWindowLifecycleCallback() {
384-
385-
@Override
386-
public void onWindowCancel(@NonNull EasyWindow<?> easyWindow) {
387-
// 如果 EasyWindow 在取消显示后,没有再次使用了,则应该在窗口消失的时候回收资源,
388-
// 避免 LeakCanary 一直报内存泄漏,关于这点框架文档有介绍,详情请看文档
389-
easyWindow.recycle();
390-
}
391-
})
392362
.show();
393363
}
394364
}
@@ -456,15 +426,6 @@ public boolean onLongClick(@NonNull EasyWindow<?> easyWindow, @NonNull ImageView
456426
return false;
457427
}
458428
})
459-
.setOnWindowLifecycleCallback(new OnWindowLifecycleCallback() {
460-
461-
@Override
462-
public void onWindowCancel(@NonNull EasyWindow<?> easyWindow) {
463-
// 如果 EasyWindow 在取消显示后,没有再次使用了,则应该在窗口消失的时候回收资源,
464-
// 避免 LeakCanary 一直报内存泄漏,关于这点框架文档有介绍,详情请看文档
465-
easyWindow.recycle();
466-
}
467-
})
468429
.show();
469430
}
470431

0 commit comments

Comments
 (0)