AdMob: "activity has leaked ServiceConnection" and "AdvertisingIdClient unbindService failed."
admob, android, memory-leaks
Solution
I'm seeing exactly the same behaviour just using the example quick start project from the AdMob website here. I'm seeing this running Lollipop on a Nexus 5.
Therefore this looks like an AdMob bug to me.
Is there anyway to get a reference to the AdMob service and unbind the service manually to see if that stops the error?
Problem
I'm using AdMob in my app. I followed implementation guidelines, and the banner is correctly showing and loading the ads. My MainActivity is responsible of creating references, building the AdRequest and showing the banner, as well as pausing, resuming, and destroying the AdView. Everytime the AdRequest has been loaded, when the Activity's onStop() is called, the following Exception is created: ``` 6706-6706/com.rocca.controlloSpese E/ActivityThread﹕ Activity com.rocca.controlloSpese.MainActivity has leaked ServiceConnection com.google.android.gms.common.b@52b1cc3c that was originally bound here android.app.ServiceConnectionLeaked: Activity com.rocca.controlloSpese.MainActivity has leaked ServiceConnection com.google.android.gms.common.b@52b1cc3c that was originally bound here at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:970) at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:864) at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1577) at android.app.ContextImpl.bindService(ContextImpl.java:1560) at android.content.ContextWrapper.bindService(ContextWrapper.java:517) at com.google.android.gms.ads.identifier.a.b(SourceFile:330) at com.google.android.gms.ads.identifier.a.a(SourceFile:187) at com.google.android.gms.ads.identifier.a.b(SourceFile:239) at com.google.android.a.t.f(SourceFile:132) at com.google.android.a.t.b(SourceFile:182) at com.google.android.a.q.a(SourceFile:258) at com.google.android.a.q.a(SourceFile:195) at com.google.android.gms.ads.internal.m.a(SourceFile:107) at com.google.android.gms.ads.internal.request.c.a(SourceFile:99) at com.google.android.gms.ads.internal.util.b.run(SourceFile:17) at com.google.android.gms.ads.internal.util.d.call(SourceFile:29) at com.google.android.gms.ads.internal.util.e.call(SourceFile:49) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:841) ``` followed by this info: ``` 6706-6781/com.rocca.controlloSpese I/AdvertisingIdClient﹕ AdvertisingIdClient unbindService failed. java.lang.IllegalArgumentException: Service not registered: com.google.android.gms.common.b@52b1cc3c at android.app.LoadedApk.forgetServiceDispatcher(LoadedApk.java:922) at android.app.ContextImpl.unbindService(ContextImpl.java:1611) at android.content.ContextWrapper.unbindService(ContextWrapper.java:529) at com.google.android.gms.ads.identifier.a.c(SourceFile:275) at com.google.android.gms.ads.identifier.b.c(SourceFile:100) at com.google.android.gms.ads.identifier.b.run(SourceFile:110) ``` This doesn't happen if the AdRequest is not built and loaded. I set up my IABHelper in onCreate(), and if the user didn't buy my "remove-ads" sku, ads are shown. This is the code I use to load the ads: ``` private void showAds() { int adresult = GooglePlayServicesUtil.isGooglePlayServicesAvailable(MainActivity.this); if (adresult == ConnectionResult.SUCCESS) { //if possible, show ads AdRequest adRequest = new AdRequest.Builder() .addTestDevice(AdRequest.DEVICE_ID_EMULATOR) .addTestDevice("C144E9DA02EA7B26F74ED2C231F31D38") .addTestDevice("93BABD84466B8C1EF529D2FB39D1ACE8") .addTestDevice("BEAA738068664AE9BBF673E37A782E03") .addTestDevice("E51508081F77DF84C129EE471DE67141") .build(); adView.setVisibility(View.VISIBLE); adView.loadAd(adRequest); } else { //if there's a problem, show error and close app GooglePlayServicesUtil.getErrorDialog(adresult, MainActivity.this, 0, new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialogInterface) { finish(); } }).show(); } } ``` adView's `pause()`, `resume()` and `destroy()` are called in the respective activity's methods. Practically, the app's performance isn't affected, but I'd rather avoid memory leaks. How do I avoid that exception? EDIT: the Manifest.xml ``` <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.rocca.controlloSpese" > <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="com.android.vending.BILLING" /> <uses-permission android:name="com.rocca.controlloSpese.BROADCAST_PERMISSION" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:finishOnCloseSystemDialogs="true" android:label="@string/app_name" android:launchMode="singleTop" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> <activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" /> </application> ```