android– 从onPause中的片段中删除位置更新时内存泄漏

android– 从onPause中的片段中删除位置更新时内存泄漏,第1张

概述在我的应用程序中的一个片段中,我需要位置更新,以确定用户何时接近一个简短的位置列表,以便用户可以获得相关信息.当我在onConnected()回调中使用创建位置更新请求时LocationServices.FusedLocationApi.requestLocationUpdates(client,LocationRequest.create(),this);我还使

在我的应用程序中的一个片段中,我需要位置更新,以确定用户何时接近一个简短的位置列表,以便用户可以获得相关信息.当我在onConnected()回调中使用创建位置更新请求时

LocationServices.FusedLocationAPI.requestLocationUpdates(clIEnt, LocationRequest.create(), this);

我还使用了删除onPause()方法中的更新

LocationServices.FusedLocationAPI.removeLocationUpdates(clIEnt, this);

然而,即使我调用该方法来删除位置更新,我也会从泄漏金丝雀那里得到警告,每当我离开该片段时,我的片段就会被泄露(所有片段导航都是使用replace()事务完成的).我在我的片段中启动位置请求时做错了什么,或者我没有在onPause()中正确清理请求,对此的任何帮助将不胜感激.

这是我的片段类的简化模型中的代码

public class BlankFragment extends Fragment implements Googleapiclient.ConnectionCallbacks    , Googleapiclient.OnConnectionFailedListener, LocationListener {private Googleapiclient clIEnt;private TextVIEw textVIEw;public BlankFragment() {    // required empty public constructor}@OverrIDepublic VIEw onCreateVIEw(LayoutInflater inflater, VIEwGroup container,                         Bundle savedInstanceState) {    VIEw root = inflater.inflate(R.layout.fragment_blank, container, false);    textVIEw = (TextVIEw) root.findVIEwByID(R.ID.location);    clIEnt = new Googleapiclient.Builder(getContext())            .addAPI(LocationServices.API)            .addConnectionCallbacks(this)            .addOnConnectionFailedListener(this)            .build();    return root;}@OverrIDepublic voID onConnected(@Nullable Bundle bundle) {    startLocationUpdates();}private voID startLocationUpdates() {    if (clIEnt.isConnected()) {       LocationServices.FusedLocationAPI.requestLocationUpdates(clIEnt, LocationRequest.create(), this);    }}private voID stopLocationUpdates(){    LocationServices.FusedLocationAPI.removeLocationUpdates(clIEnt, this);}@OverrIDepublic voID onConnectionSuspended(int i) {}@OverrIDepublic voID onConnectionFailed(@NonNull ConnectionResult connectionResult) {}@OverrIDepublic voID onLocationChanged(Location location) {    textVIEw.setText(location.toString());}@OverrIDepublic voID onResume() {    startLocationUpdates();    super.onResume();}@OverrIDepublic voID onPause() {    stopLocationUpdates();    super.onPause();}@OverrIDepublic voID onStart() {    clIEnt.connect();    super.onStart();}@OverrIDepublic voID onStop() {    if (clIEnt.isConnected()) {    clIEnt.disconnect();    }    super.onStop();}}

此处还有生成的泄漏迹线

In com.example.testlocation:1.0:1.* com.example.testlocation.BlankFragment has leaked:* GC ROOT com.Google.androID.gms.internal.zzary$zzb.zzaGN* references com.Google.androID.gms.internal.zzary.zzbkw (anonymous subclass of com.Google.androID.gms.internal.zzary$zza)* leaks com.example.testlocation.BlankFragment instance* Retaining: 7.1 KB.* Reference Key: 720085d5-af68-42f3-a291-ef959e4c8ffa* Device: Huawei Google Nexus 6P angler* AndroID Version: 7.1.2 API: 25 LeakCanary: 1.5 00f37f5* Durations: watch=5031ms, gc=167ms, heap dump=1418ms, analysis=137993ms* Details:* Instance of com.Google.androID.gms.internal.zzary$zzb|   static $classOverhead = byte[240]@316980881 (0x12e4be91)|   zzaGN = com.Google.androID.gms.internal.zzary@316955016 (0x12e45988)|   mDescriptor = java.lang.String@317419776 (0x12eb7100)|   mObject = 483616889632|   mOwner = com.Google.androID.gms.internal.zzary$zzb@317493408 (0x12ec90a0)|   shadow$_klass_ = com.Google.androID.gms.internal.zzary$zzb|   shadow$_monitor_ = 0* Instance of com.Google.androID.gms.internal.zzary|   static $classOverhead = byte[312]@317158785 (0x12e77581)|   zzbkw = com.example.testlocation.BlankFragment@316908800 (0x12e3a500)|   zzaxf = com.Google.androID.gms.common.API.API@317047488 (0x12e5c2c0)|   zzazY = com.Google.androID.gms.common.API.API$zzf@315109896 (0x12c83208)|   zzK = true|   zzaAh = java.lang.Object@315110136 (0x12c832f8)|   zzaAi = com.Google.androID.gms.internal.zzaaf$zza@317493376 (0x12ec9080)|   zzaAj = java.lang.ref.WeakReference@317491784 (0x12ec8a48)|   zzaAk = java.util.ArrayList@317491760 (0x12ec8a30)|   zzaAl = null|   zzaAm = java.util.concurrent.atomic.atomicreference@317340960 (0x12ea3d20)|   zzaAn = null|   zzaAo = false|   zzaAp = false|   zzaAq = null|   zzaAr = null|   zzaAs = false|   zzair = com.Google.androID.gms.common.API.Status@317061968 (0x12e5fb50)|   zzazt = com.Google.androID.gms.common.API.Status@317061968 (0x12e5fb50)|   zztj = java.util.concurrent.CountDownLatch@317340944 (0x12ea3d10)|   shadow$_klass_ = com.Google.androID.gms.internal.zzary|   shadow$_monitor_ = -1987877821* Instance of com.example.testlocation.BlankFragment|   static serialVersionUID = 8326097604377836997|   static $change = null|   static $classOverhead = byte[1168]@315449345 (0x12cd6001)|   clIEnt = com.Google.androID.gms.internal.zzaat@317202944 (0x12e82200)|   textVIEw = androID.support.v7.Widget.AppCompatTextVIEw@317036544 (0x12e59800)|   mAdded = false|   mAllowEnterTransitionOverlap = null|   mAllowReturnTransitionOverlap = null|   mAnimatingAway = null|   mArguments = null|   mBackStacknesting = 0|   mCalled = true|   mCheckedForLoaderManager = false|   mChildFragmentManager = null|   mChildNonConfig = null|   mContainer = null|   mContainerID = 0|   mDeferStart = false|   mDetached = false|   mEnterTransition = null|   mEnterTransitionCallback = androID.app.SharedElementCallback@1883261776 (0x70404b50)|   mExitTransition = null|   mExitTransitionCallback = androID.app.SharedElementCallback@1883261776 (0x70404b50)|   mFragmentID = 0|   mFragmentManager = null|   mFromLayout = false|   mHasMenu = false|   mHIDden = false|   mHost = null|   mInLayout = false|   mIndex = -1|   mloaderManager = null|   mloadeRSStarted = false|   mMenuVisible = true|   mNextAnim = 0|   mParentFragment = null|   mReenterTransition = androID.Transition.TransitionSet@1883202880 (0x703f6540)|   mRemoving = false|   mRestored = false|   mRetainInstance = false|   mRetaining = false|   mReturnTransition = androID.Transition.TransitionSet@1883202880 (0x703f6540)|   mSavedFragmentState = null|   mSavedVIEwState = androID.util.SparseArray@317491880 (0x12ec8aa8)|   mSharedElementEnterTransition = null|   mSharedElementReturnTransition = androID.Transition.TransitionSet@1883202880 (0x703f6540)|   mState = 0|   mStateAfteranimating = 0|   mTag = null|   mTarget = null|   mTargetIndex = -1|   mTargetRequestCode = 0|   mUserVisibleHint = true|   mVIEw = null|   mWho = null|   shadow$_klass_ = com.example.testlocation.BlankFragment|   shadow$_monitor_ = -2047550015* Excluded Refs:| FIEld: androID.vIEw.Choreographer$FramedisplayEventReceiver.mMessageQueue (always)| Thread:FinalizerWatchdogDaemon (always)| Thread:main (always)| Thread:LeakCanary-Heap-Dump (always)| Class:java.lang.ref.WeakReference (always)| Class:java.lang.ref.softReference (always)| Class:java.lang.ref.Phantomreference (always)| Class:java.lang.ref.Finalizer (always)| Class:java.lang.ref.FinalizerReference (always)

解决方法:

即使在调用removeLocationUpdates之后,Google Maps SDK也会泄漏内存,这是一个长期存在的问题.你可以阅读更多关于它here.

以下解决方法为我删除了泄漏金丝雀通知.

1)创建一个WeakLocationListener类,它将位置监听器包装在弱引用中,然后使用该类来处理onLocationChanged回调.

public class WeakLocationListener implements LocationListener {private final WeakReference<LocationListener> locationListenerRef;public WeakLocationListener(@NonNull LocationListener locationListener) {    locationListenerRef = new WeakReference<>(locationListener);}@OverrIDepublic voID onLocationChanged(androID.location.Location location) {    if (locationListenerRef.get() == null) {        return;    }    locationListenerRef.get().onLocationChanged(location);}

2)创建一个WeakLocationListener实例(使用您的片段实现的LocationListener)并在requestLocationUpdates和removeLocationUpdates时使用它 – 该位置将返回到您的activity / fragment(或任何正在实现LocationListener的类),并且泄漏金丝雀通知应该消失.

希望这可以帮助.

总结

以上是内存溢出为你收集整理的android – 从onPause中的片段中删除位置更新时内存泄漏全部内容,希望文章能够帮你解决android – 从onPause中的片段中删除位置更新时内存泄漏所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1111321.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存