2017-12-15 11 views
0

LeakCanaryによって報告されたAndroidでメモリリークが発生しましたが、トレース方法がわかりません。AndroidでLeakCanaryによって報告されたトラックメモリリーク

私はスプラッシュと呼ばれるアクティビティを持っています。スプラッシュは1つのサービスを呼び出して設定データを取得し、ハンドラを介してアクティビティにpingを戻します。

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); 
} 

スプラッシュ活動が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(); 

ハンドラがcreatのある別の場所を実装しています:startメソッドがある

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

スプラッシュアクティビティでは、小さな遅延の後で主なアクティビティを開始することです:

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

+0

私たちがこれに答える方法はありません。あなたのサービスはアクティビティを呼び出す方法をどのように取得(および保存)しますか?その参照はクリーンアップされていますか? –

+0

[mcve]は、特にこの「スプラッシュ」アクティビティとこの「ハンドラ」を表示するのに役立ちます。 – CommonsWare

+0

@CommonsWareコードを追加しました。ありがとう。 – zundi

答えて

1

私はそれはあなたがあなたのHandlerをインスタンス化する方法に関係だと思います。 SplashActivityHandler.Callbackを実装しているので、メッセージキューにハードリファレンスが保持されます。代わりに独自のHandlerクラスを実装し、内部クラスの場合はstaticにする必要があります。このカスタム内でHandlerにはを入力してください。Thisの投稿で詳細を説明し、この問題の解決方法を示しています。これが役に立ちますようお願いいたします)

+0

ちょうど好奇心から、onHandle()メソッドが終了すると、SplashActivityはこの参照を失い、GC'edされるでしょうか?または、アクティビティの参照がメッセージキュー内で「永遠に」保持されますか? – zundi

関連する問題