我在片段中使用AdMob。有时我会看到下面的堆栈
10-23 14:27:38.916: E/ActivityThread(21250): Activity com.applegrew.app.skywifiremote.MainActivity has leaked ServiceConnection com.google.android.gms.common.b@420e82e8 that was originally bound here
10-23 14:27:38.916: E/ActivityThread(21250): android.app.ServiceConnectionLeaked: Activity com.applegrew.app.skywifiremote.MainActivity has leaked ServiceConnection com.google.android.gms.common.b@420e82e8 that was originally bound here
10-23 14:27:38.916: E/ActivityThread(21250): at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:979)
10-23 14:27:38.916: E/ActivityThread(21250): at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:873)
10-23 14:27:38.916: E/ActivityThread(21250): at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1690)
10-23 14:27:38.916: E/ActivityThread(21250): at android.app.ContextImpl.bindService(ContextImpl.java:1673)
10-23 14:27:38.916: E/ActivityThread(21250): at android.content.ContextWrapper.bindService(ContextWrapper.java:517)
10-23 14:27:38.916: E/ActivityThread(21250): at com.google.android.gms.ads.identifier.a.b(SourceFile:179)
10-23 14:27:38.916: E/ActivityThread(21250): at com.google.android.gms.ads.identifier.a.a(SourceFile:207)
10-23 14:27:38.916: E/ActivityThread(21250): at com.google.android.a.t.d(SourceFile:83)
10-23 14:27:38.916: E/ActivityThread(21250): at com.google.android.a.t.b(SourceFile:131)
10-23 14:27:38.916: E/ActivityThread(21250): at com.google.android.a.q.a(SourceFile:258)
10-23 14:27:38.916: E/ActivityThread(21250): at com.google.android.a.q.a(SourceFile:195)
10-23 14:27:38.916: E/ActivityThread(21250): at com.google.android.gms.ads.internal.k.a(SourceFile:76)
10-23 14:27:38.916: E/ActivityThread(21250): at com.google.android.gms.ads.internal.request.c.f_(SourceFile:99)
10-23 14:27:38.916: E/ActivityThread(21250): at com.google.android.gms.ads.internal.util.b.run(SourceFile:17)
10-23 14:27:38.916: E/ActivityThread(21250): at com.google.android.gms.ads.internal.util.d.call(SourceFile:29)
10-23 14:27:38.916: E/ActivityThread(21250): at com.google.android.gms.ads.internal.util.e.call(SourceFile:49)
10-23 14:27:38.916: E/ActivityThread(21250): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
10-23 14:27:38.916: E/ActivityThread(21250): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
10-23 14:27:38.916: E/ActivityThread(21250): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
10-23 14:27:38.916: E/ActivityThread(21250): at java.lang.Thread.run(Thread.java:841)从堆栈跟踪来看,泄漏的来源似乎是AdMob代码。然而,在我的片断中,我有代码在片断被销毁时销毁AdMob视图。
我的片段中的片段。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initAd();
}
private void initAd() {
mAdView = (AdView) getView().findViewById(R.id.remote_pager_ad);
if (mAdView != null) {
AdRequest adRequest = new AdRequest.Builder().addTestDevice(
AdRequest.DEVICE_ID_EMULATOR).build();
mAdView.loadAd(adRequest);
}
}
@Override
public void onPause() {
mAdView.pause();
super.onPause();
}
@Override
public void onResume() {
super.onResume();
mAdView.resume();
}
@Override
public void onDestroy() {
mAdView.destroy();
super.onDestroy();
}发布于 2014-12-03 00:15:16
我在AdMob (Google Play服务)广告中遇到了一个类似的问题,它泄漏了大量的内存。使用MAT发现问题出在每个gms广告都被我的应用程序实例保留在sComponentCallbacks数组中。因此,我覆盖了registerComponentCallbacks()和unregisterComponentCallbacks(),以跟踪正在注册但从不注销的实例(当我假设它们应该这样做的时候)。此代码示例假定只有.gms.ads包有问题,但如果您发现其他导致类似泄漏的包,也可以将这些包添加到列表中:
public class MyApplication extends Application {
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@Override
public void registerComponentCallbacks(ComponentCallbacks callback) {
super.registerComponentCallbacks(callback);
ComponentCallbacksBehavioralAdjustmentToolIcs.INSTANCE.onComponentCallbacksRegistered(callback);
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
@Override
public void unregisterComponentCallbacks(ComponentCallbacks callback) {
ComponentCallbacksBehavioralAdjustmentToolIcs.INSTANCE.onComponentCallbacksUnregistered(callback);
super.unregisterComponentCallbacks(callback);
}
public void forceUnregisterComponentCallbacks() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
ComponentCallbacksBehavioralAdjustmentToolIcs.INSTANCE.unregisterAll(this);
}
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private static class ComponentCallbacksBehavioralAdjustmentToolIcs {
static ComponentCallbacksBehavioralAdjustmentToolIcs INSTANCE = new ComponentCallbacksBehavioralAdjustmentToolIcs();
private WeakHashMap<ComponentCallbacks, ApplicationErrorReport.CrashInfo> mCallbacks = new WeakHashMap<>();
private boolean mSuspended = false;
public void onComponentCallbacksRegistered(ComponentCallbacks callback) {
Throwable thr = new Throwable("Callback registered here.");
ApplicationErrorReport.CrashInfo ci = new ApplicationErrorReport.CrashInfo(thr);
if (BuildConfig.DEBUG) Log.w(TAG, "registerComponentCallbacks: " + callback, thr);
if (!mSuspended) {
if (callback.getClass().getName().startsWith("com.google.android.gms.ads")) {
mCallbacks.put(callback, ci);
}
// TODO: other classes may still prove to be problematic? For now, only watch for .gms.ads, since we know those are misbehaving
} else {
if (BuildConfig.DEBUG) Log.e(TAG, "ComponentCallbacks was registered while tracking is suspended!");
}
}
public void onComponentCallbacksUnregistered(ComponentCallbacks callback) {
if (!mSuspended) {
if (BuildConfig.DEBUG) {
Log.i(TAG, "unregisterComponentCallbacks: " + callback, new Throwable());
}
mCallbacks.remove(callback);
}
}
public void unregisterAll(Context context) {
mSuspended = true;
for (Map.Entry<ComponentCallbacks, ApplicationErrorReport.CrashInfo> entry : mCallbacks.entrySet()) {
ComponentCallbacks callback = entry.getKey();
if (callback == null) continue;
if (BuildConfig.DEBUG) {
Log.w(TAG, "Forcibly unregistering a misbehaving ComponentCallbacks: " + entry.getKey());
Log.w(TAG, entry.getValue().stackTrace);
}
try {
context.unregisterComponentCallbacks(entry.getKey());
} catch (Exception exc) {
if (BuildConfig.DEBUG) Log.e(TAG, "Unable to unregister ComponentCallbacks", exc);
}
}
mCallbacks.clear();
mSuspended = false;
}
}
}然后在BaseActivity的onPause() (或onDestroy())方法中,我调用forceUnregisterComponentCallbacks()方法:
@Override
public void onPause() {
((MyApplication) getApplicationContext()).forceUnregisterComponentCallbacks()
super.onPause();
}请注意,ComponentCallbacks是在ICS中引入的,所以如果您在ICS之前的版本中看到问题,那么这不是问题所在。
(我还意识到,这并没有解决OP中确定的确切问题,因为这与bindService()有关,而不是与ComponentCallbacks有关。但它使我们避免了相当大的内存泄漏,迫使我们完全禁用AdMob,直到可以发布热修复程序。)
发布于 2014-12-02 21:28:30
看起来你需要在你的活动失去上下文之前注销服务!当你在活动丢失后调用dismiss时,Dialog也会出现同样的问题。:-/
https://stackoverflow.com/questions/26525185
复制相似问题