跟踪LeakCanary在Android上报告的内存泄漏情况

时间:2017-12-15 19:58:59

标签: android leakcanary

我在LeakCanary报告的Android上发生了内存泄漏,但我无法找到如何跟踪它。

我有一个名为Splash的活动,它调用一个服务来获取配置数据,然后通过处理程序返回活动。

//Started like this in the Splash activity
ConfigDumpService.start(this, this, BaseService.DATA_CALLBACK_ACTION_SIMPLE);

其中start方法是:

public static void start(final Context context, final Handler.Callback handlerCallback, final int callbackAction) {
    final Messenger messenger = new Messenger(new Handler(handlerCallback));
    final Intent intent = new Intent(context, ConfigDumpService.class);
    intent.putExtra(BaseService.PARAM_MESSENGER, messenger);
    intent.putExtra(BaseService.PARAM_CALLBACK_ACTION, callbackAction);
    context.startService(intent);
}

Splash活动实现了Handler.Callback

@Override
public boolean handleMessage(final Message msg) {
    L.p("In Splash handleMessage(), thread: " + Thread.currentThread().getName());

    if (BaseService.DATA_RETRIEVE_SUCCESS == msg.arg1) {
        L.p("Message from ConfigService service is SUCCESS!");
        startApp();
    } else {
        L.p("Message from ConfigService service is FAIL!");
        showCannotContinueDialog();
    }
    return true;
}

ConfigDumpService

// Previously fetched some data...

final Message message = Message.obtain();
message.setData(bundle);

if (successful) {
    message.arg1 = BaseService.DATA_RETRIEVE_SUCCESS;
} else {
    message.arg1 = BaseService.DATA_RETRIEVE_FAIL;
}

try {
    final Messenger messenger = startIntent.getParcelableExtra(BaseService.PARAM_MESSENGER);
    messenger.send(message);
} catch (RemoteException e) {
    L.p("In onHandleIntent RemoteException");
    e.printStackTrace();
}

stopSelf();

在Splash活动中创建处理程序的另一个地方是在一小段延迟后启动主要活动:

final Handler handler = new Handler();
final Runnable mRunnable = new Runnable() {
    public void run() {

        DialogManager.removeAllDialogs();

        // Let the base activity know we're just starting the app
        BaseActivity.startWithHome(Splash.this, homeId, false, true);
        Splash.this.finish();
    }
};
handler.postDelayed(mRunnable, splashImageLoadWasSuccessful ? mSplashScreenWaitMilliseconds : 0);

调用堆栈并非超级有用。我很感激任何提示。

由于

enter image description here

1 个答案:

答案 0 :(得分:1)

我认为这与您实例化Handler.Callback的方式有关。由于您在SplashActivity中实施了Handler,因此您在邮件队列中保留了一个硬引用。相反,您应该实现自己的static类,如果它是内部类,它应该是Handler。在此自定义WeakReference中,您应该传递Activity reThis帖子会更详细地解释问题,并向您展示如何解决此问题。希望这会有所帮助;)