精华内容
参与话题
问答
  • APP保活

    2017-04-25 13:31:25
    APP保活

    APP保活

    前言

    app保活,在Android中是一种流氓行为,一方面无端浪费用户手机电量,另一方面给用户一种很困惑的感觉,影响用户体验还有可能导致整个Android系统流畅性变差,所以Google官方一种不推荐该功能,也一直在阻止这方面功能在Android系统上运行,作为一个Android开发人员,应该极力地址这种无耻的行为!!!
    

    保活的方式:

    一、白色保活:

    • 给用户明确的提示,我这个应用的进程优先级比较高,不容易被杀死,请你也不要手动杀死!
      |– 开启前台服务进程

    二、灰色保活(目前保活的主流做法,比如qq、微信 – 当然他们不止这一种保活手段)

    • 也是利用前台服务进程的方式,来提高进程的优先级,但是不会在通知栏给用户明确的提示
      |– 利用系统的漏洞,开启前台服务进程,不会有通知!

      ① API < 18,启动前台service时直接传入new=”“>

      ② API >= 18,同时启动两个id相同的前台Service,然后再将后启动的Service做stop处理;
      —–查看开启的服务是否为前台进程 “dumpsys activity services 应用包名”

      public class GrayService extends Service {
      
         private final static int GRAY_SERVICE_ID = 1001;
      
         @Override
         public int onStartCommand(Intent intent, int flags, int startId) {
      
             if (Build.VERSION.SDK_INT < 18) {
                 //API < 18
                 startForeground(GRAY_SERVICE_ID, new Notification());
             } else {
                 Intent innerIntent = new Intent(this, GrayInnerService.class);
                 startService(innerIntent);
                 startForeground(GRAY_SERVICE_ID, new Notification());
             }
      
             return super.onStartCommand(intent, flags, startId);
         }
      
         ...
         ...
      
         /**
          * 给 API >= 18 的平台上用的灰色保活手段
          */
         public static class GrayInnerService extends Service {
      
             @Override
             public int onStartCommand(Intent intent, int flags, int startId) {
      
                 startForeground(GRAY_SERVICE_ID, new Notification());
                 stopForeground(true);
                 stopSelf();
                 return super.onStartCommand(intent, flags, startId);
             }
      
             ...
         }
      }
      

      三、黑色保活(耍流氓)

    • 系统广播保活:比如开机(4.0以上系统已经屏蔽)、拍照(5.0以上系统已经屏蔽)、网络切换等 – Google一直在屏蔽的路上,我们一直在反屏蔽!

    • 多进程互相守护:
      |– 将Service在另一个进程中启动(配置process) 监听应用是否还存活,没有存活就启动 (监听的方式有轮询、socket心跳等)
      |– 利用c语言,fork一个linux进程,监听
      |– sdk唤醒,比如集成了腾讯的sdk,那sdk里面有一段程序,会去检测腾讯自家的应用是否还存活,没有存活就激活

      |-- 更可耻的 多家企业联合,互相激活,比如百度系的激活淘宝 淘宝系的激活百度等等
      

    四、白名单(超级流氓)

    • 以上所有的方式,都无法做到绝对的保活,那怎么做到绝对保活呢?
      |– 告诉底层系统不要杀自己,即使被认为的杀死了,底层系统也会帮忙再次启动;告诉三方的卫士软件,不要主动去杀死自己,怎么做到呢?
      |– 白名单 白名单 白名单(只有有实力的大企业能够做到)

    最后,再强调一遍,作为一个Android开发人员,应该保护Android开发环境不被一些无耻的行为累赘,所以不要去做应用保活这种可耻的事情!!!

    展开全文
  • App保活

    2017-07-20 10:13:00
    为什么80%的码农都做不了架构师?>>> ...

    查看App是否保活成功:https://my.oschina.net/huiyun/blog/1476143

    主要思路: 主要是两个service的相互绑定,以及对链接状态的监听,一旦断开就重新启动和绑定。

    1. 通过Activity发送一个广播(OneReceiver),通过广播OneReceiver启动一个Service(MyService)
    2. 在MyService的onCreate()方法中初始化链接监听类【在Service里写一个类继承接口ServiceConnection,并在方法onServiceDisconnected()中启动OtherService并且与之绑定】
      
    3.  在MyService的onStartCommand()方法绑定OtherService,并写一个Notification,用startForeground()方法启动在通知栏,即提高该Service的优先级。
      
    4.  再创建一个OtherService(就是之前提到的),逻辑与MyService相同,唯一的不同就是在AndroidManifest.xml文件中注册时应将该服务现在另外的进程中,防止该App被kill时连带着OtherService也被kill,这样就无法实现相互唤醒了。
      

    下面是主要的代码: MainActivity的代码:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            sendBroadcast(new Intent(this,MyReceiver.class));
        }
    }
    

    MyReceiver的代码:

    public class MyReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            Intent intent1 = new Intent(context,MyService.class);
            context.startService(intent1);
        }
    }
    

    MyService的代码:

    public class MyService extends Service {
        private MyServiceConnection connection;
        private MyBinder binder;
        private PendingIntent pendingIntent;
    
        public MyService() {
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            connection = new MyServiceConnection();
            if (binder == null) {
                binder = new MyBinder();
            }
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            startService(new Intent(MyService.this, OtherService.class));
            bindService(new Intent(MyService.this, OtherService.class), connection, Context.BIND_IMPORTANT);
            //根据具体的项目需求改判断,这里假设是判断App是否
            if (isAppRunning()) {
                Intent main = new Intent(MyService.this,MainActivity.class);
                startActivity(main);
            }
            intent = new Intent(MyService.this, OtherReceiver.class);
            pendingIntent = PendingIntent.getBroadcast(MyService.this, 0, intent, 0);
            Notification notification = new NotificationCompat.Builder(MyService.this)
                    .setContentTitle("MyService提示:")
                    .setContentText("MyService 的内容。。。。")
                    .setContentIntent(pendingIntent)
                    .setAutoCancel(false)
                    .build();
            startForeground(startId, notification);
            return START_STICKY;
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return binder;
        }
    
        class MyBinder extends Binder {
        }
    
        class MyServiceConnection implements ServiceConnection {
    
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                Log.d("SaveApp", "MyServiceConnection : Connected");
            }
    
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                Log.d("SaveApp", "MyServiceConnection : Disconnected");
                MyService.this.startService(new Intent(MyService.this,OtherService.class));
                MyService.this.bindService(new Intent(MyService.this,OtherService.class),connection,Context.BIND_IMPORTANT);
            }
        }
    
        public boolean isAppRunning() {
            ActivityManager am = (ActivityManager) getApplication().getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(100);
            for (ActivityManager.RunningTaskInfo info : list) {
                if (info.topActivity.getPackageName().equals("demo.jhc.cn.jpush") && info.baseActivity.getPackageName().equals("demo.jhc.cn.jpush")) {
                    return true;
                }
            }
            return false;
        }
    }
    
    

    OtherService的代码:

    public class OtherService extends Service {
        private OtherBinder binder;
        private OtherServiceConnection connection;
        private PendingIntent pendingIntent;
    
        public OtherService() {
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            connection = new OtherServiceConnection();
            if (binder == null) {
                binder = new OtherBinder();
            }
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            bindService(new Intent(OtherService.this, MyService.class), connection, Context.BIND_IMPORTANT);
            if (isAppRunning()) {
                intent = new Intent(OtherService.this, MainActivity.class);
            }
            pendingIntent = PendingIntent.getBroadcast(OtherService.this, 0, intent, 0);
            Notification notification = new NotificationCompat
                    .Builder(this)
                    .setContentTitle("OtherService title")
                    .setContentText("OtherService content")
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setAutoCancel(true)
                    .setContentIntent(pendingIntent)
                    .build();
            notification.flags |=  Notification.FLAG_NO_CLEAR;
            startForeground(startId, notification);
            return START_STICKY;
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return binder;
        }
    
        class OtherBinder extends Binder {
        }
    
        class OtherServiceConnection implements ServiceConnection {
    
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                Log.d("SaveApp", "MyServiceConnection : Connected");
            }
    
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                Log.d("SaveApp", "MyServiceConnection : Disconnected");
                OtherService.this.startService(new Intent(OtherService.this,MyService.class));
                OtherService.this.bindService(new Intent(OtherService.this,MyService.class),connection,Context.BIND_IMPORTANT);
            }
        }
    
    

    OtherReceiver的代码:

    public class OtherReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context,"Other Receiver : 模拟Jpush接收器",Toast.LENGTH_SHORT).show();
        }
    }
    

    转载于:https://my.oschina.net/huiyun/blog/1476079

    展开全文
  • app保活Module包

    2020-10-09 19:44:06
    倚赖包,按照教程配合使用。包你3分钟实现app保活!方法简单易懂,好实现,最小化也可唤起,强杀也可唤起。效果惊人
  • 该demo整体采用MVP的框架,运用了双进程守护进行了app保活,使其在锁屏状态下仍然能够读取短信
  • Android APP 保活

    2019-08-27 16:36:00
    第一 :启动系统任务 @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sports); // 2....
    第一 :启动系统任务
     @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_sports);
    
            // 2. 启动系统任务
            mJobManager = JobSchedulerManager.getJobSchedulerInstance(this);
            mJobManager.startJobScheduler();
    
        }

     

    系统任务:
    import android.annotation.TargetApi;
    import android.app.job.JobInfo;
    import android.app.job.JobScheduler;
    import android.content.ComponentName;
    import android.content.Context;
    import android.os.Build;
    
    import com.jiangdg.keepappalive.service.AliveJobService;
    
    /**JobScheduler管理类,单例模式
     * 执行系统任务
     *
     * Created by jianddongguo on 2017/7/10.
     * http://blog.csdn.net/andrexpert
     */
    
    public class JobSchedulerManager {
        private static final int JOB_ID = 1;
        private static JobSchedulerManager mJobManager;
        private JobScheduler mJobScheduler;
        private static Context mContext;
    
        private JobSchedulerManager(Context ctxt){
            this.mContext = ctxt;
            mJobScheduler = (JobScheduler)ctxt.getSystemService(Context.JOB_SCHEDULER_SERVICE);
        }
    
        public final static JobSchedulerManager getJobSchedulerInstance(Context ctxt){
            if(mJobManager == null){
                mJobManager = new JobSchedulerManager(ctxt);
            }
            return mJobManager;
        }
    
        @TargetApi(21)
        public void startJobScheduler(){
            // 如果JobService已经启动或API<21,返回
            if(AliveJobService.isJobServiceAlive() || isBelowLOLLIPOP()){
                return;
            }
            // 构建JobInfo对象,传递给JobSchedulerService
            JobInfo.Builder builder = new JobInfo.Builder(JOB_ID,new ComponentName(mContext, AliveJobService.class));
            // 设置每2秒执行一下任务
            builder.setPeriodic(3000);
            // 设置设备重启时,执行该任务
            builder.setPersisted(true);
            // 当插入充电器,执行该任务
            builder.setRequiresCharging(true);
            JobInfo info = builder.build();
            //开始定时执行该系统任务
            mJobScheduler.schedule(info);
        }
    
        @TargetApi(21)
        public void stopJobScheduler(){
            if(isBelowLOLLIPOP())
                return;
            mJobScheduler.cancelAll();
        }
    
        private boolean isBelowLOLLIPOP(){
            // API< 21
            return Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP;
        }
    }

    保活Service :Contants.PACKAGE_NAME 为保活APP的包名

    import android.annotation.TargetApi;
    import android.app.Service;
    import android.app.job.JobParameters;
    import android.app.job.JobService;
    import android.content.Intent;
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    import android.widget.Toast;
    
    import com.jiangdg.keepappalive.SportsActivity;
    import com.jiangdg.keepappalive.utils.Contants;
    import com.jiangdg.keepappalive.utils.SystemUtils;
    
    /**JobService,支持5.0以上forcestop依然有效
     *
     * Created by jianddongguo on 2017/7/10.
     */
    @TargetApi(21)
    public class AliveJobService extends JobService {
        private final static String TAG = "KeepAliveService";
        // 告知编译器,这个变量不能被优化
        private volatile static Service mKeepAliveService = null;
    
        public static boolean isJobServiceAlive(){
            return mKeepAliveService != null;
        }
    
        private static final int MESSAGE_ID_TASK = 0x01;
    
        private Handler mHandler = new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                // 具体任务逻辑
                if(SystemUtils.isAPPALive(getApplicationContext(), Contants.PACKAGE_NAME)){
                    Toast.makeText(getApplicationContext(), "APP活着的", Toast.LENGTH_SHORT)
                            .show();
                }else{
                    Intent intent = new Intent(getApplicationContext(), SportsActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                    Toast.makeText(getApplicationContext(), "APP被杀死,重启...", Toast.LENGTH_SHORT)
                            .show();
                }
                // 通知系统任务执行结束
                jobFinished( (JobParameters) msg.obj, false );
                return true;
            }
        });
    
        @Override
        public boolean onStartJob(JobParameters params) {
            if(Contants.DEBUG)
                Log.d(TAG,"KeepAliveService----->JobService服务被启动...");
            mKeepAliveService = this;
            // 返回false,系统假设这个方法返回时任务已经执行完毕;
            // 返回true,系统假定这个任务正要被执行
            Message msg = Message.obtain(mHandler, MESSAGE_ID_TASK, params);
            mHandler.sendMessage(msg);
            return true;
        }
    
        @Override
        public boolean onStopJob(JobParameters params) {
            mHandler.removeMessages(MESSAGE_ID_TASK);
            if(Contants.DEBUG)
                Log.d(TAG,"KeepAliveService----->JobService服务被关闭");
            return false;
        }
    }

    工具类

    **工具类
     *
     * Created by jianddongguo on 2017/7/10.
     * http://blog.csdn.net/andrexpert
     */
    
    public class SystemUtils {
    
        /**
         * 判断本应用是否存活
         * 如果需要判断本应用是否在后台还是前台用getRunningTask
         * */
        public static boolean isAPPALive(Context mContext,String packageName){
            boolean isAPPRunning = false;
            // 获取activity管理对象
            ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
            // 获取所有正在运行的app
            List<ActivityManager.RunningAppProcessInfo> appProcessInfoList = activityManager.getRunningAppProcesses();
            // 遍历,进程名即包名
            for(ActivityManager.RunningAppProcessInfo appInfo : appProcessInfoList){
                if(packageName.equals(appInfo.processName)){
                    isAPPRunning = true;
                    break;
                }
            }
            return isAPPRunning;
        }
    }

    配置文件中:

    <service
        android:name=".service.AliveJobService"
        android:permission="android.permission.BIND_JOB_SERVICE"/>

     

    原理:

    APP复活方案探讨和实践

     


    JobScheduler是谷歌在Android 5.0引入的一个能够执行某项任务的API,它允许APP在将来达到一定条件时执行指定的任务。通常情况下,即使APP被强制停止,预定的任务仍然会被执行。

    JobScheduler工作原理:

    首先在一个实现了JobService的子类的onStartJob方法中执行这项任务,使用JobInfo的Builder方法来设定条件并和实现了JobService的子类的组件名绑定,然后调用系统服务JobScheduler的schedule方法。这样,即便在执行任务之前应用程序进程被杀,也不会导致任务不会执行,因为系统服务JobScheduler会使用bindServiceAsUser的方法把实现了JobService的子类服务启动起来,并执行它的onStartJob方法。

     

     

     

    展开全文
  • 大部分手机在App灭屏的状态下就会把App睡眠了,这样是推送不了短信的,用户不满意啊。后来发现播放音乐之类的灭屏也能播啊,那就假装咱也是音乐播放方应用吧。 1.Service的内容: import android.app....

    最近在做一个运动手环项目,需要不断的更新运动数据,并且在灭屏的状态下给用户推送来电和短信。大部分手机在App灭屏的状态下就会把App睡眠了,这样是推送不了短信的,用户不满意啊。后来发现播放音乐之类的灭屏也能播啊,那就假装咱也是音乐播放方应用吧。

    1.Service的内容:

    import android.app.ActivityManager;
    import android.app.Notification;
    import android.app.PendingIntent;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.media.MediaPlayer;
    import android.os.IBinder;
    import android.support.annotation.Nullable;
    import android.util.Log;
    
    import com.smile.android.wristbanddemo.MainActivity;
    import com.smile.android.wristbanddemo.R;
    
    import java.util.List;
    
    /**
     * 描述:
     * 保活
     * @author sxk
     * @date 2019/05/14
     */
    
    public class LiveService2 extends Service {
        private final static String TAG = "PlayerMusicService";
        private MediaPlayer mMediaPlayer;
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
    //        throw new UnsupportedOperationException("Not yet implemented");
            return null;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            Log.d(TAG, TAG + "---->onCreate,启动服务");
            mMediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.no_notice);
            mMediaPlayer.setLooping(true);
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
    
            //1.通知栏占用,不清楚的看官网或者音乐类APP的效果
            Intent notificationIntent = new Intent(this, MainActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                    notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    
            Notification notification = new Notification.Builder(this)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setWhen(System.currentTimeMillis())
                    .setTicker("Keep App alive")
                    .setContentTitle("Keep "+getResources().getString(R.string.app_name)+" alive.")
                    .setOngoing(true)
                    .setPriority(Notification.PRIORITY_MAX)
                    .setContentIntent(pendingIntent)
                    .setAutoCancel(false)
                    .build();
            /*使用startForeground,如果id为0,那么notification将不会显示*/
            startForeground(100, notification);
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    startPlayMusic();
                }
            }).start();
            return START_STICKY;
        }
    
        private void startPlayMusic() {
            if (mMediaPlayer != null) {
                Log.d(TAG, "启动后台播放音乐");
                mMediaPlayer.start();
            }
        }
    
        private void stopPlayMusic() {
            if (mMediaPlayer != null) {
                Log.d(TAG, "关闭后台播放音乐");
                mMediaPlayer.stop();
            }
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            stopPlayMusic();
            Log.d(TAG, TAG + "---->onCreate,停止服务");
            // 重启
            Intent intent = new Intent(getApplicationContext(), LiveService2.class);
            startService(intent);
        }
    
        // 服务是否运行
        public boolean isServiceRunning(Context context, String serviceName) {
            boolean isRunning = false;
            ActivityManager am = (ActivityManager) this
                    .getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningAppProcessInfo> lists = am.getRunningAppProcesses();
    
    
            for (ActivityManager.RunningAppProcessInfo info : lists) {// 获取运行服务再启动
                System.out.println(info.processName);
                if (info.processName.equals(serviceName)) {
                    isRunning = true;
                }
            }
            return isRunning;
    
        }
    }
    

    2.AndroidManifest.xml中注册service:

    <service
                android:name=".LiveService2"
                android:enabled="true"
                android:priority="1000"
                android:exported="true"
                android:process=":keepalive2"/>

    3.启动service

    Intent intent = new Intent(this, LiveService2.class);
    if (Build.VERSION.SDK_INT>=26) {
        startForegroundService(intent);
    }else startService(intent);

     

    展开全文
  • Android之APP保活

    千次阅读 2019-01-09 14:55:37
    强烈建议不要这么做,不仅仅从用户角度考虑,它只会滋生更多的流氓应用,拖垮Android 平台的流畅性(假如你手机里装了支付宝、淘宝、天猫、UC等阿里系的app,那么你打开任意一个阿里系的app后,有可能就顺便把其他...
  • Android App保活实践

    千次阅读 2019-08-09 10:35:21
    1、前台服务 package ... import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.Service; import android.co...
  • App保活攻防仗

    2018-02-08 16:08:36
    五一小长假,老板特意让我去研究下Andorid黑屏如何保证app不被杀掉。 一、为什么要保活保活的源头是因为我们希望自己的进程或服务能够一直在后台运行,但是总有各种各样的原因导致我们希望破灭。 失活的...
  • android APP保活机制

    2018-03-19 11:53:22
    摘要: 需要APP暗屏情况下进行后台执行一些任务,但是google现在为了优化手机的体验,以及流畅性,做了很多的限制,电量优化,休眠模式,以及进入深度睡眠状态,进入深入休眠状态系统会根据...
  • 查看App保活是否成功

    2017-07-20 10:58:00
    为什么80%的码农都做不了架构师?>>> ...
  • 公司需要对安卓播放机上的播放软件进行意外退出自动保活,除了添加崩溃自启外,还使用了JobService进行定时检测软件是否正常运行。不正常则自动启动。这里做个记录.。 安卓播放机 的安卓版本为7.1.2。 先是...
  • 使用WorkManager保活,即使应用被杀掉,也是可以继续执行代码的,目前运行环境是模拟器,具体国内各厂商能否执行,未经过实际测试,就不说了。 我们首先定义Worker类,用来发送通知,然后点击通知可以打开Activity,...
  • 闲话说到这里,下面我介绍一种新的 App 保活方式哈,目前用小米家族手机 涵盖 Android 5.0 到 Android 8.1家族的测试。结论是,不主动干掉,是死不了的。但是主动干掉了,是活不了的。 之前介绍介绍了 双进程保活,...
  • 双进程守护APP保活方案

    千次阅读 2018-07-19 17:32:21
    原地址:http://blog.csdn.net/andrexpert/article/details/53485360 探讨一种新型的双进程守护应用保活方法(转载请声明出处:http://blog.csdn.net/andrexpert/article/details/...
  • 链接:https://segmentfault.com/a/1190000006251859
  • 03.app保活解决方案

    2018-04-25 13:55:00
    最近针对我们项目中app经常收不到推送的问题作了一些处理,增加app保活管理。我们知道当安卓进程退到后台之后,很容易被系统杀死,这个时候推送消息一般都是收不到的。我也观察了一些比较主流的app,像同花顺,钉钉...
  • Android开发中,令人头疼的保活问题始终缠绕每一个开发者。如何保证自己的进程不被系统回收呢?首当其冲应该是保证自己进程的优先级。 Android系统在运行时,如果遭遇到内存过低,为保证系统稳定与流畅,会回收一...
  • android 7 JobScheduler实现APP保活

    千次阅读 2018-05-21 09:57:41
    JobScheduler:当一系列预置的条件被满足时,JobScheduler API为你的应用执行一个操作,例如当设备接通电源适配器或者连接到WIFI,在API 21 ( Android 5.0(Lollipop) )中,google提供了一个新叫做JobScheduler API的...

空空如也

1 2 3 4 5 ... 20
收藏数 407
精华内容 162
关键字:

app保活