По существу, у меня есть утечка памяти, описанная здесь , обнаруженная LeakCanary.
![LC stacktrace](https://i.stack.imgur.com/1qPPw.png)
Я пытаюсь решить эту проблему, используя «Исправление сантехника» в приведенном выше сообщении, которое очищает очередь сообщений пустым сообщением. Предоставленный пример кода очищает очередь сообщений каждый раз, когда она становится бездействующей. Мне нужно очистить очередь только один раз, после того, как мое диалоговое окно закрыто:
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 нуждается в очистке?