我已将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);
}
}
此活动的.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创建了一个问题来跟踪此问题。
还有其他人遇到过这个问题吗?你能提出解决方案吗?
干杯,
肖恩
答案 0 :(得分:1)
我最好的猜测是StreetViewPanoramaFragment
保留对长时间运行的后台任务的引用,并且您的PanoramaActivity被注册为该片段的回调。
试一试:将回调分离为实例变量,这样您就不必担心管理该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的回调。