Android进程守护,让APP在系统内存中常驻(二)

      昨天晚上写了用系统服务等方法来实现应用保活。今天写一下用提高app的进程等级来实现应用保活。想看直接调用系统方法保活应用的可以点击Android进程守护,让APP在系统内存中常驻(一)进行跳转。

      一:第一种实现思路,创建广播接收者来监听系统关屏亮屏操作。当手机关屏时,显示一个透明的一像素的activity,此时用户时看不见的;当手机亮屏时,把这个activity给finish掉。好了,有了思路就开始实现吧。

           1.首先新建一个广播接收者:来判断当前的屏幕状态来进行一些操作。

public class AppBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())){
            AppReciver.getInstance().startApp(context);
        }else {
            AppReciver.getInstance().finishApp();
        }

    }
}

          2.创建一个1像素的activity。

  @SuppressLint("RtlHardcoded")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_null);
        //设置1像素
        Window window = getWindow();
        window.setGravity(Gravity.LEFT | Gravity.TOP);
        WindowManager.LayoutParams params = window.getAttributes();
        params.x = 0;
        params.y = 0;
        params.height = 1;
        params.width = 1;
        window.setAttributes(params);
        //用来给单例传过去activity,能让它finish掉。
        AppReciver.getInstance().setActivity(this);
    }

        3.为这个活动创建一个空的透明的主题。

        4.为这个活动修改AndroidManifest中的内容,把它单独放入一个栈中。让他使用刚刚为他创建的主题。

 

        5.创建一个单例,用来完成开始和结束活动任务的逻辑操作。

class AppReciver {

    private static final AppReciver ourInstance = new AppReciver();
    private WeakReference weakReference;

    private AppReciver() {
    }

    static AppReciver getInstance() {
        return ourInstance;
    }

    public void startApp(Context context) {
        context.startActivity(new Intent(context, NullActivity.class));
    }

    public void registerReceiver(Context context) {
        AppBroadcastReceiver appBroadcastReceiver = new AppBroadcastReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.intent.action.SCREEN_OFF");
        intentFilter.addAction("android.intent.action.SCREEN_ON");
        intentFilter.addAction("android.intent.action.USER_PRESENT");
        context.registerReceiver(appBroadcastReceiver, intentFilter);

    }

    public void finishApp() {
        if (weakReference != null && weakReference.get() != null) {
            weakReference.get().finish();
        }
    }

    public void setActivity(NullActivity activity) {
        weakReference = new WeakReference(activity);
    }
}

          6.注意上面的单例中使用了WeakReference来保存activity。这里为了避免内存泄漏使用了弱引用。最后在活动中调用一下就完成了。

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //1.系统拉活service进程
        //startService(new Intent(this,StickService.class));

        //2.通过jobScheduler拉活
        //startJob();

        //3.通过bindService,通过ServiceConnection来拉活
        //bindService();

        //4.通过activity来提升app的进程等级
        AppReciver.getInstance().registerReceiver(this);
    }

       二:service提升app的进程等级

           1.首先新建一个服务。

public class ForegroundService extends Service {
    private static final int SERVICE_ID = 1;

    public ForegroundService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

         2.如果是安卓4.0以下可以直接构建一个空的通知。安卓8.0以上,通知需要设置channel ,还需要设置通知的重要级别 ,安卓9.0以上,通知会直接显示出来。所以要进行版本的判断,来实现通知的设置方式。4.0以下的可以直接通过下面一行代码调用。

if (Build.VERSION.SDK_INT < 18) {
            //安卓4.0以下可以直接构建一个空的通知。
            //设置成前台服务,并且去除通知栏消息
            startForeground(SERVICE_ID,new Notification());
        }

         3.安卓8.0以下的就需要先设置成前台服务,然后再去通过新的服务去除通知栏的消息。好了,废话不说,直接上代码。

else if (Build.VERSION.SDK_INT < 26) {
            //设置成前台服务
            startForeground(SERVICE_ID,new Notification());
            //并且去除通知栏消息
            startService(new Intent(this,InnerService.class));
        }

          4.InnerService直接写一个内部服务就行。在里面进行去除通知栏的消息。

 private class InnerService extends Service{
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            startForeground(SERVICE_ID,new Notification());
            stopForeground(true);
            stopSelf();
            return super.onStartCommand(intent, flags, startId);
        }
    }

            5.下面是这个服务的完整代码。

public class ForegroundService extends Service {
    private static final int SERVICE_ID = 1;

    public ForegroundService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (Build.VERSION.SDK_INT < 18) {
            //安卓4.0以下可以直接构建一个空的通知。
            //设置成前台服务,并且去除通知栏消息
            startForeground(SERVICE_ID,new Notification());
        } else if (Build.VERSION.SDK_INT < 26) {
            //设置成前台服务
            startForeground(SERVICE_ID,new Notification());
            //并且去除通知栏消息
            startService(new Intent(this,InnerService.class));
        } else {
            //安卓8.0以上,通知需要设置channel
            //还需要设置通知的重要级别
            //安卓9.0以上,通知会直接显示出来。
            NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            if (manager!=null){
                NotificationChannel channel = new NotificationChannel("channel","xxx",NotificationManager.IMPORTANCE_NONE);
                manager.createNotificationChannel(channel);
                Notification notification = new NotificationCompat.Builder(this,"channel").build();
                startForeground(SERVICE_ID,notification);
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }

    private class InnerService extends Service{
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            startForeground(SERVICE_ID,new Notification());
            stopForeground(true);
            stopSelf();
            return super.onStartCommand(intent, flags, startId);
        }
    }
}

           6.在活动中启动一下就大功告成了。

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //1.系统拉活service进程
        //startService(new Intent(this,StickService.class));

        //2.通过jobScheduler拉活
        //startJob();

        //3.通过bindService,通过ServiceConnection来拉活
        //bindService();

        //4.通过activity来提升app的进程等级
        //AppReciver.getInstance().registerReceiver(this);

        //5.通过Service来提升app的进程等级
        startService(new Intent(this,ForegroundService.class));
    }

   好了,就说到这吧,有什么补充的或者哪里说的不对的欢迎在下面评论,一期交流,相互学习。

你可能感兴趣的:(Android进程守护,让APP在系统内存中常驻(二))