标签:android 性能优化 清理后台 activitymanager packagemanager
由于不是系统级的应用, 也没有获得ROOT权限, 所以自己实现任务管理器其实意义并不是很大, 就像没有root的手机安装了LBE这类的手机助手, 虽然也带一键清理内存清理后台进程的功能, 但由于手机助手没有ROOT的最高权限, 因此面对开启了守护进程或者其他自启动的应用进程也是手无举措. 而随着谷歌的推动, 即将推送面世的新系统Android M, 也对权限的管理越来越严格, 这也看出一个趋势, 对移动系统的安全和稳定性要求是越来越高.
虽然意义并不是很大, 但我们还是来练练手吧, 说不定哪天就用上了呢... 哈哈哈.
(效果图)
API是直接提供获取包信息, 应用进程信息以及关闭后台进程等接口的. 思路大概是, 首先获取所有正在运行的进程, 包括系统应用进程和非系统应用进程. 为了防止误关系统进程而引起的错误, 我们过滤掉系统进程, 只在列表显示非系统进程. 然后根据进程的包名, 可以实现关闭正在运行的某个进程或所有进程.
但这里通过这里的例子, 发现关闭了比如微信这样的软件, 但很快又在后台重新创建线程继续运行, 所以做的再好的第三方手机助手应用, 只要这个应用程序没有获取root权限或者系统权限, 依然是无法彻底关闭进程或者防止自启的. 就算加入了类似锁屏自动清后台, 一键清理内存等等这样的功能, 没有root权限的普通应用只能通过类似守护进程的方式, 维持本应用的生命力, 然后每隔一段时间就清一次后台进程. 也额外的耗一点电. 当然这好不好, 就看后台一个应用程序能不能"杀"掉众多第三方后台应用而比原来更节电, 见仁见智吧哈.
实现的过程, 并没有什么困难的地方, 所以就直接上代码了:
首先是ListView的item布局文件 process_list_item.xml :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="100dp" android:padding="10dp" android:descendantFocusability="blocksDescendants" > <ImageView android:id="@+id/imv_avatar" android:layout_width="45dp" android:layout_height="45dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:src="@mipmap/ic_launcher" /> <TextView android:id="@+id/tv_app_name" android:layout_width="wrap_content" android:layout_height="30dp" android:gravity="center_vertical|left" android:layout_toRightOf="@+id/imv_avatar" android:layout_centerVertical="true" android:layout_marginLeft="15dp" android:textSize="18sp" android:text="" /> <TextView android:id="@+id/tv_app_process_name" android:layout_width="160dp" android:layout_height="40dp" android:gravity="center" android:layout_centerVertical="true" android:textSize="18sp" android:visibility="gone" android:maxLines="2" /> <Button android:id="@+id/btn_stop_app" android:layout_width="80dp" android:layout_height="50dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:text="关闭进程" /> </RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/tv_main_title" android:layout_width="match_parent" android:layout_height="50dp" android:text="任务管理器" android:gravity="center" android:textSize="18sp" android:background="#BDBDBD" android:layout_alignParentTop="true" /> <Button android:id="@+id/btn_main_clear" android:layout_width="match_parent" android:layout_height="50dp" android:text="一键清理" android:gravity="center" android:textSize="16sp" android:textColor="#23BB67" android:layout_below="@+id/tv_main_title" /> <ListView android:id="@+id/lv_main" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/btn_main_clear" /> </RelativeLayout>
进程信息对象 ProcessInfo :
/** * Created by AlexTam on 2015/7/29. */ public class ProcessInfo { private String labelName; private Drawable labelIcon; private String processName; public ProcessInfo(){ } public ProcessInfo(String labelName, Drawable labelIcon, String processName) { this.labelName = labelName; this.labelIcon = labelIcon; this.processName = processName; } public String getLabelName() { return labelName; } public void setLabelName(String labelName) { this.labelName = labelName; } public Drawable getLabelIcon() { return labelIcon; } public void setLabelIcon(Drawable labelIcon) { this.labelIcon = labelIcon; } public String getProcessName() { return processName; } public void setProcessName(String processName) { this.processName = processName; } }
/** * Created by AlexTam on 2015/7/29. */ public class ProcessListAdapter extends BaseAdapter{ private Context context; private List<ProcessInfo> processList; private viewHolder holder; private processListButtonClick listener; public ProcessListAdapter(Context context, List<ProcessInfo> processList, processListButtonClick listener) { this.context = context; this.processList = processList; this.listener = listener; } @Override public int getCount() { return processList.size(); } @Override public Object getItem(int position) { return processList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ProcessInfo processInfo = (ProcessInfo)getItem(position); if(convertView == null) { holder = new viewHolder(); convertView = View.inflate(context, R.layout.process_list_item, null); holder.imv_avatar = (ImageView) convertView.findViewById(R.id.imv_avatar); holder.tv_name = (TextView) convertView.findViewById(R.id.tv_app_name); holder.tv_processName = (TextView) convertView.findViewById(R.id.tv_app_process_name); holder.btn = (Button) convertView.findViewById(R.id.btn_stop_app); } else { holder = (viewHolder)convertView.getTag(); } holder.imv_avatar.setImageDrawable(processInfo.getLabelIcon()); holder.tv_name.setText(processInfo.getLabelName()); holder.tv_processName.setText(processInfo.getProcessName()); holder.btn.setOnClickListener(new POnClickListener(processInfo.getProcessName())); convertView.setTag(holder); return convertView; } private class POnClickListener implements View.OnClickListener { private String processName; public POnClickListener(String processName) { this.processName = processName; } @Override public void onClick(View v) { if(listener != null) listener.onButtonClick(processName); } } private class viewHolder { ImageView imv_avatar; TextView tv_name; TextView tv_processName; Button btn; } public interface processListButtonClick { void onButtonClick(String processName); } }
/** * Created by AlexTam on 2015/7/29. */ public class MainActivity extends Activity { private ListView ll_main; private List<ProcessInfo> processList = new ArrayList<ProcessInfo>(); private List<ApplicationInfo> applicationInfoList ; private ProcessListAdapter adapter = null; private Button btn_clear; private List<String> processNamelist = new ArrayList<String>(); private ProgressDialog progressDialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ll_main = (ListView) findViewById(R.id.lv_main); btn_clear = (Button) findViewById(R.id.btn_main_clear); getProcessList(); btn_clear.setOnClickListener(new MyOnclick()); } @Override public void onDestroy() { super.onDestroy(); } private class MyOnclick implements View.OnClickListener { @Override public void onClick(View v) { if(v == btn_clear) { clearAllBackgroundProcess(); } } } /** * 获取进程信息列表 */ private void getProcessList() { ActivityManager activityManager = (ActivityManager)getSystemService(ACTIVITY_SERVICE); //获取所有将运行中的进程 List<ActivityManager.RunningAppProcessInfo> runningAppList = activityManager.getRunningAppProcesses(); PackageManager packageManager = this.getPackageManager(); //获取所有包信息 applicationInfoList = packageManager.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES); if(processList != null && processList.size() > 0) processList.clear(); if(processNamelist != null && processNamelist.size() > 0) processNamelist.clear(); for(ActivityManager.RunningAppProcessInfo process : runningAppList) { if(process.processName.indexOf(this.getPackageName()) < 0) { //过滤本应用包名 ProcessInfo p = new ProcessInfo(); ApplicationInfo appInfo = getApplicationInfoByProcessName(process.processName); if(appInfo == null) { //有些应用的守护进程并没有目标应用对应,此时返回null } else { p.setLabelIcon(appInfo.loadIcon(packageManager)); p.setLabelName(appInfo.loadLabel(packageManager).toString()); p.setProcessName(appInfo.processName); processNamelist.add(appInfo.processName); processList.add(p); } } } if(adapter == null) { adapter = new ProcessListAdapter(MainActivity.this, processList,new ItemButtonClick()); ll_main.setAdapter(adapter); ll_main.setOnItemClickListener(new MyOnItemClickListener()); } else { adapter.notifyDataSetChanged(); } } /** * 根据进程名获取应用信息 * @param processNames * @return */ private ApplicationInfo getApplicationInfoByProcessName(String processNames) { if(applicationInfoList == null || applicationInfoList.size() < 1) return null; for(ApplicationInfo applicationInfo : applicationInfoList) { if(applicationInfo.processName.equals(processNames) && (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) <= 0) //只显示第三方的应用进程,不显示系统应用 //要显示所有应用进程,删去(applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) <= 0 即可 return applicationInfo; } return null; } private class MyOnItemClickListener implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { TextView tv_appName = (TextView) view.findViewById(R.id.tv_app_name); TextView tv_processName = (TextView) view.findViewById(R.id.tv_app_process_name); String appName = tv_appName.getText().toString(); String processName = tv_processName.getText().toString(); Toast.makeText(MainActivity.this, "应用: " + appName + "\n进程: " + processName, Toast.LENGTH_SHORT).show(); } } private class ItemButtonClick implements ProcessListAdapter.processListButtonClick { String pName = null; @Override public void onButtonClick(String processName) { pName = processName; AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setTitle("关闭进程") .setMessage("确定要关闭 " + processName+" 进程吗?") .setPositiveButton("确定", new DialogInterface.OnClickListener(){ public void onClick(DialogInterface dialog, int which) { if(pName != null) { ActivityManager activityManager = (ActivityManager)MainActivity.this. getSystemService(ACTIVITY_SERVICE); activityManager.killBackgroundProcesses(pName); getProcessList(); } } }) .setNegativeButton("取消", new DialogInterface.OnClickListener(){ public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.show(); } } private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if(msg.what == 0x1) { startClearAnim(); } else if(msg.what == 0x2) { stopClearAnim(); getProcessList(); } super.handleMessage(msg); } }; /** * 一键清理 */ private void clearAllBackgroundProcess() { mHandler.sendEmptyMessage(0x1); ActivityManager activityManager = (ActivityManager)MainActivity.this.getSystemService(ACTIVITY_SERVICE); if(processNamelist != null && processNamelist.size() > 0) { for(String processName : processNamelist) { activityManager.killBackgroundProcesses(processName); } } mHandler.sendEmptyMessageDelayed(0x2, 2000); } private void startClearAnim() { progressDialog = new ProgressDialog(MainActivity.this); progressDialog.setMessage("努力清理中..."); progressDialog.show(); } private void stopClearAnim() { progressDialog.dismiss(); } }
相信很多人都明白, 其实Android系统有自己的运行机制, 每个应用都有自己的进程, 每个进程对应有一个虚拟机, 这样设计为的是当自己这个进程挂掉也不会影响系统的运行和其他进程. 而当运行一些比较占内存的应用时, 系统也会自动将优先级低, 视为"无用,过时"的后台进程关闭, 从而挤出内存. 当然这不是万能的, 因为系统也并不总是能这么及时的处理, 以至于我们在使用比如游戏这样的应用时, 低内存的手机还是会由于内存不足的原因感觉有些卡顿. 所以显得手动请后台有一定的合理性.
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:android 性能优化 清理后台 activitymanager packagemanager
原文地址:http://blog.csdn.net/stzy00/article/details/47138885