1.获取内存信息
(1)返回进程的总个数, 返回获取到剩余内存,返回获取到总内存
<span style="font-size:14px;"> /**
* 返回进程的总个数
*
* @param context
* @return
*/
public static int getProcessCount(Context context) {
// 得到进程管理者
ActivityManager activityManager = (ActivityManager) context
.getSystemService(context.ACTIVITY_SERVICE);
// 获取到当前手机上面所有运行的进程
List<RunningAppProcessInfo> runningAppProcesses = activityManager
.getRunningAppProcesses();
// 获取手机上面一共有多少个进程
return runningAppProcesses.size();
}
public static long getAvailMem(Context context) {
// 得到进程管理者
ActivityManager activityManager = (ActivityManager) context
.getSystemService(context.ACTIVITY_SERVICE);
MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
// 获取到内存的基本信息
activityManager.getMemoryInfo(memoryInfo);
// 获取到剩余内存
return memoryInfo.availMem;
}
public static long getTotalMem(Context context) {
// 获取到总内存
/*
* 这个地方不能直接跑到低版本的手机上面 MemTotal: 344740 kB "/proc/meminfo"
*/
try {
// /proc/meminfo 配置文件的路径
FileInputStream fis = new FileInputStream(new File("/proc/meminfo"));
BufferedReader reader = new BufferedReader(new InputStreamReader(
fis));
String readLine = reader.readLine();
StringBuffer sb = new StringBuffer();
for (char c : readLine.toCharArray()) {
if (c >= '0' && c <= '9') {
sb.append(c);
}
}
return Long.parseLong(sb.toString()) * 1024;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return 0;
}
</span>
<span style="font-size:14px;">tv_task_memory.setText("剩余/总内存:"
+ Formatter.formatFileSize(TaskManagerActivity.this, info.getAvailMem(this))
+ "/"
+ Formatter.formatFileSize(TaskManagerActivity.this, info.getTotalMem(this)));</span>
2. 获取手机正在运行的进程信息
(1)进程信息的业务bean<span style="font-size:14px;">public class TaskInfo {
private Drawable icon;
private String packageName;
private String appName;
private long memorySize;
/**
* 是否是用户进程
*/
private boolean userApp;
/**
* 判断当前的item的条目是否被勾选上
*/
private boolean checked;
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public Drawable getIcon() {
return icon;
}
public void setIcon(Drawable icon) {
this.icon = icon;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public long getMemorySize() {
return memorySize;
}
public void setMemorySize(long memorySize) {
this.memorySize = memorySize;
}
public boolean isUserApp() {
return userApp;
}
public void setUserApp(boolean userApp) {
this.userApp = userApp;
}
@Override
public String toString() {
return "TaskInfo [packageName=" + packageName + ", appName=" + appName
+ ", memorySize=" + memorySize + ", userApp=" + userApp + "]";
}
}</span>
(2)获取进程信息
<span style="font-size:14px;">public class TaskInfoParser {
public static List<TaskInfo> getTaskInfos(Context context) {
PackageManager packageManager = context.getPackageManager();
List<TaskInfo> TaskInfos = new ArrayList<TaskInfo>();
// 获取到进程管理器
ActivityManager activityManager = (ActivityManager) context
.getSystemService(context.ACTIVITY_SERVICE);
// 获取到手机上面所有运行的进程
List<RunningAppProcessInfo> appProcesses = activityManager
.getRunningAppProcesses();
for (RunningAppProcessInfo runningAppProcessInfo : appProcesses) {
TaskInfo taskInfo = new TaskInfo();
// 获取到进程的名字
String processName = runningAppProcessInfo.processName;
taskInfo.setPackageName(processName);
try {
// 获取到内存基本信息
/**
* 这个里面一共只有一个数据
*/
android.os.Debug.MemoryInfo[] memoryInfo = activityManager
.getProcessMemoryInfo(new int[]{runningAppProcessInfo.pid});
// Dirty弄脏
// 获取到总共弄脏多少内存(当前应用程序占用多少内存)
int totalPrivateDirty = memoryInfo[0].getTotalPrivateDirty() * 1024;
// System.out.println("==========="+totalPrivateDirty);
taskInfo.setMemorySize(totalPrivateDirty);
PackageInfo packageInfo = packageManager.getPackageInfo(
processName, 0);
// /获取到图片
Drawable icon = packageInfo.applicationInfo
.loadIcon(packageManager);
taskInfo.setIcon(icon);
// 获取到应用的名字
String appName = packageInfo.applicationInfo.loadLabel(
packageManager).toString();
taskInfo.setAppName(appName);
System.out.println("-------------------");
System.out.println("processName="+processName);
System.out.println("appName="+appName);
//获取到当前应用程序的标记
//packageInfo.applicationInfo.flags 我们写的答案
//ApplicationInfo.FLAG_SYSTEM表示老师的该卷器
int flags = packageInfo.applicationInfo.flags;
//ApplicationInfo.FLAG_SYSTEM 表示系统应用程序
if((flags & ApplicationInfo.FLAG_SYSTEM) != 0 ){
//系统应用
taskInfo.setUserApp(false);
}else{
// /用户应用
taskInfo.setUserApp(true);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
// 系统核心库里面有些系统没有图标。必须给一个默认的图标
taskInfo.setAppName(processName);
taskInfo.setIcon(context.getResources().getDrawable(
R.drawable.ic_launcher));
}
TaskInfos.add(taskInfo);
}
return TaskInfos;
}
}</span>
3.带checkbox的listview
(1)不要用checkbox本身记录自己的选择状态,复用缓存时重复,要用业务bean中变量记录,每一个数据都带这个变量
(2)checkbox本身就会有点击事件,会抢走item点击事件的焦点,解决如下:
android:focusable="false" <span style="font-family: Arial, Helvetica, sans-serif;"> android:clickable="false"</span>
(3)总代码
public class TaskManagerActivity extends Activity {
private static final String Tag = "TaskManagerActivity";
private TextView tv_task_process_count;
private TextView tv_task_memory;
private SystemInfoUtils info;
private LinearLayout ll_loading;
private ListView lv_appmanger;
private TextView tv_appsize_lable;
/*
* 总数据
*/
private List<TaskInfo> alltaskInfos;
/*
* 用户进程
*/
private List<TaskInfo> userTaskInfos;
/*
* 系统进程
*/
private List<TaskInfo> systemAppInfos;
private TaskManagerAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_task_manager);
tv_task_process_count = (TextView) findViewById(R.id.tv_task_process_count);
tv_task_memory = (TextView) findViewById(R.id.tv_task_memory);
ll_loading = (LinearLayout) findViewById(R.id.ll_loading);
lv_appmanger = (ListView) findViewById(R.id.lv_appmanger);
tv_appsize_lable = (TextView) findViewById(R.id.tv_appsize_lable);
info = new SystemInfoUtils();
/*
* 进程数量,内存大小
*/
new Thread() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
tv_task_process_count
.setText("运行中进程:"
+ info.getProcessCount(TaskManagerActivity.this)
+ "个");
tv_task_memory
.setText("剩余/总内存:"
+ Formatter.formatFileSize(
TaskManagerActivity.this,
info.getAvailMem(TaskManagerActivity.this))
+ "/"
+ Formatter.formatFileSize(
TaskManagerActivity.this,
info.getTotalMem(TaskManagerActivity.this)));
}
});
}
}.start();
initData();//填充数据
/*
* ListView点击事件
*/
lv_appmanger.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
System.out.println(position);
TaskInfo taskInfo;
if (position == 0) {
return;
} else if (position == (userTaskInfos.size() + 1)) {
return ;
}else if (position < (userTaskInfos.size() + 1)) {
taskInfo = userTaskInfos.get(position - 1);// 多了一个textview的标签 ,
// 位置需要-1
} else {
// 系统程序
int location = position - 1 - userTaskInfos.size() - 1;
taskInfo = systemAppInfos.get(location);
}
ViewHolder holder = (ViewHolder) view.getTag();
if(taskInfo.isChecked()){
taskInfo.setChecked(false);
holder.tv_app_status.setChecked(false);
}else{
taskInfo.setChecked(true);
holder.tv_app_status.setChecked(true);
}
}
});
}
//---------------------------------------------------------------------------------------------------------
/*
* 用户进程,系统进程分类
* 填充数据
*/
private void initData() {
new Thread() {
public void run() {
ll_loading.setVisibility(View.VISIBLE);
alltaskInfos = TaskInfoParser
.getTaskInfos(TaskManagerActivity.this);
userTaskInfos = new ArrayList<TaskInfo>();
systemAppInfos = new ArrayList<TaskInfo>();
for (TaskInfo taskInfo : alltaskInfos) {
if (taskInfo.isUserApp()) {
userTaskInfos.add(taskInfo);
} else {
systemAppInfos.add(taskInfo);
}
}
runOnUiThread(new Runnable() {
@Override
public void run() {
ll_loading.setVisibility(View.INVISIBLE);
adapter = new TaskManagerAdapter();
lv_appmanger.setAdapter(adapter);
}
});
};
}.start();
}
//-------------------------------------------------------------------------------------------------------------
private class TaskManagerAdapter extends BaseAdapter {
@Override
public int getCount() {
// TODO Auto-generated method stub
return alltaskInfos.size()+2;
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup arg2) {
if (position == 0) {
// 第0个位置显示的应该是 用户程序的个数的标签。
TextView tv = new TextView(getApplicationContext());
tv.setBackgroundColor(Color.GRAY);
tv.setTextColor(Color.WHITE);
tv.setText("用户程序:" + userTaskInfos.size() + "个");
return tv;
} else if (position == (userTaskInfos.size() + 1)) {
TextView tv = new TextView(getApplicationContext());
tv.setBackgroundColor(Color.GRAY);
tv.setTextColor(Color.WHITE);
tv.setText("系统程序:" + systemAppInfos.size() + "个");
return tv;
}
ViewHolder holder;
View view;
if (convertView != null && convertView instanceof LinearLayout) {
view = convertView;
holder = (ViewHolder) view.getTag();
} else {
view = View.inflate(TaskManagerActivity.this,
R.layout.item_task_manager, null);
holder = new ViewHolder();
holder.iv_app_icon = (ImageView) view
.findViewById(R.id.iv_app_icon);
holder.tv_app_name = (TextView) view
.findViewById(R.id.tv_app_name);
holder.tv_app_memory_size = (TextView) view
.findViewById(R.id.tv1);
holder.tv_app_status = (CheckBox) view
.findViewById(R.id.tv2);
view.setTag(holder);
}
TaskInfo taskInfo;
if (position < (userTaskInfos.size() + 1)) {
// 用户程序
taskInfo = userTaskInfos.get(position - 1);// 多了一个textview的标签 ,
// 位置需要-1
} else {
// 系统程序
int location = position - 1 - userTaskInfos.size() - 1;
taskInfo = systemAppInfos.get(location);
}
// 这个是设置图片控件的大小
// holder.iv_app_icon.setBackgroundDrawable(d)
// 设置图片本身的大小
holder.iv_app_icon.setImageDrawable(taskInfo.getIcon());
holder.tv_app_name.setText(taskInfo.getAppName());
holder.tv_app_memory_size.setText("内存占用:"
+ Formatter.formatFileSize(TaskManagerActivity.this,
taskInfo.getMemorySize()));
if (taskInfo.isChecked()) {
holder.tv_app_status.setChecked(true);
} else {
holder.tv_app_status.setChecked(false);
}
//判断当前展示的item是否是自己的程序。如果是。就把程序给隐藏
if(taskInfo.getPackageName().equals(getPackageName())){
//隐藏
holder.tv_app_status.setVisibility(View.INVISIBLE);
}else{
//显示
holder.tv_app_status.setVisibility(View.VISIBLE);
}
return view;
}
}
static class ViewHolder {
ImageView iv_app_icon;
TextView tv_app_name;
TextView tv_app_memory_size;
CheckBox tv_app_status;
}
}
4.进程管理器的实现
(1)杀死进程需要权限
KILL_Black......
(2)代码:
/**
* 清理进程
*
* @param view
*/
public void killProcess(View view) {
// 想杀死进程。首先必须得到进程管理器
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
// 清理进程的集合
List<TaskInfo> killLists = new ArrayList<TaskInfo>();
// 清理的总共的进程个数
int totalCount = 0;
// 清理的进程的大小
int killMem = 0;
for (TaskInfo taskInfo : userTaskInfos) {
if (taskInfo.isChecked()) {
killLists.add(taskInfo);
// userTaskInfos.remove(taskInfo);
totalCount++;
killMem += taskInfo.getMemorySize();
}
}
for (TaskInfo taskInfo : systemAppInfos) {
if (taskInfo.isChecked()) {
killLists.add(taskInfo);
// systemAppInfos.remove(taskInfo);
totalCount++;
killMem += taskInfo.getMemorySize();
// 杀死进程 参数表示包名
activityManager.killBackgroundProcesses(taskInfo
.getPackageName());
}
}
/**
* 注意: 当集合在迭代的时候。不能修改集合的大小
* 移除数据
*/
for (TaskInfo taskInfo : killLists) {
// 判断是否是用户app
if (taskInfo.isUserApp()) {
userTaskInfos.remove(taskInfo);
// 杀死进程 参数表示包名
activityManager.killBackgroundProcesses(taskInfo
.getPackageName());
} else {
systemAppInfos.remove(taskInfo);
// 杀死进程 参数表示包名
activityManager.killBackgroundProcesses(taskInfo
.getPackageName());
}
}
// 刷新界面
adapter.notifyDataSetChanged();
}
5.锁屏清理进程和定时清理进程
(1)锁屏广播接收者不能在清单文件中注册,只能代码注册--------------------:锁屏杀死进程
public class KillProcessService extends Service {
private LockScreenReceiver receiver;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private class LockScreenReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//获取到进程管理器
ActivityManager activityManager = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
//获取到手机上面所以正在运行的进程
List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
for (RunningAppProcessInfo runningAppProcessInfo : appProcesses) {
activityManager.killBackgroundProcesses(runningAppProcessInfo.processName);
}
}
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
receiver = new LockScreenReceiver();
//锁屏的过滤器
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
//注册一个锁屏的广播
registerReceiver(receiver, filter);
// Timer timer = new Timer();
//
// TimerTask task = new TimerTask() {
//
// @Override
// public void run() {
// // 写我们的业务逻辑
// System.out.println("我被调用了");
// }
// };
// //进行定时调度
// /**
// * 第一个参数 表示用那个类进行调度
// *
// * 第二个参数表示时间
// */
// timer.schedule(task, 0,1000);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
//当应用程序推出的时候。需要把广播反注册掉
unregisterReceiver(receiver);
//手动回收
receiver = null;
}
}
开启服务
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
if(SystemInfoUtils.isServiceRunning(TaskManagerSettingActivity.this, "com.itheima.mobileguard.services.KillProcessService")){
cb_status_kill_process.setChecked(true);
}else{
cb_status_kill_process.setChecked(false);
}
}
6.widget小控件
(1)布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/widget_bg_portrait"
android:gravity="center_vertical" >
<LinearLayout
android:layout_width="0.0dip"
android:layout_height="fill_parent"
android:layout_marginLeft="5.0dip"
android:layout_weight="1.0"
android:background="@drawable/widget_bg_portrait_child"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingBottom="3.0dip"
android:paddingTop="3.0dip" >
<TextView
android:id="@+id/process_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10.0dip"
android:textAppearance="@style/widget_text" />
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="1.0dip"
android:layout_marginTop="1.0dip"
android:background="@drawable/widget_bg_portrait_child_divider" />
<TextView
android:id="@+id/process_memory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10.0dip"
android:textAppearance="@style/widget_text" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical" >
<ImageView
android:layout_width="20.0dip"
android:layout_height="20.0dip"
android:src="@drawable/main_icon" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textColor="#ffffffff" />
</LinearLayout>
<Button
android:id="@+id/btn_clear"
android:layout_width="90.0dip"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginTop="5.0dip"
android:background="@drawable/function_greenbutton_selector"
android:text="一键清理"
/>
</LinearLayout>
</LinearLayout>
(2)创建类继承AppWidgetProvider,放在receiver包下
--------------见下一节
(3)在清单文件中进行配置
<receiver android:name="com.itheima.mobileguard.receivers.MyAppWidget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/example_appwidget_info" />
</receiver>
(4)创建xml配置文件 example_appwidget_info
a.在res下创建xml文件夹
b.创建example_appwidget_info.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/process_widget"
android:minHeight="72.0dip"
android:minWidth="294.0dip"
android:updatePeriodMillis="0" />
<!-- android:updatePeriodMillis="0"
谷歌默认是每隔半个小时进行更新一次
设置更新时间为0.我们就可以自己控制这个时间
-->
7.进程清理的小控件
(1)创建类继承AppWidgetProvider,放在receiver包下
public class MyAppWidget extends AppWidgetProvider {
//public void OnReceiver(){}------------只要操作widget都会调用该方法
//public void OnUpDate(){}--------系统至少半个钟更新一次,不能再小了
/**
* 第一次创建的时候才会调用当前的生命周期的方法
*
* 当前的广播的生命周期只有10秒钟。
* 不能做耗时的操作
*/
@Override
public void onEnabled(Context context) {
// TODO Auto-generated method stub
super.onEnabled(context);
System.out.println("onEnabled");
Intent intent = new Intent(context,KillProcesWidgetService.class);
context.startService(intent);
}
/**
* 当桌面上面所有的桌面小控件都删除的时候才调用当前这个方法
*/
@Override
public void onDisabled(Context context) {
// TODO Auto-generated method stub
super.onDisabled(context);
Intent intent = new Intent(context,KillProcesWidgetService.class);
context.stopService(intent);
System.out.println("onDisabled");
}
}
(2)创建服务
a.在清单文件中注册
b.代码
public class KillProcesWidgetService extends Service {
private AppWidgetManager widgetManager;
private Timer timer;
private TimerTask timerTask;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
//桌面小控件的管理者
widgetManager = AppWidgetManager.getInstance(this);
//每隔5秒钟更新一次桌面
//初始化定时器
timer = new Timer();
//初始化一个定时任务
timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("KillProcesWidgetService");
//这个是把当前的布局文件添加进行
/**
* 初始化一个远程的view
* Remote 远程
*/
RemoteViews views = new RemoteViews(getPackageName(), R.layout.process_widget);
/**
* 需要注意。这个里面findingviewyid这个方法
* 设置当前文本里面一共有多少个进程
*/
int processCount = SystemInfoUtils.getProcessCount(getApplicationContext());
//设置文本
views.setTextViewText(R.id.process_count,"正在运行的软件:" + String.valueOf(processCount));
//获取到当前手机上面的可用内存
long availMem = SystemInfoUtils.getAvailMem(getApplicationContext());
views.setTextViewText(R.id.process_memory, "可用内存:" +Formatter.formatFileSize(getApplicationContext(), availMem));
Intent intent = new Intent();
//发送一个隐式意图
intent.setAction("com.itheima.mobileguard");
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
//设置点击事件
views.setOnClickPendingIntent(R.id.btn_clear, pendingIntent);
//第一个参数表示上下文
//第二个参数表示当前有哪一个广播进行去处理当前的桌面小控件
ComponentName provider = new ComponentName(getApplicationContext(), MyAppWidget.class);
//更新桌面
widgetManager.updateAppWidget(provider, views);
}
};
//从0开始。每隔5秒钟更新一次
timer.schedule(timerTask, 0, 5000);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
//优化代码
if(timer != null || timerTask != null){
timer.cancel();
timerTask.cancel();
timer = null;
timerTask = null;
}
}
}
(3)接收桌面按钮的广播
a.在清单文件中注册
<receiver android:name="com.itheima.mobileguard.receivers.KillProcessAllReceiver" >
<intent-filter>
<action android:name="com.itheima.mobileguard" />
</intent-filter>
</receiver>
public class KillProcessAllReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
//得到手机上面正在运行的进程
List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
for (RunningAppProcessInfo runningAppProcessInfo : appProcesses) {
//杀死所有的进程
activityManager.killBackgroundProcesses(runningAppProcessInfo.processName);
}
Toast.makeText(context, "清理完毕", 0).show();
}
}
8.省电优化
(1)锁屏关闭