2)结束某个进程
3)一键清理正在运行的进程
4)查看当前剩余内存
5)查看某些系统信息
6)查看当前正在运行的任务
7)查看当前正在运行的服务
8)分享给好友
经测试,本APP可以运行在Android 2.3.3 至 Android 4.2 的系统上。
(1)欢迎界面的实现
首先要撰写一个Welcome活动,Welcome.java,实现两个活动间的延迟跳转功能。
- package cn.edu.neuq.smarttaskman;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.os.Handler;
- //欢迎界面
- public class Welcome extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.start);
- //延迟0.7秒后执行run方法中的页面跳转
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- Intent intent = new Intent(Welcome.this, MainActivity.class);
- startActivity(intent);
- Welcome.this.finish();
- }
- }, 700);
- }
- }
然后,实现start.xml的布局,最重要的是android:scaleType="centerCrop",确保图片铺满整个View。
还要实现全屏显示,把标题栏和信息栏都去掉,并使Welcome活动在点开图标后首先显示。
AndroidMainfest.xml内部修改如下:
- <activity
- android:name="cn.edu.neuq.smarttaskman.Welcome"
- android:label="@string/app_name"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
(2)主界面的实现
主界面主要是由一个RelativeLayout嵌套包含上下两个LinearLayout,中间夹着一个ListView实现的,这里不再详述。
下图为主界面,可以看到最上面为标题栏,然后是一个LinearLayout,里面有4个TextView,每个的权重都为1,四个TextView平分一行。
(3)剩余内存的获取
首先要获取ActivityManager类型的系统服务信息,然后获得ActivityManager.MemoryInfo类型的MemoryInfo对象,调用getMemoryInfo(memoryInfo),将可用内存保存到memoryInfo上,最后再进行相应的类型转换即可。
- public ActivityManager myActivityManager =
- (ActivityManager)getSystemService(Activity.ACTIVITY_SERVICE);
- public void upDateMemInfo(){
- ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
- myActivityManager.getMemoryInfo(memoryInfo) ;
- long memSize = memoryInfo.availMem ;
- //字符类型转换
- leftMemSize = Formatter.formatFileSize(getBaseContext(), memSize);
- leftMem.setText(leftMemSize);
(4)获取正在运行的进程信息
将进程以ListView的形式显示出来,最重要的是得到进程信息以及创建相应的适配器。
主要是利用了ActivityManager.RunningAppProcessInfo这个类。
- //获得正在运行进程的某些信息
- public void getRunningProcessInfo(){
- myActivityManager = (ActivityManager)MainActivity.this.getSystemService(ACTIVITY_SERVICE);
- proNum.setText(myActivityManager.getRunningAppProcesses().size()+"");
- arrayListPro = new ArrayList<String>();
- mRunningPros = myActivityManager.getRunningAppProcesses();
- for (ActivityManager.RunningAppProcessInfo amPro : mRunningPros){
- // 获得该进程占用的内存
- int[] myMempid = new int[] {amPro.pid};
- // 此MemoryInfo位于android.os.Debug.MemoryInfo包中,用来统计进程的内存信息
- Debug.MemoryInfo[] memoryInfo = myActivityManager.getProcessMemoryInfo(myMempid);
- // 获取进程占内存信息形如3.14MB
- double memSize = memoryInfo[0].dalvikPrivateDirty/1024.0;
- int temp = (int)(memSize*100);
- memSize = temp/100.0;
- String ProInfo="";
- ProInfo +="Name:"+ amPro.processName
- + "\nID:" + amPro.pid
- + "\nMemory:" + memSize + "MB";
- arrayListPro.add(ProInfo);
- }
- arrayAdapter = new ArrayAdapter<String> (MainActivity.this, android.R.layout.simple_list_item_1, arrayListPro);
- proList.setAdapter(arrayAdapter);
- }
(5)为按钮绑定监听器
1. 一键清理
- Button kill_all = (Button)findViewById(R.id.kill_all);
- kill_all.setOnClickListener(new OnClickListener(){
- public void onClick(View source){
- for (ActivityManager.RunningAppProcessInfo amPro : mRunningPros){
- String processName = amPro.processName;
- myActivityManager.killBackgroundProcesses(processName);
- }
- getRunningProcessInfo();
- upDateMemInfo();
- makeToastSimple("一键清理结束,当前可用内存为" + leftMemSize, true); }
- });
利用for循环,把所有能杀死的进程全部杀死(系统进程使用killBackgroundProcesses方法杀不死),达到一键清理的目的。
2. 刷新
- Button refresh = (Button)findViewById(R.id.refresh);
- refresh.setOnClickListener(new OnClickListener()
- {
- @Override
- public void onClick(View source)
- {
- getRunningProcessInfo();
- makeToast("已刷新");
- upDateMemInfo();
- }
- });
(6)为ListView的item绑定监听器
1. 点击产生简单对话框
当用户点击某个ListView的item的时候,就会产生一个对话框,让用户选择是否杀死该进程,如果用户点击了确定,就会先确定是点击了哪一个进程,再根据进程名去杀死该进程。
- myActivityManager.killBackgroundProcesses(processName);
- proList.setOnItemClickListener(new OnItemClickListener(){
- public void onItemClick(AdapterView<?> arg0, View arg1, final int position, long arg3) {
- new AlertDialog.Builder(MainActivity.this).setMessage("是否杀死该进程")
- .setPositiveButton("确定", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- String processName = mRunningPros.get(position).processName;
- myActivityManager.killBackgroundProcesses(processName);
- getRunningProcessInfo() ;
- upDateMemInfo();
- makeToastSimple("已杀死进程" + processName, true);
- }
- }).setNegativeButton("取消",new DialogInterface.OnClickListener(){ @Override
- public void onClick(DialogInterface dialog, int which) { dialog.cancel() ;
- }
- }).create().show() ;
- }
- });
2. 长按产生列表对话框
当用户长按某个ListView的item的时候,就会产生一个对话框,这个对话框与上一个不同的是,这个有多个选择,而不是上一种的单选(确定或取消),称之为列表对话框。
- proList.setOnItemLongClickListener(new ListView.OnItemLongClickListener(){
- @Override
- public boolean onItemLongClick(AdapterView<?> arg0, final View view, final int position, long arg3) {
- final String processName = mRunningPros.get(position).processName;
- android.content.DialogInterface.OnClickListener listener1 = new DialogInterface.OnClickListener(){
- public void onClick(DialogInterface dialog, int which) {
- if(which==0){
- myActivityManager.killBackgroundProcesses(processName);
- getRunningProcessInfo() ;
- upDateMemInfo();
- makeToastSimple("已杀死进程" + processName, true);
- }else if (which==1)
- check_detail(position);
- }
- };
- new AlertDialog.Builder(MainActivity.this)
- .setTitle("操作")
- .setItems(R.array.operation,listener1)
- .setPositiveButton(R.string.cancel, new DialogInterface.OnClickListener(){
- public void onClick(DialogInterface dialog, int which) {
- <span style="white-space:pre"> </span>@Override
- dialog.cancel() ;
- }
- }).show();
- return true;
- }
- });
(7)查看详情
- public void check_detail(int position){
- ActivityManager.RunningAppProcessInfo processInfo =
- mRunningPros.get(position);
- Intent intent = new Intent(this, detail.class);
- intent.putExtra("EXTRA_PROCESS_PID", processInfo.pid + "");
- intent.putExtra("EXTRA_PROCESS_UID", processInfo.uid + "");
- intent.putExtra("EXTRA_PROCESS_NAME", processInfo.processName);
- intent.putExtra("EXTRA_PROCESS_IMPORTANCE", processInfo.importance + "");
- intent.putExtra("EXTRA_PROCESS_IMPORTANCE_REASON_CODE",
- processInfo.importanceReasonCode + "");
- intent.putExtra("EXTRA_PROCESS_IMPORTANCE_REASON_PID",
- processInfo.importanceReasonPid + "");
- intent.putExtra("EXTRA_PROCESS_LRU", processInfo.lru + "");
- intent.putExtra("EXTRA_PKGNAMELIST", processInfo.pkgList) ;
- startActivity(intent);
- }
public static final int importance,参照Android官方文档的说明,
进程的优先级一共有六种,分别是:
IMPORTANCE_FOREGROUND, 100
IMPORTANCE_PERCEPTIBLE,130
IMPORTANCE_VISIBLE, 200
IMPORTANCE_SERVICE, 300
IMPORTANCE_BACKGROUND, 400
IMPORTANCE_EMPTY. 500
其中IMPORTANCE_PERCEPTIBLE自从API 9才开始引入,其
它的从API 3就开始引入了。级别的数字越小,代表越重要。
(8)Menu键
当用户按下物理键盘的menu键时触发,显示菜单列表,依次为“查看正
在运行的任务”,“查看正在运行的服务”等。当用户点击某个菜单时,
相应的就会执行某个函数。
- //以下是按下menu呼出的菜单的添加处理
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- menu.add(0, TASK, 0, "查看正在运行的任务");
- menu.add(0, SERVICE, 0, "查看正在运行的服务");
- menu.add(0, ABOUT, 0, "关于应用");
- menu.add(0, INFO, 0, "系统信息");
- menu.add(0, SHARE, 0, "分享应用");
- menu.add(0, EXIT, 0, "退出应用");
- return super.onCreateOptionsMenu(menu);
- }
- public void show_tasks(){
- Intent intent = new Intent(this, getTask.class);
- startActivity(intent);
- }
- public void show_services(){
- Intent intent = new Intent(this, getService.class);
- startActivity(intent);
- }
- public void about_info(){
- Intent intent = new Intent(this, about_info.class);
- startActivity(intent);
- }
- public void system_info(){
- Intent intent = new Intent(this, system_info.class);
- startActivity(intent);
- }
- public void share(){
- Intent intent=new Intent(Intent.ACTION_SEND);
- intent.setType("text/plain"); //纯文本
- intent.putExtra(Intent.EXTRA_SUBJECT, "分享");
- intent.putExtra(Intent.EXTRA_TEXT, "我发现了一个好用的Android APP,SmartTaskMan。");
- startActivity(intent);
- }
- @Override
- public boolean onOptionsItemSelected(MenuItem mi){
- switch (mi.getItemId()){
- case TASK:
- show_tasks();
- break;
- case SERVICE:
- show_services();
- break;
- case ABOUT:
- about_info();
- break;
- case INFO:
- system_info();
- break;
- case SHARE:
- share();
- break;
- case EXIT:
- finish();
- break;
- }
- return true;
- }
(9)分享功能的实现
所有可以接收plain类型的应用都响应。将文本发送到可以接收文本的应用中(例如电子邮件)。
- public void share(){
- Intent intent=new Intent(Intent.ACTION_SEND);
- intent.setType("text/plain"); //纯文本
- intent.putExtra(Intent.EXTRA_SUBJECT, "分享");
- intent.putExtra(Intent.EXTRA_TEXT, "我发现了一个好用的Android APP,SmartTaskMan。下载地址:....");
- startActivity(intent);
- }
(10)查看正在运行的任务和服务
主要是利用了以下两个类。
ActivityManager.RunningServiceInfo
‚ActivityManager.RunningTaskInfo
原理与查看正在运行的进程相同,这里不再赘述。
ActivityManager.RunningServiceInfo的部分属性:
属性名 | 数据类型 | 解释 |
process | String | 服务所在进程名 |
pid | Int | 服务所在进程的id |
uid | Int | 拥有这个服务的用户id |
foreground | Boolean | 服务是否在前台 |
activeSince | Long | 服务第一次的启动时间 |
ActivityManager.RunningTaskInfo的部分属性:
属性名 | 数据类型 | 解释 |
baseActivity | ComponentName | 该任务的应用程序 |
Id | Int | 任务的id |
numRunning | Int | 任务中所运行的Activity数量,不包括已停止或不延续运行的 |
numActivities | Int | 任务中所运行的Activity数量,包含已停止的 |
desctiption | CharSequende | 任务的当前状态描述 |
(11)系统信息
系统信息的主界面也是一个ListView,与之前的proList用系统自带的item类型不同,这里每一个item都是自定义的(在system_item.xml文件里面定义)。
- package cn.edu.neuq.smarttaskman;
- import android.os.Build;
- import android.os.Bundle;
- import android.app.Activity;
- import android.content.Context;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.BaseAdapter;
- import android.widget.ListView;
- import android.widget.TextView;
- public class system_info extends Activity {
- private ListView mLisview;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.system);
- String[][] systemInfo = getSystemInfo();
- MyAdapter myAdapter = new MyAdapter(getApplicationContext(), systemInfo);
- mLisview = (ListView)findViewById(R.id.sysList);
- mLisview.setAdapter(myAdapter);
- }
- private class MyAdapter extends BaseAdapter{
- private String[][] systemInfo;
- MyAdapter(Context context,String[][] systemInfo){
- this.systemInfo = systemInfo;
- }
- @Override
- public int getCount() {
- return systemInfo.length;
- }
- @Override
- public Object getItem(int position) {
- return systemInfo[position];
- }
- @Override
- public long getItemId(int position) {
- // TODO Auto-generated method stub
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- convertView = getLayoutInflater().inflate(R.layout.system_item, null);
- TextView name = (TextView) convertView.findViewById(R.id.name);
- TextView value = (TextView) convertView.findViewById(R.id.value);
- name.setText(systemInfo[position][1]);
- value.setText(systemInfo[position][0]);
- return convertView;
- }
- }
- private String[][] getSystemInfo() {
- Build mBuild = new Build();
- String[][] systemInfo = {
- {mBuild.BOARD,"主板"},
- {mBuild.BRAND,"系统定制商 "},
- {mBuild.CPU_ABI,"cpu指令集 "},
- {mBuild.DEVICE,"设备参数 "},
- {mBuild.DISPLAY," 显示屏参数 "},
- {mBuild.FINGERPRINT,"硬件名称"},
- {mBuild.HOST,"主机 "},
- {mBuild.MANUFACTURER," 硬件制造商 "},
- {mBuild.MODEL,"版本 "},
- {mBuild.PRODUCT," 手机制造商 "},
- {Build.VERSION.RELEASE,"版本字符串格式 "}
- };
- return systemInfo;
- }
- }
(12)消息提示
利用Toast组件,实现消息提示功能。
以下函数是一个简单的toast,只提示文本信息,如本页左图所示。函数接收一个String类型的参数和boolean类型的参数。若sel为true,则显示一个短时间(LENGTH_SHORT)的消息提示框,否则,显示一个长时间{LENGTH_LONG}的消息提示框。
- public void makeToastSimple(String str,boolean sel){
- Toast toast = Toast.makeText(MainActivity.this,str,
- sel?Toast.LENGTH_SHORT:Toast.LENGTH_LONG);
- toast.show();
- }
以下函数是一个较复杂的toast,不仅提示文本信息,还显示一张图片,如本页右图所示。函数接收一个String类型的参数。这里我利用了该Toast对象的setView方法来改变Toast对象的内容View。
- public void makeToast(String str){
- Toast toast = Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT);
- View toastView = toast.getView();
- ImageView image = new ImageView(MainActivity.this);
- image.setImageResource(R.drawable.ic_launcher);
- LinearLayout ll = new LinearLayout(MainActivity.this);
- ll.addView(image);
- ll.addView(toastView);
- toast.setView(ll);
- toast.show();
- }