##Day09##
#9.1获取正在运行的进程的信息#
/**
* 获取正在运行的进程的信息
*/
public static List<TaskInfo> getTaskInfos(Context context){
List<TaskInfo> list = new ArrayList<TaskInfo>();
//进程的管理者
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
PackageManager pm = context.getPackageManager();
//获取正在运行进程信息
List<RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();
for (RunningAppProcessInfo runningAppProcessInfo : runningAppProcesses) {
TaskInfo taskInfo = new TaskInfo();
//获取进程的名称,就是包名
String packagName = runningAppProcessInfo.processName;
taskInfo.setPackagname(packagName);
//获取相应的进程所占用的空间,int[] 你传入几个进程pid就返回几个进程所占用的空间
MemoryInfo[] processMemoryInfo = am.getProcessMemoryInfo(new int[]{runningAppProcessInfo.pid});
//将获取的内存信息转化kb的形式
int totalPss = processMemoryInfo[0].getTotalPss();
//获取进程所占用的内存信息
long ramsize = totalPss*1024;
taskInfo.setRamsize(ramsize);
try {
//获取applicationinfo,根据进程的名称获取相应进程的applicationinfo信息
ApplicationInfo applicationInfo = pm.getApplicationInfo(packagName, 0);
//获取图标
Drawable icon = applicationInfo.loadIcon(pm);
taskInfo.setIcon(icon);
//获取应用的名称
String name = applicationInfo.loadLabel(pm).toString();
taskInfo.setName(name);
//获取application的所有标签
int flags = applicationInfo.flags;
boolean isUser;
//判断是否用户进程
if ((flags & applicationInfo.FLAG_SYSTEM) == applicationInfo.FLAG_SYSTEM) {
//系统进程
isUser = false;
}else{
//用户进程
isUser = true;
}
taskInfo.setUser(isUser);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
//添加到集合中
list.add(taskInfo);
}
return list;
}
#9.2界面布局及bug的处理#
选中checkbox发现,复用的条目也选中,原因:是因为在复用checkbox的时候也把checkbox状态给复用了,所以一般在复用的时候,经常操作的控件的值,我们是不会复用的,一般会将复用的空间的值保存到bean对象中
条目点击事件中进行
1.在bean类中设置保存checkbox的状态的变量
2.在getview中根据保存的值去设置checkbox的状态
//根据bean类中保存的checkbox状态来设置条目的checkbox的状态
if (appInfo.isChecked()) {
viewHolder.cb_itemtaskmanager_ischecked.setChecked(true);
}else{
viewHolder.cb_itemtaskmanager_ischecked.setChecked(false);
}
3.在条目点击事件中进行点击修改操作
lv_taskmanager_process.setOnItemClickListener(new OnItemClickListener() {
//view :条目的view对象
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//1.屏蔽用户程序多少个和系统程序多少个点击事件
if (position == 0 || position == userAppInfos.size()+1) {
return;
}
//2.获取进程信息
//获取条目对应的信息
//判断用户程序是否展示完
if (position <= userAppInfos.size()) {
//获取用户程序
appInfo = userAppInfos.get(position-1);
}else{
//系统程序
appInfo = systemAppInfos.get(position - userAppInfos.size()-2);
}
//3.设置checkbox的状态,保存checkbox的状态
//根据保存的状态来判断,选中就改为不选中,不选中就改为选中
if (appInfo.isChecked()) {
appInfo.setChecked(false);
}else{
appInfo.setChecked(true);
}
//4.更新界面
//第一种方式
//myAdapter.notifyDataSetChanged();
//第二种方式,刷新单个条目
ViewHolder viewHolder = (ViewHolder) view.getTag();
viewHolder.cb_itemtaskmanager_ischecked.setChecked(appInfo.isChecked());
}
});
#9.3全选&反选#
/**
* 全选
*/
public void all(View v){
//设置用户程序的checkbox为true
for (TaskInfo taskinfo : userAppInfos) {
taskinfo.setChecked(true);
}
//系统程序的checkbox为true
for (TaskInfo taskinfo : systemAppInfos) {
taskinfo.setChecked(true);
}
//更新界面
myAdapter.notifyDataSetChanged();
}
/**
* 反选
* @param v
*/
public void cancel(View v){
//用户程序
for (TaskInfo taskInfo : userAppInfos) {
//true改为false,false改为true
taskInfo.setChecked(!taskInfo.isChecked());
}
//系统程序
for (TaskInfo taskInfo : systemAppInfos) {
//true改为false,false改为true
taskInfo.setChecked(!taskInfo.isChecked());
}
//更新界面
myAdapter.notifyDataSetChanged();
}
#9.4清理#
前台进程 : 在通知栏上的都是前台进程,前台杀不死,程序一直在运行
可见进程 : 现在用的进程,这个进程也杀不死
服务进程 : 运行服务的进程,当内存不足的时候杀死服务进程,当内存充足的时候不杀死,当内存不足杀死之后,在内存充足的时候,系统会自动重启服务
后台进程 : 运行在后台进程,杀死
空进程 : 程序退出之后,它的进程就会变成空进程,是为了方便下次启动的时候能快速启动,杀死
优先进程
前台进程 -> 可见进程 -> 服务进程 -> 后台进程 -> 空进程
清理
/**
* 清理
* @param v
*/
public void clear(View v){
//杀死进程
//1.获取进程的管理者
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
//保存被杀死的进程的信息
List<TaskInfo> deletinfos = new ArrayList<TaskInfo>();
//2.杀死用户进程,不能再集合循环的时候,从集合中移出数据
for (TaskInfo taskInfo : userAppInfos) {
//判断进程是否选中,选中杀死,没选中不杀死
if (taskInfo.isChecked()) {
//杀死后台进程
//packageName : 包名
am.killBackgroundProcesses(taskInfo.getPackagname());
deletinfos.add(taskInfo);
}
}
//3.杀死系统进程
for (TaskInfo taskInfo : systemAppInfos) {
//判断进程是否选中,选中杀死,没选中不杀死
if (taskInfo.isChecked()) {
//杀死后台进程
//packageName : 包名
am.killBackgroundProcesses(taskInfo.getPackagname());
deletinfos.add(taskInfo);
}
}
//根据杀死进程集合中的信息,去删除用户进程和系统进程集合中的数据
for (TaskInfo taskInfo : deletinfos) {
if (taskInfo.isUser()) {
userAppInfos.remove(taskInfo);
}else{
systemAppInfos.remove(taskInfo);
}
}
//更新界面
myAdapter.notifyDataSetChanged();
}
权限:<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
#9.5进程的细节处理#
1.在清理操作中,添加提醒用户杀死进程和释放内存的操作
long memory=0;
//根据杀死进程集合中的信息,去删除用户进程和系统进程集合中的数据
for (TaskInfo taskInfo : deletinfos) {
if (taskInfo.isUser()) {
userAppInfos.remove(taskInfo);
}else{
systemAppInfos.remove(taskInfo);
}
memory+=taskInfo.getRamsize();
}
//b -> mb
String size = Formatter.formatFileSize(getApplicationContext(), memory);
Toast.makeText(getApplicationContext(), "共杀死"+deletinfos.size()+"个进程,释放"+size+"内存", 0).show();
//杀死进程做准备
deletinfos.clear();
deletinfos = null;
2.处理不能选中自己的效果
a.在条目点击事件中
if (appInfo.isChecked()) {
appInfo.setChecked(false);
}else{
if (!appInfo.getPackagname().equals(getPackageName())) {
appInfo.setChecked(true);
}
}
b.在全选中进行操作
//设置用户程序的checkbox为true
for (TaskInfo taskinfo : userAppInfos) {
if (!appInfo.getPackagname().equals(getPackageName())) {
taskinfo.setChecked(true);
}
}
c.在反选中操作
//用户程序
for (TaskInfo taskInfo : userAppInfos) {
if (!appInfo.getPackagname().equals(getPackageName())) {
//true改为false,false改为true
taskInfo.setChecked(!taskInfo.isChecked());
}
}
#9.6获取进程个数和内存#
proc -> meminfo(存储的就是内存的信息)
@deprecated : 可以将方法设置成过时的方法
1.创建一个工具类,创建获取进程数和内存的方法
/**
* 获取正在运行的进程的个数
* @return
*/
public static int getAvailableProcess(Context context){
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> processes = am.getRunningAppProcesses();
return processes.size();
}
/**
* 获取空闲的内存信息
* @param context
* @return
*/
public static long getAvaliableRam(Context context){
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
MemoryInfo outInfo = new MemoryInfo();//创建一个白纸
am.getMemoryInfo(outInfo);//将内存的信息写到白纸上
return outInfo.availMem;//空闲内存
// outInfo.totalMem;//总共内存
// return 0;
}
/**
* 获取总的内存信息
* @param context
* @return
* 在高版本中使用的
*/
public static long getTotalRam(Context context){
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
MemoryInfo outInfo = new MemoryInfo();//创建一个白纸
am.getMemoryInfo(outInfo);//将内存的信息写到白纸上
// return outInfo.availMem;//空闲内存
return outInfo.totalMem;//总共内存,高版本中有的字段,在低版本中不能使用
// return 0;
}
/**
* 获取总的内存信息
* @param context
* @return
* 在低版本中使用的
* @deprecated
*/
public static long getTotalRam(){
StringBuilder sb = new StringBuilder();
File file = new File("/proc/meminfo");
try {
BufferedReader br = new BufferedReader(new FileReader(file));
//读取出一行信息
String readLine = br.readLine();
//解析出数字
//转化成字符数组
char[] charArray = readLine.toCharArray();
//拿出string类型中的所有数字
for (char c : charArray) {
//判断字符数组中的元素是否数字
if (c >='0' && c<='9') {
//添加组合
sb.append(c);
}
}
String string = sb.toString();//数字
//转化成int
long parseInt = Integer.parseInt(string);
return parseInt*1024;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
2.使用,着重掌握根据sdk执行不同方法操作
//获取进程个数
int availableProcess = ProcessUtils.getAvailableProcess(getApplicationContext());
tv_taskmanager_process_count.setText("运行中进程:"+availableProcess+"个");
//获取空闲内存和总内存
long avaliableRam = ProcessUtils.getAvaliableRam(getApplicationContext());
//转成成字符串
String freesize = Formatter.formatFileSize(getApplicationContext(), avaliableRam);
//获取总内存
//获取sdk的版本
int sdk = android.os.Build.VERSION.SDK_INT;
//根据sdk的版本执行相应的方法,来避免程序出错
long totalRam;
if (sdk >= 16) {
totalRam = ProcessUtils.getTotalRam(getApplicationContext());
}else{
totalRam = ProcessUtils.getTotalRam();
}
//转化成字符串
String totalsize = Formatter.formatFileSize(getApplicationContext(), totalRam);
tv_taskmanager_ramortotal.setText("剩余/总内存:"+freesize+"/"+totalsize);
#9.7清理进程的细节处理#
原因:程序运行就需要内存,程序退出内存会释放的,但是android系统为了快速启动应用,不会完成释放,当我们再次打开的时候,会获取内存,这时候就会把原来的内存加上去,
细节的处理
//修改显示的进程数
availableProcess = availableProcess - deletinfos.size();
tv_taskmanager_process_count.setText("运行中进程:"+availableProcess);
memory = avaliableRam+memory;
//转化成字符串
String formatFileSize = Formatter.formatFileSize(getApplicationContext(), memory);
//空闲空间处理
tv_taskmanager_ramortotal.setText("剩余/总内存:"+formatFileSize+"/"+totalsize);