【日志分析】退出插件界面时无法卸载插件,错误解决方案pm clear 引起内存泄漏

问题描述

期望行为:退出插件时(即不使用时)将插件卸载——这样才满足插件化需求。

问题:为了解决插件不正常卸载的问题 ,在断连的时候强制pm clear 插件会导致宿主也自动关闭了,进而引起内存泄漏

错误代码

@Override
public void onPluginDisconnected(IPluginUi plugin) {
    if (mPlugin == plugin) mPlugin = null;//判断是否同一对象(内存地址相同)
    Log.d(PLUGIN_TAG,"onPluginDisconnected " + plugin);
    String pkgName = "com.tool.plugin";
    try {
        Runtime runtime = Runtime.getRuntime();
        runtime.exec("pm clear " + pkgName);
        Log.d(PLUGIN_TAG,"onPluginDisconnected: runtime execute pm clear " + pkgName);
    } catch (Exception e) {
        Log.d(PLUGIN_TAG, "Error while onPluginDisconnected " + e);
    }
}

日志分析

原因:由于在Activity生命周期结束时未正确解除绑定的ServiceConnection引起的ServiceConnection内存泄漏

07-05 07:42:57.480 17441 17441 D PluginListener: onPluginDisconnected: runtime execute pm clear com.tool.plugin
07-05 07:42:57.482  1358  5599 V ActivityTaskManager: Make invisible? ActivityRecord{8eff59a u0 com.android.settings/.Settings t34} finishing=false state=STOPPED containerShouldBeVisible=true behindFullyOccludedContainer=true mLaunchTaskBehind=false
07-05 07:42:57.482  1358  5599 V ActivityTaskManager: Already invisible: ActivityRecord{8eff59a u0 com.android.settings/.Settings t34}
07-05 07:42:57.482  1358  5599 V ActivityTaskManager: ensureActivitiesVisible behind ActivityRecord{4c28d0d u0 com..android.launcher/.uioverrides.QuickstepLauncher t7}
07-05 07:42:57.482 17441 17441 E ActivityThread: Activity com.android.settings.SubSettings has leaked ServiceConnection com.android.settings.network.telephony.NetworkPreferenceCategoryController$1@9e05856 that was originally bound here
07-05 07:42:57.482 17441 17441 E ActivityThread: android.app.ServiceConnectionLeaked: Activity com.android.settings.SubSettings has leaked ServiceConnection com.android.settings.network.telephony.NetworkPreferenceCategoryController$1@9e05856 that was originally bound here

从日志能学习Actvity线程执行的相关生命周期流程。

07-05 07:42:57.482 17441 17441 E ActivityThread:     at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:2113)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at android.app.LoadedApk.getServiceDispatcherCommon(LoadedApk.java:1985)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:1964)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:2141)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at android.app.ContextImpl.bindService(ContextImpl.java:2017)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at android.content.ContextWrapper.bindService(ContextWrapper.java:863)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at com.android.settings.network.telephony.NetworkPreferenceCategoryController.bindNetworkQueryService(NetworkPreferenceCategoryController.java:285)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at com.android.settings.network.telephony.NetworkPreferenceCategoryController.registerNetworkQueryService(NetworkPreferenceCategoryController.java:171)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at com.android.settings.network.telephony.MobileNetworkSettings.onCreate(MobileNetworkSettings.java:514)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at androidx.fragment.app.Fragment.performCreate(Fragment.java:3094)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:504)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:268)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1943)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1839)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1782)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at androidx.fragment.app.FragmentManager.executePendingTransactions(FragmentManager.java:641)
07-05 07:42:57.482 17441 17441 E ActivityThread:     at com.android.settings.SettingsActivity.switchToFragment(SettingsActivity.java:799)

代码解读

Fragment创建的时候,因为注册了网络相关服务,而pm clear时没有取消服务出错导致内存泄漏

package com.android.settings.network.telephony;

@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class MobileNetworkSettings extends AbstractMobileNetworkSettings implements
        MobileNetworkRepository.MobileNetworkCallback {

    @Override
    public void onCreate(Bundle icicle) {
        final TelephonyStatusControlSession session =
                setTelephonyAvailabilityStatus(getPreferenceControllersAsList());

        super.onCreate(icicle);
        final Context context = getContext();
        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
        mTelephonyManager = context.getSystemService(TelephonyManager.class)
                .createForSubscriptionId(mSubId);

        session.close();
            
        //安装插件并监听
        Log.d(LOG_TAG,"onPluginConnected during onCreate ");
        PluginManagerWrapper.getInstance(context).addPluginListener(mPluginListener,IPluginUi.class
,true);

        onRestoreInstance(icicle);
        //注册了服务
        use(OpNetworkPreferenceCategoryController.class).registerNetworkService();
    }


}


http://www.niftyadmin.cn/n/5537199.html

相关文章

【Linux】服务器被work32病毒入侵CPU占用99%

文章目录 一、问题发现二、问题解决2.1 清楚病毒2.2 开启防火墙2.3 修改SSH端口2.4 仅使用凭据登录&#xff08;可选&#xff09; 一、问题发现 我的一台海外服务器&#xff0c;一直只运行一项服务&#xff08;你懂的&#xff09;&#xff0c;但是前不久我发现CPU占用99%。没在…

input调用手机摄像头实现拍照功能vue

项目需要一个拍照功能&#xff0c;实现功能如下图所示:若使用浏览器则可以直接上传图片&#xff0c;若使用手机则调用手机摄像头拍照。 1.代码结构 <!--input标签--> <input ref"photoRef"type"file"accept"image/*"capture"envir…

efibootmgr 命令及其用途

efibootmgr 是一个在基于 UEFI 的系统上用于管理 EFI 引导项的工具。它允许用户查看、创建、删除和修改 EFI 引导项。以下是一些常见的 efibootmgr 命令及其用途&#xff1a; 查看当前引导项 sudo efibootmgr这个命令会列出所有当前配置的 EFI 引导项。 添加新的引导项 假设…

在C++中内存泄露的几种情况及解决内存泄露和指针越界有哪些方法?

一、在C中&#xff0c;内存泄露通常指的是程序在动态分配内存后未能正确地释放这些内存&#xff0c;导致系统资源被持续占用而无法被其他程序或该程序的后续部分使用。以下是C中内存泄露的几种常见情况&#xff0c;按照不同的原因进行分类和归纳&#xff1a; 忘记释放内存&…

海外金融机构银行保险证券数字化转型营销销售数字化成功案例讲师培训师讲授开户销售营销客户AI人工智能创新思维

金融机构需要数字营销的主要原因 数字银行、直接存款和移动网络的兴起让客户无需前往当地分行即可轻松办理银行业务。这些举措不仅提升了用户体验&#xff0c;也迫使银行向数字化世界迈进。 金融服务公司需要在数字营销渠道上保持稳固的地位&#xff0c;以免落后于大型机构。…

【高考】【填志愿】分数限制下,选好专业还是选好学校?

【高考】选专业时&#xff0c;应避免的误区-CSDN博客 【高考】选专业时以什么为主&#xff1f;-CSDN博客 分数限制下&#xff0c;选好专业还是选好学校&#xff1f;-CSDN博客 分数限制下&#xff0c;选好专业还是选好学校&#xff1f;-CSDN博客 分数限制下&#xff0c;选好专…

专业的酱酒鉴评方法及要求

在探讨酱酒鉴评的领域&#xff0c;我们不仅需要关注鉴评的基本方法&#xff0c;还要深入了解品评环境的设置、品酒杯的选择以及品酒员的专业素质。这些因素共同构成了酱酒鉴评的完整体系&#xff0c;确保了鉴评结果的科学性和准确性。 酱酒鉴评的基本方法 酱酒鉴评主要依赖于…

C语言_指针初阶(进阶还在更新中)

指针是什么 指针是内存中一个最小单元的编号&#xff0c;也就是地址平时口语中说的指针&#xff0c;通常指的是指针变量&#xff0c;是用来存放内存地址的变量指针就是地址&#xff0c;口语中说的指针通常指的是指针变量。我们可以通过&&#xff08;取地址操作符&#xff…