【发布时间】:2019-04-12 21:49:33
【问题描述】:
我基本上有被 LeakCanary 检测到的here 描述的内存泄漏。
我正在尝试通过使用上述帖子中的“Plumber's Fix”来解决此问题,该帖子使用空消息刷新消息队列。每次空闲时提供的代码示例刷新消息队列。在我的对话框被解除后,我只需要刷新一次队列:
public class ExampleDialogFragment extends AppCompatDialogFragment {
public static ExampleDialogFragment newInstance() {
return new ExampleDialogFragment();
}
@NonNull
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
return new AlertDialog.Builder(getContext())
.setPositiveButton(android.R.string.ok, (dialog, which) -> onClicked())
.create();
}
private void onClicked() {
if (getTargetFragment() instanceof Callbacks) {
((Callbacks) getTargetFragment()).onButtonClicked();
flushStackLocalLeaks();
}
}
private static void flushStackLocalLeaks() {
final Handler handler = new Handler(Looper.myLooper());
handler.post(() -> Looper.myQueue().addIdleHandler(() -> {
Timber.d("Flushing on thread %s", Thread.currentThread().getName());
handler.sendMessageDelayed(handler.obtainMessage(), 1000);
return false; // we only want to flush once, not *every* 1000 mSec
}));
}
public interface Callbacks {
void onButtonClicked();
}
}
我面临的问题是,在 LeakCanary 报告中,位于泄漏根的 HandlerThread 绝不是我期望的线程。有时是ConnectivityThread,有时是HandlerThread,其中mName = "queued-work-looper",其他是我的分析库使用的HandlerThread。在这些情况下,它都不是主线程。我希望消息会从主线程泄漏。所以
- 为什么这种泄漏发生在主线程以外的 HandlerThread/ConnectivityThread 上?
- 我如何知道哪个 HandlerThread 需要刷新?
【问题讨论】:
-
您找到了解决办法吗?我发现最接近的是材料对话框框架的解决方法,但它们使用反射,我不确定这些 API 是否会被列入灰名单,所以不想做这个修复。 github.com/afollestad/material-dialogs/issues/513
-
已请@piwai 看看。
标签: android memory-leaks leakcanary