jjzjj

Android需求2 -- MTK手机内存显示和清除后台

胖大师 2023-04-06 原文

Android需求2

设置中增加一个一级菜单显示内存信息,进入后的界面可自己定义,显示当前已用内存和手机总内存,同时还有一个按钮,点击按钮清理掉除设置外的所有后台应用。

系统内置的方法的获取内存的方法

  1. strings.xml中的 total_memory 属性 ,发现又系统方法获取内存,通过全局搜索 total_memory
  2. 发现 process_stats_summary的有一项的 title是 total_memory
  3. process_stats_summary进行 R.xml.process_stats_summary 全局搜索
  4. 发现 ProcessStatsSummary.java进行了调用,路径为 com.android.settings.applications,里面是获取内存的方法

手机总内存和已用内存的实现

  1. top_level_setting.xml中添加一级菜单,代码如下:

    <PreferenceScreen>
        ...
        ...
    	<Preference
            android:fragment="com.android.settings.memory.MemoryFragment"
            android:icon="@drawable/ic_phone_info"
            android:key="top_memory_info"
            android:order="40"
            android:title="@string/memory_info"
            android:summary="@string/read_memory_summary" />
    </PreferenceScreen>
    
  2. com.android.settings目录下新建一个包 memory,并在该包下新建一个类 MemoryFragment,该类继承 SettingsPreferenceFragment

    使用ActivityManager类来获取内存信息:

    ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
    manager.getMemoryInfo(memoryInfo);

    总内存: memoryInfo.totalMem

    可用内存: memoryInfo.availMem

    参考文件:https://blog.csdn.net/qq_34763699/article/details/82470191?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-82470191-blog-82630411.pc_relevant_multi_platform_whitelistv1&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-82470191-blog-82630411.pc_relevant_multi_platform_whitelistv1&utm_relevant_index=1

    package com.android.settings.memory;
    
    import android.app.ActivityManager;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.ActivityInfo;
    import android.content.pm.PackageManager;
    import android.os.Bundle;
    
    
    import android.os.RemoteException;
    import android.text.format.Formatter;
    import android.util.Log;
    import android.app.settings.SettingsEnums;
    import android.widget.Toast;
    
    import androidx.preference.Preference;
    
    import com.android.settings.R;
    import com.android.settings.SettingsPreferenceFragment;
    import com.android.settings.applications.ProcStatsData.MemInfo;
    import com.android.settings.applications.ProcessStatsBase;
    
    import java.util.List;
    
    
    public class MemoryFragment extends SettingsPreferenceFragment {
    
        private static final String TAG = "MemoryFragment";
        private Context context;
    
    
        private static final String KEY_TOTAL_MEMORY = "my_total_memory";
        private static final String KEY_USED_MEMORY = "my_used_memory";
    
        private Preference mTotalMemory;
        private Preference mUsedMemory;
    
        @Override
        public void onCreate(Bundle icicle) {
            super.onCreate(icicle);
    
            addPreferencesFromResource(R.xml.memory_info_show);
    
            mTotalMemory = findPreference(KEY_TOTAL_MEMORY);
            mUsedMemory = findPreference(KEY_USED_MEMORY);
    
            showMemory();
    
        }
    
        public void showMemory(){
            // Get Memory information
            ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
            manager.getMemoryInfo(memoryInfo);
    
            String totalMemory = Formatter.formatShortFileSize(context, memoryInfo.totalMem);
            String availMemory = Formatter.formatShortFileSize(context, memoryInfo.availMem);
            Log.d(TAG, "totalMemory: " + totalMemory + "<==> availMemory==> " + availMemory);
    
            //Assign memory information to the control
            mTotalMemory.setSummary(totalMemory);
            mUsedMemory.setSummary(availMemory);
        }
    
        @Override
        public int getMetricsCategory() {
            return SettingsEnums.PROCESS_STATS_SUMMARY;
        }
    
        @Override
        public int getHelpResource() {
            return 0;
        }
    
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            this.context = context;
        }
    
    
    }
    
    
  3. xml包下 新建一个二级目录布局文件 ,名为 memory_info_show.xml

    <PreferenceScreen
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:settings="http://schemas.android.com/apk/res-auto"
        android:key="customize_menu"
        android:title="@string/memory_menu">
    
        <Preference
            android:key="my_total_memory"
            android:title="@string/total_memory"
            android:icon="@drawable/ic_emergency_gesture_24dp"
            android:order="100"/>
    
        <Preference
            android:key="my_used_memory"
            android:title="@string/used_memory"
            android:icon="@drawable/ic_emergency_gesture_24dp"
            android:order="150" />
    
    
    </PreferenceScreen>
    
  4. strings.xml中添加标题内容

    <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
        <!-- Memory Title -->
        <string name="memory_menu">Memory for Phone</string>
        <!-- Show Memory info -->
        <string name="memory_info">Show Memory</string>
        <!-- Memory Summary -->
        <string name="read_memory_summary">Memory</string>
        <!-- Used Memory -->
        <string name="used_memory">Used Memory</string>
        
        ...
        ...
    </resources>
    
  5. 效果实现

杀死除自己外的其他后台应用

清除多任务后台 Recents(多任务)

Android 9.0 与Android 8.1 中的点击Recent键清除按钮有些区别,之前Android 8.1 的全部清除按钮位于SystemUI中,而Android 9.0 的“全部清除”按钮位于Launcher3中;

**Android 获取上下文几个方法的区别 **

  1. getContext(): 这是View的一个方法,获取视图上下文,view一般是依托于Activity,所以这个方法返回的是当前Activity实例,一般在Activity中可以使用 YourActivityName.this代替。
  2. getApplicationContext(): 这个是获取整个生命周期的上下文,一般用于application中,获取app相关的基础信息。
  3. getBaseContext(): 是ContextWrapper中的方法,基本不用,Google也不推荐使用,是一种委托,在一个context获取另一个context。
  4. getApplication(): 这个是获取当前进程的Application实例,可以去操作自己写的Application中的方法。

SystemUI 的参考资料 : https://www.jianshu.com/p/2e0f403e5299

SystemUI 源码分析 :https://blog.csdn.net/u011164827/article/details/102998091

SystemUIrecents 实现流程分析 :https://blog.csdn.net/wcsbhwy/article/details/118893801

  1. SystemUI 的功能划分一般为以下几个部分
    • StatusBar(状态栏):通知消息提示和状态展示
    • NavigationBar(导航栏):返回,HOME,Recent
    • KeyGuard(键盘锁):锁屏模块
    • Recents:近期应用管理,以堆叠的形式展示
    • Notification Panel(通知面板):展示系统或应用的通知内容,提供快速系统设置开关
    • Volume:展示或控制音量的变化:媒体、铃音、通知、通话音量
    • ScreenShot(截屏):长按电源键+音量下键后截屏,用以展示截取的屏幕照片/内容
    • PowerUI:主要处理和Power相关的事件。
    • RingtonePlayer:铃音播放
    • StackDivider:控制管理分屏
    • PipUI:画中画管理(Android7.0)

工具使用 :在SDK目录下,sdk/tools/bin/uiautomatorviewer.bat 文件 , 双击打开文件 ,待进入 UI Automator Viewer,手机打开某个页面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HFMFBnC6-1655341417191)(E:\Typora–pictures\image-20220608150049720.png)]

清除任务后台除设置外

​ 通过ActivtyManager来进行获取和移除任务栈

参考资料https://blog.csdn.net/hacker_crazy/article/details/78365406

https://blog.csdn.net/hacker_crazy/article/details/78399303

https://blog.csdn.net/liu149339750/article/details/8111462

  1. 在二级布局文件 memory_info_show.xml中增加一个Preference来设置一个点击事件 my_clear_background

    <PreferenceScreen
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:settings="http://schemas.android.com/apk/res-auto"
        android:key="customize_menu"
        android:title="@string/memory_menu">
    
        <Preference
            android:key="my_total_memory"
            android:title="@string/total_memory"
            android:icon="@drawable/ic_emergency_gesture_24dp"
            android:order="100" />
    
        <Preference
            android:key="my_used_memory"
            android:title="@string/used_memory"
            android:icon="@drawable/ic_emergency_gesture_24dp"
            android:order="150" />
    
        <Preference
            android:key="my_clear_background"
            android:icon="@drawable/btn_clear_bg"
            android:title="@string/clear_title"
            android:summary="@string/clear_summary"
            android:order="160"/>
    
    </PreferenceScreen>
    
  2. 在实现类中MemoryFragment.java类中,获取控件的key,并为其添加点击事件,并通过ActivityManager类来进行获取开启的任务栈,并进行判断,移除任务栈,方法

    public void killAllAppsExceptionSettings()

    package com.android.settings.memory;
    
    import android.app.ActivityManager;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.ActivityInfo;
    import android.content.pm.PackageManager;
    import android.os.Bundle;
    
    
    import android.os.RemoteException;
    import android.text.format.Formatter;
    import android.util.Log;
    import android.app.settings.SettingsEnums;
    import android.widget.Toast;
    
    import androidx.preference.Preference;
    
    import com.android.settings.R;
    import com.android.settings.SettingsPreferenceFragment;
    import com.android.settings.applications.ProcStatsData.MemInfo;
    import com.android.settings.applications.ProcessStatsBase;
    
    import java.util.List;
    
    
    public class MemoryFragment extends SettingsPreferenceFragment implements Preference.OnPreferenceClickListener {
    
        private static final String TAG = "MemoryFragment";
        private Context context;
    
    
        private static final String KEY_TOTAL_MEMORY = "my_total_memory";
        private static final String KEY_USED_MEMORY = "my_used_memory";
        private static final String KEY_CLEAR_BACKGROUND = "my_clear_background";
    
        private Preference mTotalMemory;
        private Preference mUsedMemory;
        private Preference mClearBackground;
    
     	private long freeMemory;
    
        @Override
        public void onCreate(Bundle icicle) {
            super.onCreate(icicle);
    
            addPreferencesFromResource(R.xml.memory_info_show);
    
            mTotalMemory = findPreference(KEY_TOTAL_MEMORY);
            mUsedMemory = findPreference(KEY_USED_MEMORY);
            mClearBackground = findPreference(KEY_CLEAR_BACKGROUND);
    
            showMemory();
            mClearBackground.setOnPreferenceClickListener(this);
    
        }
    
        public void showMemory(){
            // Get Memory information
            ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
            manager.getMemoryInfo(memoryInfo);
    			
    		// Get Total Memory , Avail Memory and used Memory
            String totalMemory = Formatter.formatShortFileSize(context, memoryInfo.totalMem);
            String availMemory = Formatter.formatShortFileSize(context, memoryInfo.availMem);
            // 获取已用的内存大小
            String usedMemory= Formatter.formatShortFileSize(context, (memoryInfo.totalMem - memoryInfo.availMem));
            Log.d(TAG, "totalMemory: " + totalMemory + "<==> availMemory==> " + availMemory + "<==> usedMemory " + usedMemory );
     		
     		// 获取当前的可用内存
     		freeMemory = memoryInfo.availMem;
    
            //Assign memory information to the control
            mTotalMemory.setSummary(totalMemory);
            mUsedMemory.setSummary(availMemory);
        }
    
        @Override
        public int getMetricsCategory() {
            return SettingsEnums.PROCESS_STATS_SUMMARY;
        }
    
        @Override
        public int getHelpResource() {
            return 0;
        }
    
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            this.context = context;
        }
    
    	// 清除除设置应用外其他所有后台应用
        public void killAllAppsExceptionSettings(){
            int MAX_TASKS = 100;
            // 获取Activity管理类
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            // 获取用户最近使用过的应用程序信息集合,第一个参数:最大值,第二个参数:ActivityManager.RECENT_IGNORE_UNAVAILABL
            /**
            *	RecentTaskInfo 类,主要的字段
            * 		Intent	baseIntent	得到能跳转这个Task的Activity,即能通过这个Intent启动这个Intent指向的程序。
            *		int		id			得到这个Task的标识,如果是-1,则标识这个程序没有启动,其他数字表示启动了。
           	*		int		persistentId	任务的唯一值
            */
            List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasks(MAX_TASKS,
                    ActivityManager.RECENT_IGNORE_UNAVAILABLE);
            Log.d(TAG, "recentTasks.size = " + recentTasks.size());
            // 进行一个循环遍历,并通过比较,筛选出不需要移除的哪一项,并忽略
            for (ActivityManager.RecentTaskInfo recentInfo : recentTasks) {
                Intent intent = new Intent(recentInfo.baseIntent);
                if (recentInfo.origActivity != null) {
                    intent.setComponent(recentInfo.origActivity);
                }
                if (!intent.getComponent().getClassName().equals("com.android.settings.Settings")){
                    Log.d(TAG, "forceStopPackage ==> " + intent.getComponent().getPackageName() + "  <==  className ==> " + intent.getComponent().getClassName());
                    am.killBackgroundProcesses(intent.getComponent().getPackageName());
                    //RemoveTask.removeTask(mContext, recentInfo.persistentId);
                    try {
                        //	清除最近的任务  Remove a task by id
                        ActivityManager.getService().removeTask(recentInfo.persistentId);
                    } catch (RemoteException e) {
                        Log.w(TAG, "Failed to remove task=" +recentInfo.persistentId);
                    }
                }
            }
        }
    
        @Override
        public boolean onPreferenceClick(Preference preference) {
            Log.d(TAG, "onPreferenceClick: " +  preference.getKey() );
            ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
            manager.getMemoryInfo(memoryInfo);
            // 计算当前的释放的内存
            String nowMemory  = Formatter.formatShortFileSize(context , (freeMemory - memoryInfo.availMem));
            Log.d(TAG,"Last Memory ==> " + nowMemory);
            switch (preference.getKey()){
                case "my_clear_background":
                    //SendBroadcast();
                    killAllAppsExceptionSettings();
                    Toast.makeText(context, "Clear All Apps Success!! Free Memory: " + nowMemory, Toast.LENGTH_SHORT).show();
                    break;
            }
            return false;
        }
    
    }
    
  3. 实现效果

    在Settings中的二级菜单中,点击Clear按钮,实现清除后台所有任务,除Settings外

有关Android需求2 -- MTK手机内存显示和清除后台的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby-on-rails - 使用 Sublime Text 3 突出显示 HTML 背景语法中的 ERB? - 2

    所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择

  5. ruby-on-rails - link_to 不显示任何 rails - 2

    我试图在索引页中创建一个超链接,但它没有显示,也没有给出任何错误。这是我的index.html.erb代码。ListingarticlesTitleTextssss我检查了我的路线,我认为它们也没有问题。PrefixVerbURIPatternController#Actionwelcome_indexGET/welcome/index(.:format)welcome#indexarticlesGET/articles(.:format)articles#indexPOST/articles(.:format)articles#createnew_articleGET/article

  6. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  7. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  8. ruby-on-rails - 复数 for fields_for has_many 关联未显示在 View 中 - 2

    目前,Itembelongs_toCompany和has_manyItemVariants。我正在尝试使用嵌套的fields_for通过Item表单添加ItemVariant字段,但是使用:item_variants不显示该表单。只有当我使用单数时才会显示。我检查了我的关联,它们似乎是正确的,这可能与嵌套在公司下的项目有关,还是我遗漏了其他东西?提前致谢。注意:下面的代码片段中省略了不相关的代码。编辑:不知道这是否相关,但我正在使用CanCan进行身份验证。routes.rbresources:companiesdoresources:itemsenditem.rbclassItemi

  9. 怎样用一台手机做自媒体? - 2

    其实做自媒体的成本并不高,入门只需要一部手机即可!在手机上找视频素材、使用手机剪辑视频、最后使用手机发布视频作品获得收益!方法并不难,今天这期内容就来给粉丝们分享一种小方法,每天稳定收益100-300,抓紧点赞收藏!1、找素材(1)使用手机拍摄自己喜欢的经典段落,使用程序把文案内容提取出来(2)也可以在豆瓣、知乎、微博等网站中找一些自己需要的文案素材(3)把文案进行润色修改,可以加入一些自己的观点(4)视频素材可以使用软件中自带的素材,也可以在素材网站中下载完整版的素材2、文案配音(1)把复制好的文案直接导入小程序中(2)调整音色、音调后一键合成音频即可(3)可以选择自己朗读配音,需要花一点时

  10. ruby-on-rails - 在 Flash 警报 Rails 3 中显示错误消息 - 2

    如果我在模型中设置验证消息validates:name,:presence=>{:message=>'Thenamecantbeblank.'}我如何让该消息显示在闪光警报中,这是我迄今为止尝试过的方法defcreate@message=Message.new(params[:message])if@message.valid?ContactMailer.send_mail(@message).deliverredirect_to(root_path,:notice=>"Thanksforyourmessage,Iwillbeintouchsoon")elseflash[:error]

随机推荐