精华内容
下载资源
问答
  • 一个仿制手机卫士的一键加速的百分框,自己写的一个demo,用来练习一下自定义viewpackage com.dengyun.jiawei.percentview; import android.content.Context; import android.graphics.Canvas; import android....

    一个仿制手机卫士的一键加速的百分框,自己写的一个demo,用来练习一下自定义view



    package com.dengyun.jiawei.percentview;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.RectF;
    import android.graphics.Region;
    import android.support.annotation.Nullable;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    
    import static java.lang.Math.cos;
    import static java.lang.Math.sin;
    
    /**
     * @title
     * @desc Created by liujiawei on 2018/3/19.
     */
    
    public class PercentView extends View {
        private Paint mPaint;
        private Paint mBgPaint;
        private Paint btnGgPaint;
        private Paint btnTextPaint;
        private int mCenterX,mCenterY;
        private float mRadius =500;//外层区域
        private float mCirRaius =400;//圆半径
        private float mRectWidth =500;//按键背景宽度
        private String percentText ="60分";
        private String btnText ="一键加速";
        private float fontSize =250;// 分数字体大小
        private float fontSize_btn =80;//按键字体大小
        private int percent =60;//分数大小
        private Region globalRegion, btnRegion;
        private OnBtnClickListener listener;
        private Matrix matrix;
        private Context context;
        private  float fontWidth;//分数字体宽度
    
        public PercentView(Context context) {
            this(context,null);
        }
    
        public PercentView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            this.context  = context;
            matrix = new Matrix();
            //分数画笔
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            //背景画笔
            mBgPaint = new Paint();
            mBgPaint.setColor(Color.parseColor("#FF0ABBEC"));
            //按键文字画笔
            btnTextPaint = new Paint();
            btnTextPaint.setColor(Color.parseColor("#FF0ABBEC"));
            //按键背景画笔
            btnGgPaint = new Paint();
            btnGgPaint.setColor(Color.WHITE);
    
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            mCenterX = w/2;
            mCenterY = h/2;
            globalRegion = new Region(-w/2,-h/2,w/2,h/2);
            btnRegion  = new Region();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.translate(mCenterX,mCenterY);
            if (matrix.isIdentity()){
                canvas.getMatrix().invert(matrix);
            }
            //绘制背景
            RectF rectF = new RectF(-mRadius,-mRadius,mRadius,mRadius);
            canvas.drawRect(rectF,mBgPaint);
    
            // 绘制分度盘
            for (int i=0;i<100;i++) {
                int x = (int) (mCirRaius * cos(i * 3.6f * Math.PI / 180-Math.PI /2));
                int y = (int) (mCirRaius * sin(i * 3.6f * Math.PI / 180-Math.PI /2));
                if (i<=percent){
                    mPaint.setColor(Color.WHITE);
                }else {
                    mPaint.setColor(Color.GRAY);
                }
                canvas.drawCircle(x, y, 5, mPaint);
    
            }
            //绘制分数
            percentText = percent + "";
            Paint.FontMetrics metrics = new Paint.FontMetrics();
            mPaint.setColor(Color.WHITE);
            mPaint.setTextSize(fontSize);
            fontWidth = mPaint.measureText(percentText);
            float fenWidth = btnTextPaint.measureText("分");
            float totalWidth = fontWidth + fenWidth;
            canvas.drawText(percentText, -totalWidth / 2, 0, mPaint);
            btnTextPaint.setColor(Color.WHITE);
            btnTextPaint.setTextSize(fontSize_btn);
            canvas.drawText("分",totalWidth/2-fenWidth,0,btnTextPaint);
            btnTextPaint.setColor(Color.parseColor("#FF0ABBEC"));
            mPaint.setTextSize(fontSize_btn);
            //绘制按键
            RectF btnRect = new RectF(-mRectWidth/2,50,mRectWidth/2,200);
            Path path  = new Path();
            path.addRoundRect(btnRect,75,75, Path.Direction.CW);
            btnRegion.setPath(path,globalRegion);//绑定按键区域
    
            canvas.drawPath(path,btnGgPaint);
            fontWidth = btnTextPaint.measureText(btnText);
            canvas.drawText(btnText,-fontWidth/2,155,btnTextPaint);
    
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            //设置区域按键监听
            float pts[] = new float[2];
            pts[0] =  event.getX();
            pts[1] =   event.getY();
            matrix.mapPoints(pts);
            int Px = (int) pts[0];
            int Py = (int) pts[1];
            switch (event.getActionMasked()){
                case MotionEvent.ACTION_DOWN:
                    if (btnRegion.contains(Px,Py)){
                        btnGgPaint.setColor(Color.GRAY);
                        btnTextPaint.setColor(Color.WHITE);
                        invalidate();
                    }
    
                    break;
                case MotionEvent.ACTION_UP:
                    if (btnRegion.contains(Px,Py)){
                        listener.onPercentUp();
                        btnGgPaint.setColor(Color.WHITE);
                        btnTextPaint.setColor(Color.parseColor("#FF0ABBEC"));
                        invalidate();
                    }
    
                    break;
            }
            return true;
        }
        //动态改变分度值
        public void changePercent(int i) {
            percent = i;
            invalidate();
        }
    
        public interface OnBtnClickListener{
              void  onPercentUp();
        }
        public void setOnBtnClickListener(OnBtnClickListener listener){
            this.listener = listener;
        }
    }
    


    项目地址:https://github.com/569518423/PercentView
    展开全文
  • 获取android5.0以上运行内存并杀死,过滤自己及系统进程,杀死其他进程(源码)
  • 一键加速手机QQ音乐,让扣扣等级飞起来,
  • Android 一键加速原理

    2016-10-31 16:31:00
    在上一篇中介绍了“垃圾清理”,在系统优化中有一个功能往往是与垃圾清理分不开的,那就是“手机加速”。目前流行的管理软件中以及网络上并没有明确的定义什么叫“垃圾清理”什么叫“手机加速”。结合上一篇的“垃圾...

    说明

     

    在上一篇中介绍了“垃圾清理”,在系统优化中有一个功能往往是与垃圾清理分不开的,那就是“手机加速”。目前流行的管理软件中以及网络上并没有明确的定义什么叫“垃圾清理”什么叫“手机加速”。结合上一篇的“垃圾清理”这里统一做一个在本系列文章中的定义:

    n 垃圾清理:在本系列文章中认为扫描和清理的是静态内容,包括应用的文件缓存、缩略图、日志等系统或应用创建的文件,这些文件不具有“运行时”特征。

    n 手机加速:在本系列文章中认为清理的是动态内容,包括杀死运行时进程、限制开机自启动、限制后台自启动,以及应用运行时所占用的内存等,这些内容都与进程相关,具有“运行时”特征。

    在对垃圾清理和手机加速做了简单的区分以后,本篇接下来将研究一下手机加速的相关内容。

    清理运行时进程

     

    清理运行时进程也就是清理后台进程,有些手机管理软件中也叫“一键加速”或者“一键清理”等,其实指的都是这个功能。

    在正式介绍介绍进程清理之前,先简单介绍一些Android中进程的内存管理策略。

    Android内存管理策略

     

    Android中,进程的生命周期都是由系统控制的,即使用户关掉了程序,进程依然是存在于内存之中。这样设计的目的是为了下次能快速启动。当然,随着系统运行时间的增长,内存会越来越少。Android Kernel 会定时执行一次检查,杀死一些进程,释放掉内存。

    在Android对内存管理引入了Linux中使用的一种名称为OOM(Out Of Memory,内存不足)的机制来完成这个任务,该机制会在系统内存不足的情况下,选择一个进程并将其Kill掉。在Android中对Linux原生的OOM机制根据嵌入式设备的特点进行了一些改造,于是就有了Low Memory Killer。

     内存管理不是本文的重点,想了解Low Memory Killer的朋友可以自己查阅相关资料或者查看源码,这里不做详细介绍。Low Memory Killer在源码中的位置为:@/kernel/goldfish/drivers/staging/android/lowmemorykiller.c。这里要明确的问题由两点:

    A.       Low Memory Killer在用户空间中指定了一组内存临界值,当其中的某个值与进程描述中的oom_adj值在同一范围时,该进程将被Kill掉。

    B.       Android中的oom相关参数在init.rc中进行初始化配置,在系统运行时由ActivityManagerService进行动态调整。

    Android进程优先级

     

    根据oom_adj,Android将进程分为6个等级,它们按优先级顺序由高到低依次是:

    1)        前台进程( FOREGROUND_APP)

    2)        可视进程(VISIBLE_APP )

    3)        次要服务进程(SECONDARY_SERVER )

    4)        后台进程 (HIDDEN_APP)

    5)        内容供应节点(CONTENT_PROVIDER)

    6)        空进程(EMPTY_APP)

    这六类进程所对应的oom_adj的值在不同的手机中可能会有所不同。下面是在我的小米2S手机上的参数如下:

     

    注意值越大说明进程重要程度越低。

    在我的小米2S上这几种进程会被杀死的时机如下:

     

    注意这些数字的单位是page. 1 page = 4 kB。

    对于单个进程的oom_adj的值可以查看/proc/pid/oom_adj的值,如下:

     

    清理运行时进程

     

    在简单的了解了Android对进程和内存的管理策略以后,我们会发现这样一个问题:Android中的Low Memory Killer策略会定时扫描,并根据其策略选择杀死进程的。那能给我们清理运行时进程带来什么参考呢?

    我们在杀死运行时进程的一种可行性方案:可以根据oom_adj的值制定一个阀值,在用户触发(当然也可以定时触发)时,判断如果进程的oom_adj的值大于阀值,则杀死。杀死进程有两种方式,下面分别介绍:

    选择在Linux层面杀死进程

     

    可以选择根据1.2中的方式读取/proc/pid/oom_adj的值进行判断,然后通过Linux中的kill函数杀死进程。

    在Android层面,系统是通过如下属性定义进程的重要程度的:

    @/frameworks/base/core/Java/android/app/ActivityManager$RunningAppProcessInfo

     

    其中,importance的取值如下,关于各个值的含义在下面的注释中:

     

    采用这种方式杀死进程的部分示例代码如下:

     

    在上面的示例代码中我们是通过ActivityManager类中的killBackgroundProcesses接口来杀死进程的,下面来看一下killBackgroundProcesses:

     

    这里需要注意如下几点:

    A.     但是通过该方法只能杀死进程优先级低于SERVICE_ADJ的进程。

    B.      使用该方法需要声明KILL_BACKGROUND_PROCESSES权限

    C.      该接口为ActivityManager中的公开接口,不需要任何权限。

    对于大部分情况下,通过调用改接口杀死后台进程就够了,但有时候我们要执行更加严格的进程清理策略,杀死优先级更高的进程,该如何处理呢?下面一节将做介绍。

    一种更加严格的进程杀死方案

     

    接着上一节最后的问题继续分析,看一下系统是如何选择杀死指定优先级以下的进程的。虽然在Android中并没有提供接口给我们使用,但是可以确信Android自身肯定也会有我们类似的需求。最后我在ActivityManagerService(后面简称“Ams”)中找到了这个功能的系统实现,如下:

    @/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

     

    @/frameworks/base/core/java/android/os/Process.java

     

    通过上面的过程可以看出,Ams在杀死进程时最后实际调用的是android.os.Process中的killProcessQuiet方法。到此就十分清晰了,我们在实现杀死进程时只有自己实现上述过程就可以了。

    通过killProcessQuiet的实现我们可以看出该方法是一个隐藏的方法,在应用中时不能直接调用的。仔细观察Process类,我们又发现了一个类似的实现,即killProcess方法,如下:

     

    这里的killProcess和killProcessQuiet是一样的,唯一的区别是通过killProcess杀死进程时会有“Sendingsignal. PID: %d SIG: %d"”字样的log打印出来。所以,我们在实现自己的杀进程逻辑时直接使用killProcess方法就可以了。

    一种防止被杀死进程重启的方案

     

    本节上面的三个小节中介绍了三种杀死进程的可行性方案,通过验证它们也是可行有效的。但是,细心的朋友在验证上面的方案时会发现直接杀死进程时可能会遇见如下一些问题:

    A.       有些进程无法被杀死或者在被杀死后会重启(主要是系统应用和Service)。

    B.       在杀死当前正在运行的进程时可能会出现异常状况。

    那么需要如何解决这种情况呢?通过查看ActivityManager的代码,我发现了这样一个方法,如下:

     

    仔细看一下forceStopPackage方法的说明,哎呀,简直超出我们的预期。通过使用forceStopPackage方法,不仅可以强制停止应用进程,甚至可以强行停止掉与当前进程相关的其他一些相关的内容,比如:

     

    • 与当前应用共享uid的其他进程。
    • 所有证照运行的Service
    • 所有的Activity
    • 通知
    • 定时器

     

    进一步研究forceStopPackage的实现后发现,在调用forceStopPackage时系统会将当前的package状态设置为stopped状态。在Android2.3版本之后,被标记为stopped状态的应用是不能接受广播的,除非在发送广播时指定FLAG_EXCLUDE_STOPPED_PACKAGES标志,但是系统广播是无法认为指定改标志位的。

    下面是forceStopPackage方法的内部实现:

    @/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

     

    通过对这个方法的研究我们可以得出如下几点结论:

    A.       在使用forceStopPackage接口时需要声明FORCE_STOP_PACKAGES权限。

    B.       forceStopPackage是一个隐藏接口,需要通过反射等手段实现调用。

    C.       使用forceStopPackage接口需要系统签名.

    D.       forceStopPackage接口除了可以用来杀死进程外,还可以达到禁止开机自启动和后台自启动的目的。

    E.        在使用forceStopPackage接口时可能会有不想要发生的副作用(清空定时器等),慎重使用。

    F.        Package的stopped状态是在Android4.0以后增加的,也就是说在2.3之前的版本forceStopPackage并不能禁用开机广播等。

    一件加速快捷方式动画效果实现

     

    关于UI相关的内容不是本文的终端,感兴趣的朋友可以参考网上的一篇文章:

    http://blog.csdn.net/ruils/article/details/16922557

    开机自启动管理

     

    我们无论做什么事情总是要知其然,然后才能之前所以然。因此,在了解如何禁止开启自启动之前需要先来来了解一下开机自启动的原理,以及系统发出BOOT_COMPLETED广播的时机。

    开机自启动的原理

     

    Android在开机时,在系统启动完成后会发送一个Standard Broadcast,名为"android.intent.action.BOOT_COMPLETED”。所谓“开机自启”就是注册接收BOOT_COMPLETED的静态广播,在收到广播时将自己唤起。

    下面是一小段示例程序:

     

    在AndroidManifest中注册静态BOOT_COMPLETED广播:

     

    要使BOOT_COMPLETED广播生效,需要声明RECEIVE_BOOT_COMPLETED权限。

     

    这里很简单,大家基本上都用过,没有什么可讲的。这里要说的是几点要注意的问题:

    A.       在使用BOOT_COMPLETED广播时,要记得声明RECEIVE_BOOT_COMPLETED权限。

    B.       在Android4.0开始,Android增加了Package stopped状态,处于该状态的应用是接收不到开机广播的。处于stopped状态的应用包括:

    n  调用1.3.4中介绍的forceStopPackage接口停止的应用。

    n  在“设置->应用->应用详情页”中点“停用”按钮,被停用的应用。

    n  新安装完成,从未打开和运行过的应用。

    C.       在Android2.3之前的版本中,不存在上一条所说的限制,可以接收的开机广播。

    D.       在Android4.0以后的版本中,如果想使处于stopped状态的应用也接收到广播,需要在intent中增加FLAG_EXCLUDE_STOPPED_PACKAGES这个Flag。但是这里要注意的是,系统广播使用户无法自定义的。

    E.        BOOT_COMPLETED是一个Standard广播,在开发应用时有时会希望自己的应用在接收到开机广播后比其他同样接收开机广播的应用更早的启动就需要指定”android:priority”属性的值为最大整数(priority为整形,取值范围为-1000到1000)即可。

    开机自启动的时机

     
    在2.1节中我们了解到开机自启动是通过接受系统广播“BOOT_COMPLETED”实现的,那“BOOT_COMPLETED”是系统什么时候发出的呢?对于Android系统启动的过程,不是本文研究的内容,不做介绍,这里只说一下与开机广播“BOOT_COMPLETED”相关的部分,如下图所示:
     
     

    可以看出开机广播是在系统启动完成后,在启动第一个应用进程(桌面)时发出的。

    实现禁止开机自启动

     

    了解了开机自启动的原理,接下来介绍一下在开发手机管理软件时,如何实现禁止应用开机自启动。通过前面的分析,我们想一下如果想禁用开机广播有哪些可能的实现?从应用接收处理广播的整个过程来说,其实无外乎下面这几种可能:

    A.       阻止系统发出BOOT_COMPLETED开机完成广播。

    B.       不阻止系统发出广播,但是阻止应用接收到BOOT_COMPLETED开机完成广播。

    C.       应用可以接收到BOOT_COMPLETED广播,但是阻止应用进行响应。

    D.       运行应用接收BOOT_COMPLETED广播并且进行响应,但是在应用响应后阻止其运行。

    接下来将依次分析这几种情况的可行性:

    A.       第一种方案在应用的层次难以实现,而且也不太合理,是不可行的。

    B.       第二种方案理论上是可行的,至少到目前为止前面介绍过的forceStopPackage就可以做到。

    C.       第三种方案,理论上也是可行的,但可能会有些难度(进程注入)。

    D.       第四种方案,也是可行的,而且根据之前的分析也是比较容易做到的。

    下面就依次分析一下具体的实现方案:

    通过停止应用实现禁止开机自启动

     

    对于上面的第二种方案中“不阻止系统发出广播,但是阻止应用接收到BOOT_COMPLETED开机完成广播“的想法,相信大家很快都会想到在1.3.4中介绍过的forceStopPackage这个接口,这个接口除了可以杀死正在运行的进程以外,还有一些“副作用”,其中将应用状态置为“stopped”和清空定时器这些正是我们在实现禁止开机自启动时所需要的。

    由于前面一对forceStopPackage的使用和需要注意的问题等都做了比较详细的说明,这里不再赘述,不清楚的朋友可以参考1.3.4节。

    通过停用广播接收器实现禁止开机启动

     

    forceStopPackage接口完全可以满足我们的需求,甚至大大超出了我们的需求,不仅禁用了开机自启动,连后台自启动等等也都禁用了。这些副作用很多时候并不是我们想要的,那有没有一种”副作用”相对较小的实现方式呢?于是引出了本小节这种实现方式。

    本方案也是基于第二种方案中“不阻止系统发出广播,但是阻止应用接收到BOOT_COMPLETED开机完成广播“的想法实现的。

    刚开始有这个想法的时候可能会有些无从下手的感觉,没关系既然本方案的核心是“阻止广播接收”,那我们就先来看一下Android中静态的广播接收器是如何定义的,下面是Android官方文档中关于receiver的截图:


    不知道各位读者在看到“android:enable”这个属性的时候有没有像我一样眼前一亮的感觉。就我而言,在平时开发普通的应用程序时几乎没有关注过这个属性,因为很少有这方面的需求。好了,让我们看一下“android:enable”这个属性,如下:

     

    看完了这段描述,是不是感觉不仅满足了我们的需求,而且又有一个小惊喜呢?是的,就是这句“The<application> element has its own enabled attribute that applies to allapplication components, including broadcast receivers.”。这说明除receiver以外的其他应用组件也都拥有“android:enable”属性。呵呵,到这里是不是为我们禁止后台自启动应用也找到了一种解决方案?

    在了解了“android:enable”这个属性以后,下面看一下它的使用:

    @/frameworks/base/core/java/android/content/pm/PackageManager.java

     

    在PackageManager中除了setComponentEnabledSetting以外,还提供了另外一个接口setApplicationEnabledSetting,通过setApplicationEnabledSetting可以停用应用中所有的组件,代码如下:

     

    这里要注意的问题由这么几点:

    A.       通过调用setApplicationEnabledSetting可以将应用中的所有组件置为disable状态。

    B.       与forceStopPackage接口相比,该接口不会清空定时器等,因此如果应用通过定时器定时发送自定义广播,并且在广播中指定FLAG_EXCLUDE_STOPPED_PACKAGES是可以唤醒的。

    C.       使用setComponentEnabledSetting接口必须是system程序并具有system签名。

    D.       使用该接口需要声明CHANGE_COMPONENT_ENABLED_STATE。

    E.        该接口在应用于在AndroidManifest中的入口Activity(intent-filter指定action为“android.intent.category.LAUNCHER”)时,还可以达到隐藏应用快捷方式图标的效果。

    下面是使用该接口的一段代码片段:

     

    停用广播接收器方案实例研究

     
    开机自启动管理有一款小而美的软件AutoStart相信很多朋友都听说过,截图如下:
     
     
    这款软件就是利用了2.3.2中介绍的原理实现的,下面是一小段反编译后的代码片段:
     
     

    不少朋友会有到这里会有这样一个疑问:在上一节中不是说使用setComponentEnabledSetting接口需要system权限(是system程序并具有system签名)吗?AutoStart并不是system,它是怎么做到的呢?一个同事告诉我AutoStart是通过“pm”命令来做的提醒了我,下面看一下pm命令:

     

    执行pm需要的shell权限,在取得root权限的情况下就可以直接执行使用了。这也提醒我们在分析一个问题遇到阻碍的时候,不防稍微发散一下和听取一下别人的建议。

    停用广播接收器方案继续探讨

     

    用过Windows系统的朋友都知道在Windows中有一个称为注册表的东西,维护着Windows系统中已安装应用的相关信息。在Android中严格意义上是不存在注册表这样的东西的,但是在维护安装包信息方面,Android中存在着一个类似的文件“/data/system/packages.xml”,如下图:

     

    在通过setComponentEnabledSetting设置后,最终会在packages.xml中产生如下数据:

     

    那在取得root权限的情况下,直接修改packages.xml能不能达到停止自启动的效果呢?大家不妨可以自己验证一下,这里应该是不可以的。因为packages.xml是在PackageManagerService服务初始化的时候解析完成的,以后使用的都是保存在内存数据结构中的数据,直接修改packages.xml文件无法达到修改内存中的数据的目的。这里在重启手机下次进入时应该是会生效的(没有验证)。

    通过杀死进程实现禁止开机自启动

     

    本方案是对第四种方案“运行应用接收BOOT_COMPLETED广播并且进行响应,但是在应用响应后阻止其运行”的分析和讨论。本方案的想法是这样的:

    如果我们在系统启动完成后能够尽早的接收到“BOOT_COMPLETED”,然后监控其他应用进程,如果发现接下来有其他应用被启动,则强行杀死。这样也就达到了禁止应用开机自启动的目的。下面依次分析该方案中的几个关键点:

    A.       如何能够尽早的启动?

    结合2.1和2.2中介绍的原理,这里我们可以采取两方面的措施:

    1)        指定receiver的优先级为最大整数

    2)        指定receiver的category为“android.intent.category.HOME”

     

    B       如何监控当前进程?

    自身启动一个定时器,定时轮询正在运行的服务,执行清理工作。

    查询开机启动的应用可以通过PackageManager中提供的下面这个接口实现:

     

    除了杀死开机启动的应用进程外,在定时唤醒时也可以杀死后台启动的进程。在ActivityManager中提供了获取正在运行的Services和Application的方法,如下:

     
     

    C       如何杀死进程?

    这里可以采用前面介绍过的android.os.killProcess即可;也可以采用ActivityManager中的killBackgroundProcesses接口。ActivityManager中的restartPackage接口也能达到同样的目的,但已不推荐使用。

    该方案存在的问题:

    A.       采用定时轮询的方式实现,自身比较耗电。

    B.       除了可以用来限制开机自启动,也可以用来限制后台自启动。

    C.       在获取开启自启动列表时,可以先判断是否具有“android.permission.RECEIVE_BOOT_COMPLETED”权限。

    杀死进程方案实例研究

     
    采用杀死进程方案的应用中也存在一个非常有名的应用”AutorunManager”,截图如下:
     
     

    AutorunStartupIntentReceiver接收到开启广播后,启动AutorunService服务:

     

    AutorunService服务启动后,启动一个Timer执行h任务:

     

    h任务读取程序开机自启动设置,如果程序不允许开机启动,则杀死该程序进程:

     

    后台自启动管理

     

    所谓名不正则言不顺,在分析后台自启动之前,这里先对开机自启动和后台自启动做一个概念上的区分。网上没有找到相关的定义,这里主要是根据自己的理解来给出一下本系列文章中的定义。

     

    • 开机自启动:

     

    1)        从启动时机来说:发生在刚启动完成时。

    2)        从启动原理来说:由开机启动广播“BOOT_COMPLETED”触发。

     

    • 后台自启动

     

    1)        从启动时机来说:发生在启动完成后正常运行时。

    2)        从启动原理来说:由“BOOT_COMPLETED”广播以外的其他场景触发,常见的常见有:锁屏解锁、网络状态变化、定时器等。

    开机自启动与后台自启动实际上并没有本质上的区别,在第2章中介绍过的方法也同样适用于后台自启动。这里只说几点需要注意的问题:

    A.       在使用forceStopPackage接口时有一种情况比较难以避免,就是应用之前相互唤起的问题。

    B.       在使用setComponentEnabledSetting接口时需要注意对用户自定义广播的处理。

    C.       在使用killPrcocess方式时需要注意误杀情况的处理。

     

    总结

     

    垃圾清理和手机加速的功能到现在就差不多介绍完了,这里想说一些个人的想法,希望能够引起本系列文章读者的一些思考。

    Android中的”垃圾清理“和”手机加速”本身就是一个悖论。你认为是垃圾的东西,可能正是产生垃圾的软件所想保留的;你认为通过手机加速为用户清理了内存空间,殊不知充分利用内存正是Linux内存管理的机制,不提供应用直接杀死进程,将进程统一由系统创建和回收,也是Android为快速创建进程的一种优化。我从不认为Linux内核的开发者或者Android框架的开发者会比我们更加白痴(无知),在系统的设计之初和系统的演化过程中,这里肯定经历过了无数次的讨论与权衡验证,证明了目前所采用的方案是一种可以平衡各方需求的相对优良的做法。

    看到目前市面上形形色色的各类手机管理软件、电子市场各显神通地打着“用户体验”的幌子,为了满足用户心理上那种“爽”的需求,提供甚至自动去清理垃圾和手机加速。应用们为了搜集用户信息和推送等苦心积虑的监听各种广播和定时器来保证自身应用的驻留。这两者的相互博弈,导致应用的整体情况更加恶劣。看到目前Android应用的各种乱象,作为一名Android开发者,真的很痛心疾首。

    并不一定所有的朋友都能认同我的观点,甚至很多人会觉得正是这些不规范造就了Android生态的繁荣,也同样造就了一批类似于360这样的手机安全公司。但是,我还是所有开发者希望在开发应用的过程中能够指定一个“合适的策略”,因为作为用户的我们已经被你们搞的够乱了

     

    到此,手机加速就介绍完了,欢迎大家交流讨论。下一篇将介绍《应用杂篇》,即不属于前几篇的一些应用管理方面的功能,如应用锁、山寨应用识别、应用安装位置判断、应用智能推荐等。

    转载于:https://www.cnblogs.com/jamboo/articles/6016332.html

    展开全文
  • 最近有人问我金山清理大师桌面上的一键加速的动画是如何实现的,我下了个金山清理大师装在手机上,体现了一把,感觉还不错,所以就花了点时间研究了一下。 先看看效果: 点一下,   第一感觉就是在Window中增加...

    转载请注明出处:http://blog.csdn.net/ruils/article/details/16922557

    最近有人问我金山清理大师桌面上的一键加速的动画是如何实现的,我下了个金山清理大师装在手机上,体现了一把,感觉还不错,所以就花了点时间研究了一下。

    先看看效果:


    点一下,

     

    第一感觉就是在Window中增加View的做法来实现的,像360卫士的悬浮窗那样,而且这个动画效果会随着一键加速图标在桌面上的位置改变而改变,放在什么地方就从什么地方开始做动画,放在左边屏幕,就会向右边做动画,放在右边屏幕会向左边做动画,在自己的代码中怎么才能知道自己的图标所在屏幕的位置呢,百思不得其解,后来看了下Log,才发现其中的奥秘

    Log:

    I/ActivityManager(595): START u0 {act=android.intent.action.MAIN flg=0x10000000 cmp=com.cleanmaster.mguard_cn/com.cleanmaster.processcleaner.ProcessCleanerActivity bnds=[216,385][376,585]} from pid 866
    

    从log中可以看出,点击一键加速的图标,实现上是启动了一个activity,而且还带有参数:bnds=[216,385][376,585],我去找了下Lanucher中的代码,

    packages/apps/Launcher2/src/com/android/launcher2/

    Launcher.java

    2001         Object tag = v.getTag();
    2002         if (tag instanceof ShortcutInfo) {
    2003             // Open shortcut
    2004             final Intent intent = ((ShortcutInfo) tag).intent;
    2005             int[] pos = new int[2];
    2006             v.getLocationOnScreen(pos);
    2007             intent.setSourceBounds(new Rect(pos[0], pos[1],
    2008                     pos[0] + v.getWidth(), pos[1] + v.getHeight()));
    2009 
    2010             boolean success = startActivitySafely(v, intent, tag);
    2011 
    2012             if (success && v instanceof BubbleTextView) {
    2013                 mWaitingForResume = (BubbleTextView) v;
    2014                 mWaitingForResume.setStayPressed(true);
    2015             }
    2016         } else if (tag instanceof FolderInfo) {

    只有在点击一个快捷方式的时候,才会有附带坐标信息,原来这个一键加速是个快捷方式!现在明白了,点击一个快捷方式图标的时候,Lanucher会把此快捷方式的矩形的坐标放在Intent中传给所启动的activity。

    intent.setSourceBounds
    既然知道这个坐标是怎么放的了,那取出来就简单了:

    intent.getSourceBounds();

    那接下来就一步一步实现这个动画

    程序中用到的图片资源,我是从金山清理大师的APK中拿出来的,仅供学习参考之用!


    1.首先要添加一个快捷方式到桌面

    请参考我写的另外一篇博客:

    [Android开发实战]添加快捷方式到桌面的两种方式

    2.创建这个快捷方式启动的Activity.

    这个activity得是透明的,我们创建一个Style

        <style name="Transparent">
            <item name="android:windowBackground">@android:color/transparent</item>
            <item name="android:windowIsTranslucent">true</item>
            <item name="android:windowNoTitle">true</item>
        </style>
    然后把这个Style应用到这个Activity上:

      <activity
                android:name="com.cleanmanager.AnimationActivity"
                android:theme="@style/Transparent" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                </intent-filter>
            </activity>

    注意给Activity加上<action android:name="android.intent.action.MAIN" />,因为这个Activity要从别的程序(Lanucher)中启动,所以这个Activity要能够做为一个启动的入口。


    3. 在onCreate方法中,把动画所需要的布局文件显示在快捷方式所在的位置:

    // 取得Lanucher传过来的所点击的快捷方式的矩形坐标。
    		rect = intent.getSourceBounds();
    		if (rect == null) {
    			finish();
    			return;
    		}
    
    		Log.d(TAG, rect.toShortString());
    
    		mRelativeLayout = (RelativeLayout) findViewById(R.id.framelayout);
    		mShortcut = (RelativeLayout) findViewById(R.id.shortcut);
    
    		backImageView = (ImageView) findViewById(R.id.clean_back);
    		roateImageView = (ImageView) findViewById(R.id.clean_rotate);
    		// iconmageView = (ImageView) findViewById(R.id.clean_icon);
    		textView = (TextView) findViewById(R.id.text);
    
    		// DisplayMetrics dm = new DisplayMetrics();
    		int width = getWindowManager().getDefaultDisplay().getWidth();
    		int hight = getWindowManager().getDefaultDisplay().getHeight();
    
    		Log.d(TAG, "width = " + width);
    		Log.d(TAG, "hight = " + hight);
    
    		RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mShortcut
    				.getLayoutParams();
    		layoutParams.topMargin = rect.top - (rect.bottom - rect.top) / 4;
    
    		// 判断快捷方式在屏幕的哪一边,如果在左边,伸缩动画就会向右,如果在右边,伸缩动画向左。
    		if (rect.left < width / 2) {
    			direction = Direction.RIGHT;
    			layoutParams.leftMargin = rect.left;
    
    		} else {
    			direction = Direction.LEFT;
    			layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    			layoutParams.rightMargin = width - rect.right;
    			Log.d(TAG, "rightMargin = " + (width - rect.right));
    		}
    
    		mRelativeLayout.updateViewLayout(mShortcut, layoutParams);

    快捷方式在屏幕左边的时候,就以左边为基准,快捷方式在屏幕右边的时候,就以右边为基准。


    4.在onAttachedToWindow的时候,开始做旋转动画。 我们模拟金山清理大师正在清理,两秒钟之后,清理完了,开始做伸缩了

    	@Override
    	public void onAttachedToWindow() {
    		super.onAttachedToWindow();
    		// 旋转动画开始
    		roateImageView.startAnimation(AnimationUtils.loadAnimation(this,
    				R.anim.rotate_anim));
    
    		// 假设垃圾清理了两秒钟,然后开如做伸缩动画。
    		mHandler.sendEmptyMessageDelayed(MESSAGE_ROTATE_FINISHED, 2000);
    	}

    5.把旋转动画清除,然后开始拉伸updateWidth();

    	private Handler mHandler = new Handler() {
    
    		public void handleMessage(android.os.Message msg) {
    			switch (msg.what) {
    			case MESSAGE_ROTATE_FINISHED:
    				mWidth = backImageView.getWidth();
    				Log.d(TAG, "mWidth = " + mWidth);
    				updateWidth();
    				roateImageView.clearAnimation();
    				roateImageView.setVisibility(View.INVISIBLE);
    				break;
    			case MESSAGE_UPDATE_WIDTH:
    				updateWidth();
    				break;
    
    			default:
    				break;
    			}
    
    		};

    6.主要是通过不停的加大拉伸ImageView的宽度来实现拉伸动画。实现方式有很多种,可以自定义View,以后我会讲解如何自定义View,这里用的比较简单的方式实现的。

    定义宽度到达以前宽度的2.5倍就线束动画,显示文字。

    	private void updateWidth() {
    		// 宽度没有达到原来宽度的2.5度,继续做动画
    		if (backImageView.getWidth() <= 2.5f * mWidth) {
    			RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) backImageView
    					.getLayoutParams();
    			// 每次增加20的宽度,可以自行设置,和用户体验有关系,可自行调整
    			layoutParams.width = backImageView.getWidth() + 20;
    			mShortcut.updateViewLayout(backImageView, layoutParams);
    			// 继续发更新消息。也可发送delay消息,和用户体验有关系,<span style="font-family: Arial, Helvetica, sans-serif;">可自行调整</span>
    			mHandler.sendEmptyMessage(MESSAGE_UPDATE_WIDTH);
    		} else {
    			textView.setVisibility(View.VISIBLE);
    
    		}
    
    	};


    看下效果:



    点一下,



    如果您喜欢这篇文章请点赞哦!

    最后附上源码:

    示例源码下载:http://download.csdn.net/detail/u012379847/6604299

    Github地址:https://github.com/seashell752/CleanManager


    展开全文
  • 懒人全自动脚本,一键自动swap2c一键3d加速一键wifi加速等等前言/注意事项以下有部分补丁并不是能适合所有的ROM使用,请在下载/使用前看清楚我在帖子中的说明,如果因为用户自身问题造成手机某些功能不正常工作...

    懒人全自动脚本,一键自动swap2c一键3d加速,一键wifi加速等等

    前言/注意事项

    以下有部分补丁并不是能适合所有的ROM使用,请在下载/使用前看清楚我在帖子中的说明,如果因为用户自身问题造成手机某些功能不正常工作本人概不负责

    添加自动化功能的脚本均由本人亲自编写,版权没有,欢迎转载,但还请说明出处

    你所下载得到的.zip包里面的文件请都不要重命名,因为我在刷机脚本中给文件定义好了权限或者定义了刷入并自动执行的命令,重命名后刷机脚本就不能正常实现自动化功能

    论坛上已有补丁或不需要实现自动化功能我就没有重复发了,大家可以转到本坛帖子或XDA去找到更多的内容

    本坛:/forum.php?mod=viewthread&tid=3424772&extra=page%3D1%26filter%3Dtypeid%26typeid%3D1346%26typeid%3D1346

    一键开启swap并开机自动启动(手机内存,不会消耗SD卡内存,读写速度更快)

    (适用于所有ROM)

    为什么我要写这个脚本?论坛不是有一堆开swap的优秀教程了吗?原因是我发现原版的MiniCM7-2.2.0中居然开机自动会挂载18M的swap,不知道你发现了没,也不知道其他ROM有么有这个情况,这样就导致了很多朋友无法开启更大的swap,nobodyAtall大神并没有在更新log里面说明这个,可能是最新CM7.2源码里面的功能吧,如果你发现了这个18Mswap在哪里不妨告诉我,此脚本可以和原来的18M的swap叠加

    用CWM刷入本栏目提供的补丁包,开机,用RE管理器进入system/,这时你可以看到多了3个脚本

    权限什么的我全部已经设置好,你只需选择执行文件

    你想把swap建在哪里呢?要多大?维维为大家提供了3个位置选择,并且都是开机自动运行的,但你只能选择一个位置。

    CreatIMGCache.sh代表在手机cache/文件夹下创建一个大小为45M的swap.img文件

    CreatIMGSystem.sh代表在手机system/文件夹下创建一个大小为64M的swap.img文件

    CreatIMGData.sh代表在手机data/文件夹下创建一个大小为90M的swap.img文件

    想好了要建在什么位置了?好,那来吧,点击你想要创建swap的位置的脚本,就拿data的做例子,点击CreatIMGData.sh,再点击运行,稍后一会,你要的菜马上就好

    看到脚本输出最后一行swap了吗,第一个数据不为0而且和你创建的大小相近就表示成功了,看,Data区的64M是不是和图中数据的大小基本一致!

    相关介绍/修改swap大小

    什么是cache system data?先在这里说一下它们的大小,你修改swap大小时请不要超过它们的大小

    cache是系统自带个一个文件夹,大概有50M左右,是电子市场专用下载的文件夹。

    system就是系统文件的文件夹,大概150M左右,存放系统文件所用

    data是我们平时安装文件到机子中所存储的文件夹,大概200M左右,使我们安装应用存储的

    你还可以自己修改swap的大小再然后再执行创建,用文本编辑器打开你要修改的脚本文件,修改如图数据即可,kb为单位

    自动swap脚本下载: SwapPatch -All .zip (157.77 KB, 下载次数: 2109)

    什么?你的swap不会开机启动了?试试我这个补丁吧(修复data、system、cache下swap.img不开机启动): FixAutoRun.zip (157.85 KB, 下载次数: 683)

    3D加速补丁

    (2.3系统+nAa內核v10 或以上 / alfs v07 ICS适用)

    作用和效果请参考:/thread-3258390-1-10.html (感谢机油。Kai。柒)

    脚本会自动删除system/lib/egl/libGLES_android.so和自动在p中加入需要内容

    你只需用CWM刷入即可

    补丁下载: update-Adreno-Lib.zip (1.31 MB, 下载次数: 937)

    xLoud&Bravia

    (适用性未知)

    来自:/forum.php?mod=viewthread&tid=3424772&extra=page%3D1%26filter%3Dtypeid%26typeid%3D1346%26typeid%3D1346]/forum.php?mod=viewthread&tid=3424772&extra=page%3D1%26filter%3Dtypeid%26typeid%3D1346%26typeid%3D1346

    已测试MiniCM7-2.2.0不起效,其他ROM我没做任何测试,请自测

    脚本自动在p里添加内容,用户只需刷入即可

    补丁下载: xLo

    展开全文
  • WiFi上网加速器 ...一键式的专业信号增强,不增加手机辐射,绿色安全,永久免费,请放心下载!WiFi信号增强器是网上冲浪、聊天、游戏加速的好帮手! 我们的优势: 信号增强—WIFI超强信号更强
  • 360一键root 是一款360出品的Android手机一键root工具,支持三星、索爱、MOTO、HTC、LG、中兴、华为等超过70个品牌500款机型的一键root,帮助您获取权限删除系统内不必要的应用,精简系统,加快手机速度。...
  • 一键清理 开源版

    千次阅读 2015-03-05 14:50:17
    一键清理 开源版,包括内存加速,缓存清理,自启管理,软件管理等。 点击下载最新版本 说明 前一段时间买了一个android 手机,发现竟然没有一键所清理有进程功能!就下载了市面上的一些一键清理软件。但是使用...
  • Android一键清理原理

    千次阅读 2018-08-31 18:15:41
    在总篇中提到过垃圾清理,本篇将着重介绍针对缓存、卸载残留、无用数据等“静态内容”的清理,有关于系统进程的清理以及手机加速的相关功能,将放到《手机加速篇》中介绍研究。   什么是垃圾   关于系统垃圾的...
  • 360安卓一键root,获取权限,精简系统,加速手机
  • 百度一键root工具完美覆盖安卓[2]2.2-4.1的主流机型,集成10套强力智能Root引擎绝对安全,Root无风险,Root成功之后,手机上的授权管理让您感受到强大而又贴心的功能。 百度一键root工具功能: 系统精简 删除预置...
  • 数十种root破解方案,安全无忧!全面支持安卓2.2至4.2主流机型!...开机加速 禁止开机自启,尽享极速开机 内存管理 彻底清理进程,告别手机卡顿 权限监控 监控恶意行为,保护隐私资费 百度一键Root截图:
  • 360一键root工具 v5.1.3 pc绿色版 软件大小:3.9MB 软件语言:简体中文 ...360一键root工具获取手机最高权限,精简系统,加速手机,360安卓一键root工具完美支持 Android 2.1-4.2.1 超过100个品牌上千款机型一键ro
  • 2、全面优化的UI设计 ,运行流畅,使管理手机文件 ,照片,音乐快速便捷。 3、支持P2SP下载核心,加速资源的下载速度,高速资源下载体验。 4、直接一键升级正版应用,在线直接下载正版限免,并高于iTunes五倍的速度...
  • 百度安卓一键Root工具,操作简单,安全无风险,轻松获取最高权限。最安全最好用对的安卓手机Root工具。Root后,可以删除手机预装应用,管理开机自启动,提升手机性能。 软件介绍 完美覆盖安卓[3]2.2-4.1的主流机型 ...
  • 刷机精灵 v1.1.2

    2015-01-15 23:59:23
    3、手机一键加速:迅速让手机告别卡顿 4、手机省电功能:让手机续航更持久 5、一键更换字体:热门酷炫手机字体一键拥有 【了解我们】 1、最专业:目前已支持上百款安卓热门机型一键刷机 2、最快速:针对支持机型...
  • Android 一键清理、内存清理功能实现

    千次阅读 2016-10-09 14:32:40
    在总篇中提到过垃圾清理,本篇将着重介绍针对缓存、卸载残留、无用数据等“静态内容”的清理,有关于系统进程的清理以及手机加速的相关功能,将放到《手机加速篇》中介绍研究。 什么是垃圾 关于系统垃圾的定义 ...
  • 高仿QQ的手机管家的小火箭加速

    千次阅读 2015-01-06 10:53:56
    腾讯的手机管家,用过这个App的人都应该知道桌面的火箭一键加速这个功能,研究一下这个小火箭是怎么做出来的。先来了解一下小火箭有神马动作,首先在没有触碰它时,就是一个电源的显示或是一个图标依附在屏幕的两侧...
  • 最近小编发现一款更加稳定、强大的远程管理软件RdViewer,完全免费下载、使用方式相当简易,支持Windows、iOS、Android,不管你是要电脑连电脑,还是出门在外临时用手机操控家里的电脑,都能够用这款 RdViewer 轻松...
  • 安装EcStore收货地址一键分析插件后,就能直接复制在淘宝平台或京东一号店平台上的客户收货地址,简单粘贴到地址分析栏,一键点击“地址分析”就可完成收货地址输入,加速下单过程,避免输入错误,再不会因为写错收...
  • 此次升级的智邦国际ERP系统31.83版本,通过增强采购、库存、生产、财务等业务一体化管理,PC端、手机端、平板端、PDA端协同智能化水平,帮助企业加速供应链协同战略,让连接随时随地,让企业...
  • 仿市面上一些手机管家的源码。仅仅适合学习使用。里面功能包括文件管理、垃圾清理、一键加速等等
  • 小狐狸加速器Mac版可以让你一键加速网络,让你体验极速、流畅的网络环境,小狐狸加速器Mac版提供多种免费的网络路线。而且小狐狸加速器支持多平台,包括手机、电脑等平台,喜欢的用户快来下载吧! 小狐狸加速器...
  • 推荐一款手机清理工具App悟空清理 1介绍 悟空清理是一款完全免费的手机加速与存储空间清理工具软件,强力去除顽固垃圾,使手机运行更...一键加速,智能扫描,一键清理;手机加速,清理释放内存,使用更畅快 ;...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 139
精华内容 55
关键字:

手机一键加速