Android 活动泄露了在Galaxy S4中获取Google AdId的ServiceConnection

Android 活动泄露了在Galaxy S4中获取Google AdId的ServiceConnection,android,memory-leaks,google-play-services,Android,Memory Leaks,Google Play Services,我正在努力为我的应用程序获取谷歌的广告ID。但当我在我的Galaxy S4(4.3)上测试它时,它工作了。它以泄漏的ServiceConnection错误结束。这不会使强制关闭,但每次单击“活动”上的“上一步”按钮时都会打印错误日志。S4为新出厂复位状态。在我的Galaxy J5(6.0.1)上很好 我看到播放服务已过时,AdId为空 W/GooglePlayServicesUtil:googleplayservices过时了。需要10084000,但找到3225130 有什么办法解决这个问题吗

我正在努力为我的应用程序获取谷歌的广告ID。但当我在我的Galaxy S4(4.3)上测试它时,它工作了。它以泄漏的ServiceConnection错误结束。这不会使强制关闭,但每次单击“活动”上的“上一步”按钮时都会打印错误日志。S4为新出厂复位状态。在我的Galaxy J5(6.0.1)上很好

我看到播放服务已过时,AdId为空

W/GooglePlayServicesUtil:googleplayservices过时了。需要10084000,但找到3225130

有什么办法解决这个问题吗

代码

公共静态类InitialishingTask扩展了AsyncTask{
private final String TAG=InitialisingTask.class.getSimpleName();
@凌驾
受保护的Void doInBackground(上下文…上下文){
上下文=上下文[0];
adverisingidclient.Info idInfo=null;
试一试{
idInfo=AdvertisingIdClient.getAdvertisingIdInfo(上下文);
}catch(Google PlayServicesNotAvailableException | Google PlayServicesRepairableeException | IOException){
Log.w(标记,“获取谷歌广告失败。异常消息=“+e.getMessage());
}
if(idInfo!=null){
字符串adId=idInfo.getId();
setAdId(adId);
Log.d(标记“获取谷歌广告id已完成。adId=“+adId”);
}
返回null;
}
}
错误日志

02-24 00:42:59.611 24301-24301/com.company.android.sample E/ViewRootImpl: sendUserActionEvent() mView == null
02-24 00:42:59.611 24301-24301/com.company.android.sample E/ActivityThread: Activity com.company.android.sample.MainActivity has leaked ServiceConnection com.google.android.gms.common.zza@42b401c0 that was originally bound here
                                                                             android.app.ServiceConnectionLeaked: Activity com.company.android.sample.MainActivity has leaked ServiceConnection com.google.android.gms.common.zza@42b401c0 that was originally bound here
                                                                                 at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:979)
                                                                                 at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:873)
                                                                                 at android.app.ContextImpl.bindServiceAsUser(ContextImpl.java:1818)
                                                                                 at android.app.ContextImpl.bindService(ContextImpl.java:1806)
                                                                                 at android.content.ContextWrapper.bindService(ContextWrapper.java:503)
                                                                                 at com.google.android.gms.common.stats.zza.zza(Unknown Source)
                                                                                 at com.google.android.gms.common.stats.zza.zza(Unknown Source)
                                                                                 at com.google.android.gms.ads.identifier.AdvertisingIdClient.zzf(Unknown Source)
                                                                                 at com.google.android.gms.ads.identifier.AdvertisingIdClient.zze(Unknown Source)
                                                                                 at com.google.android.gms.ads.identifier.AdvertisingIdClient.getAdvertisingIdInfo(Unknown Source)
                                                                                 at com.skb.nads.internal.sdk.v1.AdSdk$1.run(AdSdk.java:115)
                                                                                 at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390)
                                                                                 at java.util.concurrent.FutureTask.run(FutureTask.java:234)
                                                                                 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
                                                                                 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
                                                                                 at java.lang.Thread.run(Thread.java:841)
02-24 00:42:59.611 24301-24301/com.company.android.sample E/ViewRootImpl:sendUserActionEvent()mView==null
02-24 00:42:59.611 24301-24301/com.company.android.sample E/ActivityThread:Activity com.company.android.sample.main活动已泄漏ServiceConnection com.google.android.gms.common。zza@42b401c0原来是订在这里的
android.app.ServiceConnection泄漏:Activity com.company.android.sample.main Activity已泄漏ServiceConnection com.google.android.gms.common。zza@42b401c0原来是订在这里的
在android.app.LoadedApk$ServiceDispatcher上。(LoadedApk.java:979)
位于android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:873)
位于android.app.ContextImpl.bindServiceAsUser(ContextImpl.java:1818)
位于android.app.ContextImpl.bindService(ContextImpl.java:1806)
位于android.content.ContextWrapper.bindService(ContextWrapper.java:503)
位于com.google.android.gms.common.stats.zza.zza(未知来源)
位于com.google.android.gms.common.stats.zza.zza(未知来源)
在com.google.android.gms.ads.identifier.advisingidclient.zzf(未知来源)
在com.google.android.gms.ads.identifier.advisingidclient.zze(未知来源)
在com.google.android.gms.ads.identifier.advisingidclient.getadvisingidinfo(未知来源)
位于com.skb.nads.internal.sdk.v1.AdSdk$1.run(AdSdk.java:115)
位于java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390)
在java.util.concurrent.FutureTask.run(FutureTask.java:234)处
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
运行(Thread.java:841)

使用
ContextWrapper
捕获泄漏的
ServiceConnection
解决

    @Override
    protected Void doInBackground(Context... contexts) {

        Context context = contexts[0];

        final List<ServiceConnection> leakableServiceList = new ArrayList<>(1);
        try {
            ContextWrapper contextWrapper = new ContextWrapper(context) {
                @Override
                public boolean bindService(Intent service, ServiceConnection conn, int flags) {
                    if ("com.google.android.gms.ads.identifier.service.START".equals(service.getAction())
                            && "com.google.android.gms".equals(service.getPackage())) {
                        leakableServiceList.add(conn);
                    }
                    return super.bindService(service, conn, flags);
                }
            };
            AdvertisingIdClient.setShouldSkipGmsCoreVersionCheck(true);
            AdvertisingIdClient.Info idInfo = AdvertisingIdClient.getAdvertisingIdInfo(contextWrapper);
            if (idInfo != null) {
                String adId = idInfo.getId();
                setAdId(adId);
                Log.d(TAG, "fetching Google Ads id finished. adId=" + adId);
            }
            // https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient
        } catch (GooglePlayServicesNotAvailableException | GooglePlayServicesRepairableException | IOException | IllegalStateException e) {
            Log.w(TAG, "fetch Google Ads is failed. exception message=" + e.getMessage());
        } finally {
            for (ServiceConnection conn: leakableServiceList) {
                try {
                    context.unbindService(conn);
                    Log.w(TAG, "Oh! leaking service connection is detected and fixed.");
                } catch(IllegalArgumentException e) {
                    // OK - already unbind and not leaked!
                } catch(Throwable t) {
                    Log.e(TAG, "something terrible happens", t);
                }
            }
        }

        return null;
    }
@覆盖
受保护的Void doInBackground(上下文…上下文){
上下文=上下文[0];
最终列表leakableServiceList=新的ArrayList(1);
试一试{
ContextWrapper ContextWrapper=新的ContextWrapper(上下文){
@凌驾
公共布尔绑定服务(意图服务、服务连接连接、int标志){
if(“com.google.android.gms.ads.identifier.service.START.”等于(service.getAction())
&&“com.google.android.gms”.equals(service.getPackage())){
leakableServiceList.add(连接);
}
返回super.bindService(服务、连接、标志);
}
};
AdvertisingIdClient.setShouldSkipGmsCoreVersionCheck(true);
AdvertisingIdClient.Info idInfo=AdvertisingIdClient.getAdvertisingIdInfo(contextWrapper);
if(idInfo!=null){
字符串adId=idInfo.getId();
setAdId(adId);
Log.d(标记“获取谷歌广告id已完成。adId=“+adId”);
}
// https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient
}catch(Google PlayServicesNotAvailableException | Google PlayServicesRepairableException | IOException |非法状态异常e){
L
    @Override
    protected Void doInBackground(Context... contexts) {

        Context context = contexts[0];

        final List<ServiceConnection> leakableServiceList = new ArrayList<>(1);
        try {
            ContextWrapper contextWrapper = new ContextWrapper(context) {
                @Override
                public boolean bindService(Intent service, ServiceConnection conn, int flags) {
                    if ("com.google.android.gms.ads.identifier.service.START".equals(service.getAction())
                            && "com.google.android.gms".equals(service.getPackage())) {
                        leakableServiceList.add(conn);
                    }
                    return super.bindService(service, conn, flags);
                }
            };
            AdvertisingIdClient.setShouldSkipGmsCoreVersionCheck(true);
            AdvertisingIdClient.Info idInfo = AdvertisingIdClient.getAdvertisingIdInfo(contextWrapper);
            if (idInfo != null) {
                String adId = idInfo.getId();
                setAdId(adId);
                Log.d(TAG, "fetching Google Ads id finished. adId=" + adId);
            }
            // https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient
        } catch (GooglePlayServicesNotAvailableException | GooglePlayServicesRepairableException | IOException | IllegalStateException e) {
            Log.w(TAG, "fetch Google Ads is failed. exception message=" + e.getMessage());
        } finally {
            for (ServiceConnection conn: leakableServiceList) {
                try {
                    context.unbindService(conn);
                    Log.w(TAG, "Oh! leaking service connection is detected and fixed.");
                } catch(IllegalArgumentException e) {
                    // OK - already unbind and not leaked!
                } catch(Throwable t) {
                    Log.e(TAG, "something terrible happens", t);
                }
            }
        }

        return null;
    }