从来好事天生俭,自古瓜儿苦后甜。这篇文章主要讲述Android开发之获取系统所有进程信息。相关的知识,希望能为你提供帮助。
最近在做一个app,有一个进程管理模块用于管理系统中正在运行的进程,并且可以关闭进程进行加速手机的功能,基本把它实现了出来。界面的效果都是自己写的,虽然有BUG,但是基本上能满足需求,后期我会改进BUG。好了,来看看效果:
文章图片
1.获取系统的可用内存和总内存。
获取系统内存中应用的信息,需要用到ActivityManager这个类,然而当你用这个类拿数据的时候你会发现,拿到的数据不正确。用这个类的API获取系统的总内存和可用内存会出现数据不正确的情况。除了这个类,android手机中有文件描述了这些信息— — /proc/meminfo。meminfo文件中详细的记录了安卓手机的一些数据,包括可用内存和总内存。附上代码:
public static long getTotalMemSize() { long size=0; File file = new File("/proc/meminfo"); try { BufferedReader buffer = new BufferedReader(new InputStreamReader(new FileInputStream(file))); String memInfo = buffer.readLine(); int startIndex = memInfo.indexOf(":"); int endIndex = memInfo.indexOf("k"); memInfo = memInfo.substring(startIndex + 1, endIndex).trim(); size = Long.parseLong(memInfo); size *= 1024; buffer.close(); } catch (java.io.IOException e) { e.printStackTrace(); } return size; }public static long getAviableMemSize() { long size=0; File file = new File("/proc/meminfo"); try { BufferedReader buffer = new BufferedReader(new InputStreamReader(new FileInputStream(file))); String memInfos=new String(); int i=0; while ((memInfos=buffer.readLine())!=null){ i++; if (i==2){ memInfo = memInfos; }} int startIndex = memInfo.indexOf(":"); int endIndex = memInfo.indexOf("k"); memInfo = memInfo.substring(startIndex + 1, endIndex).trim(); size = Long.parseLong(memInfo); size *= 1024; buffer.close(); } catch (java.io.IOException e) { e.printStackTrace(); }return size; }
【Android开发之获取系统所有进程信息。】操作很简单分别是读取第一行的数据和第二行的数据,将字符串分去出,将所得值乘以1024变为byte类型。
2.获取内存中运行应用的信息
首先,自然要有一个Bean文件用于存储这些信息,之后通过ActivityManager的getRunningAppProcesses()方法得到一个RunningAppProcessInfo的List。便利这个List去除我们想要的数据,存在我们的Bean文件夹中。
public static List< TaskBean> getAllTask() { List< TaskBean> taskList=new ArrayList< > (); List< ActivityManager.RunningAppProcessInfo> runList=UIUtils.getActManager().getRunningAppProcesses(); try { for (ActivityManager.RunningAppProcessInfo r:runList) { TaskBean taskBean = new TaskBean(); String processName = r.processName; taskBean.setPackageName(processName); PackageInfo packageInfo = UIUtils.getPacManager().getPackageInfo(processName, 0); taskBean.setIcon(packageInfo.applicationInfo.loadIcon(UIUtils.getPacManager())); taskBean.setName(packageInfo.applicationInfo.loadLabel(UIUtils.getPacManager()).toString()); Debug.MemoryInfo[] processInfo=UIUtils.getActManager().getProcessMemoryInfo(new int[]{r.pid}); taskBean.setMemSize(processInfo[0].getTotalPrivateDirty()*1024); if ((packageInfo.applicationInfo.flags& ApplicationInfo.FLAG_SYSTEM)!=0){ taskBean.setSystem(true); }else { taskBean.setUser(true); } if (taskList != null) { taskList.add(taskBean); for (int i=0; i< taskList.size(); i++) { if (taskList.get(i).getPackageName().equals(Constants.PACKAGE_INFO)){ taskList.remove(i); } } } } } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); }return taskList; }
好了,大功告成。当你开开心心的拿到手机上调试的时候你会发现,一个数据都没有。原来,在Android5.0之后,谷歌处于完全考虑已经弃用了通过如上方法拿到进程中的信息。那么又应该怎么做呢?
public static List< TaskBean> getTaskInfos() { List< AndroidAppProcess> processInfos = ProcessManager.getRunningAppProcesses(); List< TaskBean> taskinfos = new ArrayList< TaskBean> (); // 遍历运行的程序,并且获取其中的信息 for (AndroidAppProcess processInfo : processInfos) { TaskBean taskinfo = new TaskBean(); // 应用程序的包名 String packname = processInfo.name; taskinfo.setPackageName(packname); // 湖区应用程序的内存 信息 android.os.Debug.MemoryInfo[] memoryInfos = UIUtils.getActManager() .getProcessMemoryInfo(new int[] { processInfo.pid }); long memsize = memoryInfos[0].getTotalPrivateDirty() * 1024L; taskinfo.setMemSize(memsize); taskinfo.setPackageName(processInfo.getPackageName()); try { // 获取应用程序信息 ApplicationInfo applicationInfo = UIUtils.getPacManager().getApplicationInfo( packname, 0); Drawable icon = applicationInfo.loadIcon(UIUtils.getPacManager()); taskinfo.setIcon(icon); String name = applicationInfo.loadLabel(UIUtils.getPacManager()).toString(); taskinfo.setName(name); if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { // 用户进程 taskinfo.setUser(true); } else { // 系统进程 taskinfo.setSystem(true); } } catch (PackageManager.NameNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); // 系统内核进程 没有名称 taskinfo.setName(packname); Drawable icon = UIUtils.getContext().getResources().getDrawable( R.drawable.ic_launcher); taskinfo.setIcon(icon); } if (taskinfo != null) { taskinfos.add(taskinfo); for (int i=0; i< taskinfos.size(); i++) { if (taskinfos.get(i).getPackageName().equals(Constants.PACKAGE_INFO)){ taskinfos.remove(i); } } } } return taskinfos; }
好了,接下来只需要判断安装的版本就可以了:
int sysVersion = Integer.parseInt(Build.VERSION.SDK); taskList = sysVersion > 21 ? TaskManagerEngine.getTaskInfos() : TaskManagerEngine.getAllTask();
好了,大功告成。数据就能正常拿到了。关于这个效果,我实现下来比较复杂,用了属性动画和补间动画,依赖于Material Design,封装的不是很好,也有BUG所以这里就不介绍实现方式了。希望这篇文章对你有所帮助。有什么问题可以留言在下方。
推荐阅读
- Android登录界面实现
- Nexus 5 Change FireFox OS to android
- Android中获取屏幕高度和宽度
- android中的动画之布局动画
- Android安全之Https中间人攻击漏洞
- Android琐碎知识点集合
- Java4Android基础学习之复写(override)
- Android--第三方控件--okHttp
- Android高级-正则表达式