android 如何实现一键清理

 从事android系统开发有一段时间,一直在想着能够有一些内容能够与朋友们分享;同时,也能够再一次的加深之前解决的问题和原理!开发过程中有时也是通过搜索各种资料和阅读各位博主的文章,解决了遇到的问题;在此,也对各位博主和大神表示感谢,这也是我想写博客的原因,不能一直是"拿来主义"!
 先写一个比较简单的例子当作开端!
 问题描述:在一次客户定制的机器上有一音乐apk,在点击最近任务界面的"X"号退出之后仍然能够播放歌曲
 ![一键清理图](https://img-blog.csdn.net/20170913211629401?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTWljaGFlbDMxMjkxNw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

解决方案:X号的资源id为dismiss_task,源码位于frameworks\base\packages\SystemUI\src\com\android\systemui\recents\views\TaskViewHeader.java
该按键的点击事件在该类中的

      @Override
    public void onClick(View v) {
        if (v == mIconView) {
            EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
        } 
       else if (v == mDismissButton) {
       **ActivityManager activityManager = (ActivityManager)
                getContext().getSystemService(Context.ACTIVITY_SERVICE);*
            TaskView tv = Utilities.findParent(this, TaskView.class);
            tv.dismissTask();*
      **if("清理app的title".equalsIgnoreCase(mTitleView.getText().toString())){
                activityManager.forceStopPackage("清理app的包名");*
      }*
            // Keep track of deletions by the dismiss button
            MetricsLogger.histogram(getContext(), "overview_task_dismissed_source",
                    Constants.Metrics.DismissSourceHeaderButton);
     }     
    .............
    }

只需要调用ActivityManager的forceStopPackage(String pkgName)方法即可,该函数是系统隐藏函数,其作用是:强制终止指定的apk,包括apk所在的进程及service,并且终止service不会被当做crash而被系统重新启动起来;因此使用该函数限制因素有:1.集成的app必须放置到system/app或者priv-app 2.具有系统签名
重新编译SystemUI验证,可以发现功能虽然可以,但是还是存在问题;如果切换语言的话,会导致“清理app的title”变成相应的语言,还是不起作用;那么在TaskViewHeader.java文件中查看是否有获取App相关信息函数;是否有任务栈之类的变量呢?仔细查看代码,在该mDismissButton上方的mIconView中有一个Task mTask全局变量,frameworks\base\packages\SystemUI\src\com\android\systemui\recents\model\Task.java
查看该类,很明显的看到该类有一个getComponent()的方法,能够返回应用的组件名;因此完全可以通过获取的组件名,再获得相应的包名既可以完全解决该问题。
如何获得getComponent()方法呢?该方法是Task中TaskKey的内部类的方法;TaskKey又是Task的公共的全局变量,那么可以通过mTask获取到对应的TaskKey属性,再由TaskKey调用getComponent()就可以完全解决!
修改上述代码如下:

        ComponentName cn = mTask.key.getComponent();
            String pkgName = cn.getPackageName();  //获取包名
             String className = ngetClassName();     //获取类名
            if("清理app的类名".equalsIgnoreCase(pkgName)){
                activityManager.forceStopPackage("清理app的类名");
        }
其实通过做android系统开发,有些问题主要是考虑到系统是否有类似的功能和对应的函数,这也就要求我们有时对源码有个大致的印象,能够定位到问题点、相应的系统函数或者系统功能,完成自己所需要的功能和问题的解决方案!

你可能感兴趣的:(android系统开发)