2015-09-04 10 views
11

Chromeのカスタムタブを実装し、LeakCanaryでメモリリークを検出しようとしています。Chromeのカスタムタブでメモリリークが検出されました

デモ・アプリケーションは、我々は別のアクティビティ層を追加しない限り漏れるように見えない( - MainActivitydemo appで行うすべてを、すなわちMainActivityは/カスタムタブサービスへのバインドを解除し、URLを起動し結合する、Activity2を起動します)。

MainActivityは次のようになります。

09-04 13:49:26.783 10456-12161/org.chromium.customtabsclient.example D/LeakCanary﹕ In org.chromium.customtabsclient.example:1.0:1. 
09-04 13:49:26.783 10456-12161/org.chromium.customtabsclient.example D/LeakCanary﹕ * org.chromium.customtabsclient.Activity2 has leaked: 
09-04 13:49:26.783 10456-12161/org.chromium.customtabsclient.example D/LeakCanary﹕ * GC ROOT android.support.customtabs.CustomTabsClient$1.val$callback (anonymous class extends android.support.customtabs.ICustomTabsCallback$Stub) 
09-04 13:49:26.783 10456-12161/org.chromium.customtabsclient.example D/LeakCanary﹕ * references org.chromium.customtabsclient.Activity2$2.this$0 (anonymous class extends android.support.customtabs.CustomTabsCallback) 
09-04 13:49:26.783 10456-12161/org.chromium.customtabsclient.example D/LeakCanary﹕ * leaks org.chromium.customtabsclient.Activity2 instance 

https://gist.github.com/abvanpelt/ddbc732f31550b09fc27

私の質問がされています:これはデモアプリケーションのバグです。このリークが発生しますActivity2MainActivityからの復帰

public class MainActivity extends Activity implements OnClickListener { 
    private Button mLaunchButton; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     LeakCanary.install(getApplication()); 

     setContentView(R.layout.main); 

     mLaunchButton = (Button) findViewById(R.id.launch_button); 
     mLaunchButton.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View v) { 
     int viewId = v.getId(); 

     if (viewId == R.id.launch_button) { 
      Intent intent = new Intent(getApplicationContext(), Activity2.class); 
      startActivity(intent); 
     } 
    } 
} 

? (おそらくunbindCustomTabsService()には必要な分解がありませんか?)これはChromeカスタムタブライブラリ自体のバグですか?

ありがとうございます。

答えて

2

サンプルのMainActivityは、匿名の内部クラスとしてCustomTabsServiceConnectionおよびCustomTabsCallbackのインスタンスを作成します。

静的内部クラスに変更すると、thisのMainActivityへの参照が削除され、MainActivityへの参照がWeakReferencesとして設定されている場合、LeakCanaryはMainActivityの漏洩に関する報告を停止します。

ServiceConnectionがそのオブジェクトを監視するように設定されている場合、その漏れに関するカヌーリークレポートが表示されることがあります。これは、Chromeサービスにリンクされているため、GCがサーバー側で実行されるまでGCでクリーニングすることができないためです。

サービスをループでバインドおよびアンバインドするテストを作成しましたが、しばらくしてからServiceConnectionsが実際に収集されていることを確認しました。

ので、デモはサービスが切断された後、長い時間生きている活動のような重い物を持つ避け、MainActivityへの参照を保持しているServiceConnectionを避けるために向上させることができ、それが持つ問題ではありませんカスタムタブライブラリ。停止することを

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    this.unbindService(mServiceConnection); 
    mServiceConnection = null; 
} 

-

private void launchChromeCustomTab(final Context context, final Uri uri) { 

    mServiceConnection = new CustomTabsServiceConnection() { 
     @Override 
     public void onCustomTabsServiceConnected(ComponentName componentName, CustomTabsClient client) { 
      client.warmup(0L); 
      final CustomTabsIntent intent = new CustomTabsIntent.Builder().build(); 
      intent.launchUrl(context, uri); 
      mIsCustomTabsLaunched = true; 
     } 

     @Override 
     public void onServiceDisconnected(ComponentName name) { 
     } 
    }; 
    CustomTabsClient.bindCustomTabsService(context, "com.android.chrome", mServiceConnection); 
} 

に従ってください、あなたはこのmServiceConnection onDestroyメソッドをアンバインドする必要があるとして、あなたはcustomTabを起動している場合

- この質問のための答えを見つけることが

+0

ありがとう、これは、そのリークを修正しました。不思議なことに、Chromium 42で修正された別のリークが見つかっています(https://code.google.com/p/chromium/issues/detail?id=473146)。これはChromium 42で修正されました。 'ResourcesContextWrapperFactory'リークを参照してください。 :/ – Allison

+0

更新プログラムとして、githubのデモアプリケーションがメモリリークを防ぐために更新されました。 – andreban

+0

:(このリークの問題については何もできませんでしたが、まだ良い解決策を探しています。 私のアプリケーションで同じ問題が発生しています がServiceConnectionをリークしました – Manisha

1

投げる

android.app.ServiceConnectionLeaked: Activity <Your_Activity> has leaked ServiceConnection 
+0

onCreateまたはonStartでCustomTabsサービスに接続して、Chromeがバックグラウンドでタブが開きます。 launchChromeCustomTabの実装は、タブを開いたときにサービスに接続しているようです。これは、サービスへの接続の利点を無効にする可能性が高く、単にインテントを作成してlaunchUrlを直接呼び出した場合と同様の結果になります。 – andreban

関連する問題