I'm attempting to implement Chrome Custom Tabs and detecting a memory leak through LeakCanary.
The demo application does not appear to leak unless we add another Activity layer (i.e. MainActivity
launches Activity2
, which binds/unbinds to the custom tab service and launches the url -- everything the MainActivity
does in the demo app).
MainActivity looks like this:
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);
}
}
}
Returning from Activity2
to MainActivity
will cause this leak:
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
My question is: is this a bug in the demo application? (Maybe unbindCustomTabsService()
is missing some needed teardown?) Or is this a bug in the Chrome Custom Tabs library itself?
Thank you.
It is useful to fix the memory leak issue by blocking Flash in Google Chrome. Step 1: In Chrome, type chrome://settings/content/flash to the address bar. Step 2: Block sites from running Flash.
Severe memory leaks can even make sites unusable. Since the JavaScript memory leak detector is a part of the Google Chrome browser, you should not hesitate to select a profiling type and analyze your website’s memory usage. To find out how much memory different pages use, you should open the built-in Chrome Task Manager.
Step 1: Open Google Chrome and right-click on the tab bar. Step 2: Select Task Manager from the following pop-up menu. Step 3: It will open the task manager and you can see the amount of RAM used by Chrome tabs, extensions, and services. Step 4: Select the process with unnecessary high RAM usage and hit the End Process button at the bottom.
In this tutorial, we are going to take a look at the Memory panel of the Chrome Developer Tools. This panel is used to find memory issues such as memory leaks, bloats, and garbage collections, which all affect the page performance. The Chrome Memory tab is used to diagnose and fix memory issues such as leaks, bloats, garbage collections.
Found the Answer for this question -
If you are launching customTab as follow
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);
}
Then you need to unbind this mServiceConnection onDestroy method as -
@Override
protected void onDestroy() {
super.onDestroy();
this.unbindService(mServiceConnection);
mServiceConnection = null;
}
That will stop throwing
android.app.ServiceConnectionLeaked: Activity <Your_Activity> has leaked ServiceConnection
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With