Android 活动泄露了在Galaxy S4中获取Google AdId的ServiceConnection
我正在努力为我的应用程序获取谷歌的广告ID。但当我在我的Galaxy S4(4.3)上测试它时,它工作了。它以泄漏的ServiceConnection错误结束。这不会使强制关闭,但每次单击“活动”上的“上一步”按钮时都会打印错误日志。S4为新出厂复位状态。在我的Galaxy J5(6.0.1)上很好 我看到播放服务已过时,AdId为空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 有什么办法解决这个问题吗
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;
}