Android Leak Canary 和 StreetViewPanoramaFragment

标签 android google-maps leakcanary

我已将 Leak Canary 添加到个人 Android 应用程序,并生成了以下堆栈跟踪:

05-13 06:49:15.589  27088-28230/com.upwardsnorthwards.blueplaqueslondon D/LeakCanary﹕ In com.upwardsnorthwards.blueplaqueslondon:1.2:3.
* com.upwardsnorthwards.blueplaqueslondon.activities.PanoramaActivity has leaked:
* GC ROOT thread com.google.maps.api.android.lib6.gmm6.streetview.bf.v (named 'Renderer')
* references com.google.maps.api.android.lib6.gmm6.streetview.f.mParent
* references android.widget.FrameLayout.mParent
* references android.widget.FrameLayout.mContext
* leaks com.upwardsnorthwards.blueplaqueslondon.activities.PanoramaActivity instance
* Reference Key: 9d5d97cd-865a-4f93-92c1-63f7a8589525
* Device: motorola motorola XT1021 condor_tescogb
* Android Version: 4.4.4 API: 19
* Durations: watch=5024ms, gc=236ms, heap dump=745ms, analysis=39070ms

导致此问题的 PanoramaActivity 有一个 onCreate 方法,如下所示:

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_panorama);
    final StreetViewPanoramaFragment streetViewPanoramaFragment =
            (StreetViewPanoramaFragment) getFragmentManager()
                    .findFragmentById(R.id.street_view_panorama);
    streetViewPanoramaFragment.getStreetViewPanoramaAsync(this);
    final Intent intent = getIntent();
    if (intent != null) {
        placemark = (Placemark) intent
                .getParcelableExtra(BluePlaquesConstants.PANORAMA_CLICKED_PARCLEABLE_KEY);
    }
}

此 Activity 的 .xml 布局文件如下所示:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/street_view_panorama"
    android:name="com.google.android.gms.maps.StreetViewPanoramaFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

我的项目 gradle 文件如下所示:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
    compile 'com.android.support:appcompat-v7:21.0.3'
    compile 'com.google.android.gms:play-services:6.5.87'
    compile 'com.github.hotchemi:android-rate:0.4.2'
    compile 'com.squareup:otto:1.3.6'
}

应用程序的完整源代码可在 https://github.com/seanoshea/BluePlaquesLondon-Android 获得。我在 https://github.com/seanoshea/BluePlaquesLondon-Android/issues/69 创建了一个问题来跟踪这个.

有没有其他人遇到过这个问题?您能否提出解决方案?

干杯,

肖恩

最佳答案

我最好的猜测是 StreetViewPanoramaFragment 保留了对长时间运行的后台任务的引用,并且您的 PanoramaActivity 已注册为该 fragment 的回调。

试一试:将回调分离到一个实例变量中,这样您就不必担心管理 StreetViewPanoramaFragment 的生命周期:

在 PanoramaActivity.java 中:

private OnStreetViewPanoramaReadyCallback mCallback;    

@Override
public void onCreate(final Bundle savedInstanceState) {
    // do the stuff you described

    mCallback = new OnStreetViewPanoramaReadyCallback() {
        // whatever this needs to implement
    };
    streetViewPanoramaFragment.getStreetViewPanoramaAsync(mCallback);

    // the rest of your stuff
}

@Override
public void onDestroy() {
    mCallback = null;
}

我不能保证这就是问题所在,但它可能会成为一个问题。如果后台有异步任务,并且您旋转设备,PanoramaActivity 将消失,但不能标记为垃圾回收,因为它在等待 streetViewPanoramaFragment 的回调时仍然保留。 p>

关于Android Leak Canary 和 StreetViewPanoramaFragment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30206808/

相关文章:

android - 无法将 json 格式的字符串转换为 Java 映射

Android 主从流示例

google-maps - Google map 未在 React 应用程序中呈现

javascript - 在谷歌地图中创建三 Angular 形

java - 为什么这个 Observable.timer() 会导致内存泄漏?

android - 如何在 ionic 应用程序中使用 Videogular 插件在视频上显示缩略图?

javascript - 什么触发 android chrome 显示 "make page mobile-friendly"面板?

android - Worklight 7.1 使用 mapkit cordova 插件打开本地 map 应用程序

android - DisplayLeakActivity 不存在

android - 使用 LeakCanary 在 DeathMonitor 上发生内存泄漏