Android项目实战--手机卫士28--读取进程的信息并显示出来

2024-06-09 15:48

本文主要是介绍Android项目实战--手机卫士28--读取进程的信息并显示出来,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!



最新实战教程,让你了解Android自动化刷量、作弊与防作弊的那些事,案例:刷友盟统计、批量注册苹果帐号




今天呢,我们就继续我们的进程管理啦,昨天我们就讲到了拿到进程数目,以及可用的内存,那么今天,我们就把那些进程一个个的显示出来,

但在做今天这个之前,我先给大家提个醒,我觉得那个程序锁的界面有点不好看,所以就修改了一下,大家到时可以看看源码,我们就先把今天要做的,和那个程序锁的给大家看看先吧

     

大家可以看到,我们这个界面也是挺简单的,有一个标签把系统的进程和用户的进程给区分开来,所以我们到时在显示在listview的时候就要小心处理了,


首先,我们要先新建一个model类,用来存放那些进程的信息

com.xiaobin.security.domain.TaskInfo

package com.xiaobin.security.domain;import android.graphics.drawable.Drawable;public class TaskInfo
{private String name;private Drawable icon;private int id;//以KB作为单位private int memory;private boolean isCheck;private String packageName;//是否为系统进程private boolean isSystemProcess;public String getName(){return name;}public void setName(String name){this.name = name;}public Drawable getIcon(){return icon;}public void setIcon(Drawable icon){this.icon = icon;}public int getId(){return id;}public void setId(int id){this.id = id;}public boolean isCheck(){return isCheck;}public void setCheck(boolean isCheck){this.isCheck = isCheck;}public String getPackageName(){return packageName;}public void setPackageName(String packageName){this.packageName = packageName;}public int getMemory(){return memory;}public void setMemory(int memory){this.memory = memory;}public boolean isSystemProcess(){return isSystemProcess;}public void setSystemProcess(boolean isSystemProcess){this.isSystemProcess = isSystemProcess;}}

好啦,写完model类之后,我们就要写一个类来读取我们的进程信息啦

com.xiaobin.security.engine.TaskInfoProvider

package com.xiaobin.security.engine;import java.util.ArrayList;
import java.util.List;import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Debug.MemoryInfo;import com.xiaobin.security.domain.TaskInfo;public class TaskInfoProvider
{private PackageManager packageManager;private ActivityManager activityManager;public TaskInfoProvider(Context context){packageManager = context.getPackageManager();activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);}public List<TaskInfo> getAllTask(List<RunningAppProcessInfo> runningAppProcessInfos){List<TaskInfo> taskInfos = new ArrayList<TaskInfo>();for (RunningAppProcessInfo runningAppProcessInfo : runningAppProcessInfos){TaskInfo taskInfo = new TaskInfo();int id = runningAppProcessInfo.pid;taskInfo.setId(id);String packageName = runningAppProcessInfo.processName;taskInfo.setPackageName(packageName);try{// ApplicationInfo是AndroidMainfest文件里面整个Application节点的封装ApplicationInfo applicationInfo = packageManager.getPackageInfo(packageName, 0).applicationInfo;// 应用的图标Drawable icon = applicationInfo.loadIcon(packageManager);taskInfo.setIcon(icon);// 应用的名字String name = applicationInfo.loadLabel(packageManager).toString();taskInfo.setName(name);//设置是否为系统应用taskInfo.setSystemProcess(!filterApp(applicationInfo));// 可以返回一个内存信息的数组,传进去的id有多少个,就返回多少个对应id的内存信息MemoryInfo[] memoryInfos = activityManager.getProcessMemoryInfo(new int[] { id });// 拿到占用的内存空间int memory = memoryInfos[0].getTotalPrivateDirty();taskInfo.setMemory(memory);taskInfos.add(taskInfo);taskInfo = null;}catch (Exception e){e.printStackTrace();}}return taskInfos;}// 判断某一个应用程序是不是用户的应用程序,如果是返回true,否则返回falsepublic boolean filterApp(ApplicationInfo info){// 有些系统应用是可以更新的,如果用户自己下载了一个系统的应用来更新了原来的,// 它就不是系统应用啦,这个就是判断这种情况的if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0){return true;}else if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0)// 判断是不是系统应用{return true;}return false;}}

读取进程的信息,其实也很简单的,我们上一次已经拿到了RunningAppProcessInfo的集合啦,那么我们只要遍历这个集合,那就可以拿到这些进程啦,

那么,我们就可以读取到它们的processName字段啦,其实这个字段就是这个应用的包名啦,那么, 拿到了包名之后,我们就可以拿到很多信息的啦。

如上面写到的,通过PackageManager来拿到一个applicationInfo,拿到这个对象也好办啦,什么应用名字啦,图标啦,都可以拿到啦,这些我们之前在程序锁啊,应用管理这些都写过啦,上面也再写了一次,当复习啦。

接下来,我们就要读取这个进程占用的内存啦,其实这个操作也很简单啦,就是通过ActivityManager对象来调用它里面的方法getProcessMemoryInfo,通过传递

一个id的数组进去,就可以拿到,对应id数组里面的占用内存信息啦,所以还是挺简单的。


大家还会看到,我们上面有个方法,就是判断是不是系统应用的,其实这个方法,我们之前在应用管理那里也有写过的,但是我当时没怎么说,造成了不少人的误解,那我今天就和大家说一下吧

我们拿到的ApplicationInfo对象里面有个flags,就是标记我们应用的类别的,如FLAG_SYSTEM就是一个系统应用啦,FLAG_UPDATED_SYSTEM_APP就是一个可升级的系统应用啦,但如果用户把它升级了,那么,就应该把它当成是用户的应用的啦,所以我们上面就返回true啦


好啦,写完这个读取进程信息的类之后,我们就要回到我们的界面,显示出来的啦

因为我们读取这些信息都是很久的,所以我们就和程序锁啊,应用管理这些一样,用一个线程来加载这些东西,并显示一个进度条

	private void initData(){//因为这个title是要显示当前进程数目和可用内存的,所以我们每次在这里都调用一下,以更新数据initTitle();ll_process_load.setVisibility(View.VISIBLE);new Thread(new Runnable(){@Overridepublic void run(){taskInfoProvider = new TaskInfoProvider(ProcessManagerActivity.this);taskInfos = taskInfoProvider.getAllTask(runningAppProcessInfos);Message msg = new Message();msg.what = LOAD_FINISH;handler.sendMessage(msg);}}).start();}

完成加载之后,就会发送一个消息给handler,然后就进来显示的操作的

	private Handler handler = new Handler(){public void handleMessage(Message msg) {switch(msg.what){case LOAD_FINISH : ll_process_load.setVisibility(View.INVISIBLE);adapter = new TaskInfoAdapter();lv_process_list.setAdapter(adapter);break;default : break;}}};

那么,接下来,我们就是要进行我们最麻烦的那个操作啦,就是listview的操作啦,也就是adapter的编写啦

因为我们要区分系统进程和用户进程嘛,还要加两个标签,所以那就处理起来有点麻烦的啦

首先,我们要区分系统进程,和用户进程,那么我们就用两个list来分别存放它们,在adapter的构造方法里面,对它们进行初始化

		public TaskInfoAdapter(){//存放用户的应用进程userTaskInfo = new ArrayList<TaskInfo>();//存放系统的应用进程systemTaskInfo = new ArrayList<TaskInfo>();for(TaskInfo taskInfo : taskInfos){if(taskInfo.isSystemProcess()){systemTaskInfo.add(taskInfo);}else{userTaskInfo.add(taskInfo);}}}

因为我们要加两个标签来显示是用户进程还是系统进程嘛(也就是两个TextView),所以返回的条目就要加2啦

		@Overridepublic int getCount(){//加上两个标签,一个是系统标签,一个是用户标签return taskInfos.size() + 2;}

因为多了两个条目,所以返回值也要特别处理一下啦

		@Overridepublic Object getItem(int position){if(position == 0){return 0;	//显示成用户应用的标签}else if(position <= userTaskInfo.size()){return userTaskInfo.get(position - 1);	//用户应用进程的条目}else if(position == userTaskInfo.size() + 1){return position;	//显示成系统进程的标签}else if(position <= taskInfos.size() + 2){//系统应用进程的条目return systemTaskInfo.get(position - userTaskInfo.size() - 2);}else{return position;}}

最后,就是我们的getView方法啦,这个是非常的重要的,关系到我们的显示

		@Overridepublic View getView(int position, View convertView, ViewGroup parent){View view;TaskInfoViews views;TaskInfo taskInfo;if(position == 0){//显示成用户应用的标签return newTextView("用户进程(" + userTaskInfo.size() + ")");	}else if(position <= userTaskInfo.size()){//用户应用进程的条目taskInfo = userTaskInfo.get(position - 1);}else if(position == userTaskInfo.size() + 1){//显示成系统进程的标签return newTextView("系统进程(" +  systemTaskInfo.size() + ")");	}else if(position <= taskInfos.size() + 2){//系统应用进程的条目taskInfo = systemTaskInfo.get(position - userTaskInfo.size() - 2);}else{taskInfo = new TaskInfo();}if(convertView == null || convertView instanceof TextView){view = View.inflate(ProcessManagerActivity.this, R.layout.process_manager_item, null);views = new TaskInfoViews();views.iv_process_icon = (ImageView) view.findViewById(R.id.iv_process_manager_icon);views.tv_process_name = (TextView) view.findViewById(R.id.tv_process_manager_name);views.tv_process_memory = (TextView) view.findViewById(R.id.tv_process_manager_memory);views.cb_process_state = (CheckBox) view.findViewById(R.id.cb_process_manager_state);view.setTag(views);}else{view = convertView;views = (TaskInfoViews) view.getTag();}views.iv_process_icon.setImageDrawable(taskInfo.getIcon());views.tv_process_name.setText(taskInfo.getName());views.tv_process_memory.setText("占用内存:" + TextFormater.getSizeFromKB(taskInfo.getMemory()));views.cb_process_state.setChecked(taskInfo.isCheck());return view;}

在里面,我们用到一个生成TextView的方法

		private TextView newTextView(String title){TextView tv_title = new TextView(ProcessManagerActivity.this);tv_title.setText(title);return tv_title;}

好啦,这个adapter比较复杂,不像我们之前写的那样,直接显示就行啦,这次,多了很多判断,但实际开发中,这种情况是很常见的,所以大家最好懂得这样来定义自己复杂的adapter,不然就会很麻烦的了

如果对上面代码有什么不明白的,可以说出来


好啦,写到这里,我们的逻辑就基本上完成的啦,下面把activity的完整类和布局文件粘出来

process_manager.item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="65dip"android:background="@drawable/item_background_selector"><ImageView android:id="@+id/iv_process_manager_icon"android:layout_width="60dip"android:layout_height="60dip"android:layout_alignParentLeft="true"android:scaleType="fitXY"android:src="@drawable/app"android:contentDescription="@string/hello_world"/><LinearLayout android:layout_width="wrap_content"android:layout_height="65dip"android:layout_toRightOf="@id/iv_process_manager_icon"android:layout_marginLeft="10dip"android:gravity="center_vertical"android:orientation="vertical"><TextView android:id="@+id/tv_process_manager_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="18sp"android:textColor="#ff000000"android:text="@string/hello_world"/><TextView android:id="@+id/tv_process_manager_memory"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="16sp"android:textColor="#ff000000"android:text="@string/hello_world"/></LinearLayout><CheckBox android:id="@+id/cb_process_manager_state"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_marginRight="10dip"/></RelativeLayout>


com.xiaobin.security.ui.ProcessManagerActivity

package com.xiaobin.security.ui;import java.util.ArrayList;
import java.util.List;import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;import com.xiaobin.security.R;
import com.xiaobin.security.domain.TaskInfo;
import com.xiaobin.security.engine.TaskInfoProvider;
import com.xiaobin.security.utils.TextFormater;public class ProcessManagerActivity extends Activity implements OnClickListener
{private static final int LOAD_FINISH = 1;private TextView tv_process_count;private TextView tv_process_memory;private LinearLayout ll_process_load;private ListView lv_process_list;private Button bt_process_clear;private Button bt_process_setting;private ActivityManager activityManager;private List<RunningAppProcessInfo> runningAppProcessInfos;private TaskInfoProvider taskInfoProvider;private List<TaskInfo> taskInfos;private TaskInfoAdapter adapter;@SuppressLint("HandlerLeak")private Handler handler = new Handler(){public void handleMessage(Message msg){switch (msg.what){case LOAD_FINISH:ll_process_load.setVisibility(View.INVISIBLE);adapter = new TaskInfoAdapter();lv_process_list.setAdapter(adapter);break;default:break;}}};@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);// 请求一个自己定义的title,但有一些Android系统是被修改过的,// 所以有可能是无法请求的,如乐Phone或小米的手机,这些系统是被修改过的,// 所以就要判断一下是否请求成功boolean flags = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);setContentView(R.layout.process_manager);if (flags){// 设置自定义的titlegetWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.process_manager_title);}tv_process_count = (TextView) findViewById(R.id.tv_process_count);tv_process_memory = (TextView) findViewById(R.id.tv_process_memory);ll_process_load = (LinearLayout) findViewById(R.id.ll_process_load);lv_process_list = (ListView) findViewById(R.id.lv_process_list);bt_process_clear = (Button) findViewById(R.id.bt_process_clear);bt_process_setting = (Button) findViewById(R.id.bt_process_setting);bt_process_clear.setOnClickListener(this);bt_process_setting.setOnClickListener(this);initData();}@Overridepublic void onClick(View v){switch (v.getId()){case R.id.bt_process_clear:break;case R.id.bt_process_setting:break;default:break;}}private void initData(){// 因为这个title是要显示当前进程数目和可用内存的,所以我们每次在这里都调用一下,以更新数据initTitle();ll_process_load.setVisibility(View.VISIBLE);new Thread(new Runnable(){@Overridepublic void run(){taskInfoProvider = new TaskInfoProvider(ProcessManagerActivity.this);taskInfos = taskInfoProvider.getAllTask(runningAppProcessInfos);Message msg = new Message();msg.what = LOAD_FINISH;handler.sendMessage(msg);}}).start();}// 拿到当前运行的进程数目private int getRunningAppCount(){runningAppProcessInfos = activityManager.getRunningAppProcesses();return runningAppProcessInfos.size();}// 拿到系统剩余的内存private String getAvailMemory(){// new一个内存的对象MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();// 拿到现在系统里面的内存信息activityManager.getMemoryInfo(memoryInfo);// 拿到有效的内存空间long size = memoryInfo.availMem;return TextFormater.dataSizeFormat(size);}// 设置title的信息private void initTitle(){tv_process_count.setText("进程数目:" + getRunningAppCount());tv_process_memory.setText("剩余内存:" + getAvailMemory());}// ===========================================================================private class TaskInfoAdapter extends BaseAdapter{private List<TaskInfo> userTaskInfo;private List<TaskInfo> systemTaskInfo;public TaskInfoAdapter(){// 存放用户的应用进程userTaskInfo = new ArrayList<TaskInfo>();// 存放系统的应用进程systemTaskInfo = new ArrayList<TaskInfo>();for (TaskInfo taskInfo : taskInfos){if (taskInfo.isSystemProcess()){systemTaskInfo.add(taskInfo);}else{userTaskInfo.add(taskInfo);}}}@Overridepublic int getCount(){// 加上两个标签,一个是系统标签,一个是用户标签return taskInfos.size() + 2;}@Overridepublic Object getItem(int position){if (position == 0){return 0; // 显示成用户应用的标签}else if (position <= userTaskInfo.size()){return userTaskInfo.get(position - 1); // 用户应用进程的条目}else if (position == userTaskInfo.size() + 1){return position; // 显示成系统进程的标签}else if (position <= taskInfos.size() + 2){// 系统应用进程的条目return systemTaskInfo.get(position - userTaskInfo.size() - 2);}else{return position;}}@Overridepublic long getItemId(int position){return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent){View view;TaskInfoViews views;TaskInfo taskInfo;if (position == 0){// 显示成用户应用的标签return newTextView("用户进程(" + userTaskInfo.size() + ")");}else if (position <= userTaskInfo.size()){// 用户应用进程的条目taskInfo = userTaskInfo.get(position - 1);}else if (position == userTaskInfo.size() + 1){// 显示成系统进程的标签return newTextView("系统进程(" + systemTaskInfo.size() + ")");}else if (position <= taskInfos.size() + 2){// 系统应用进程的条目taskInfo = systemTaskInfo.get(position - userTaskInfo.size()- 2);}else{taskInfo = new TaskInfo();}if (convertView == null || convertView instanceof TextView){view = View.inflate(ProcessManagerActivity.this,R.layout.process_manager_item, null);views = new TaskInfoViews();views.iv_process_icon = (ImageView) view.findViewById(R.id.iv_process_manager_icon);views.tv_process_name = (TextView) view.findViewById(R.id.tv_process_manager_name);views.tv_process_memory = (TextView) view.findViewById(R.id.tv_process_manager_memory);views.cb_process_state = (CheckBox) view.findViewById(R.id.cb_process_manager_state);view.setTag(views);}else{view = convertView;views = (TaskInfoViews) view.getTag();}views.iv_process_icon.setImageDrawable(taskInfo.getIcon());views.tv_process_name.setText(taskInfo.getName());views.tv_process_memory.setText("占用内存:"+ TextFormater.getSizeFromKB(taskInfo.getMemory()));views.cb_process_state.setChecked(taskInfo.isCheck());return view;}private TextView newTextView(String title){TextView tv_title = new TextView(ProcessManagerActivity.this);tv_title.setText(title);return tv_title;}}private class TaskInfoViews{ImageView iv_process_icon;TextView tv_process_name;TextView tv_process_memory;CheckBox cb_process_state;}}


好啦,今天就讲到这里啦,有什么不明白的,可以留言


最后,和大家说一下

为了方便大家的交流,我创建了一个群,这样子大家有什么疑问也可以在群上交流

群号是298440981



今天源码下载



这篇关于Android项目实战--手机卫士28--读取进程的信息并显示出来的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1045609

相关文章

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

MyBatis分页查询实战案例完整流程

《MyBatis分页查询实战案例完整流程》MyBatis是一个强大的Java持久层框架,支持自定义SQL和高级映射,本案例以员工工资信息管理为例,详细讲解如何在IDEA中使用MyBatis结合Page... 目录1. MyBATis框架简介2. 分页查询原理与应用场景2.1 分页查询的基本原理2.1.1 分

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

sky-take-out项目中Redis的使用示例详解

《sky-take-out项目中Redis的使用示例详解》SpringCache是Spring的缓存抽象层,通过注解简化缓存管理,支持Redis等提供者,适用于方法结果缓存、更新和删除操作,但无法实现... 目录Spring Cache主要特性核心注解1.@Cacheable2.@CachePut3.@Ca

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模