4、 onStartCommand 函数 START_NOT_STICKY 返回值
Service.START_NOT_STICKY : " 非粘性 " , onStartCommand 方法返回该返回值时 , 如果在执行 onStartCommand 后 , 服务被杀死 , 系统不会重启 Service 服务 ;
/** * Constant to return from {@link #onStartCommand}: if this service's * process is killed while it is started (after returning from * {@link #onStartCommand}), and there are no new start intents to * deliver to it, then take the service out of the started state and * don't recreate until a future explicit call to * {@link Context#startService Context.startService(Intent)}. The * service will not receive a {@link #onStartCommand(Intent, int, int)} * call with a null Intent because it will not be restarted if there * are no pending Intents to deliver. * * <p>This mode makes sense for things that want to do some work as a * result of being started, but can be stopped when under memory pressure * and will explicit start themselves again later to do more work. An * example of such a service would be one that polls for data from * a server: it could schedule an alarm to poll every N minutes by having * the alarm start its service. When its {@link #onStartCommand} is * called from the alarm, it schedules a new alarm for N minutes later, * and spawns a thread to do its networking. If its process is killed * while doing that check, the service will not be restarted until the * alarm goes off. */ public static final int START_NOT_STICKY = 2;
5、 onStartCommand 函数 START_REDELIVER_INTENT 返回值
Service.START_REDELIVER_INTENT : 重传 Intent ; onStartCommand 方法返回该返回值时 , 如果在执行 onStartCommand 后 , 服务被杀死 , 系统会自动重启 , 并传入 Intent 值 , 不会传入 null ;
/** * Constant to return from {@link #onStartCommand}: if this service's * process is killed while it is started (after returning from * {@link #onStartCommand}), then it will be scheduled for a restart * and the last delivered Intent re-delivered to it again via * {@link #onStartCommand}. This Intent will remain scheduled for * redelivery until the service calls {@link #stopSelf(int)} with the * start ID provided to {@link #onStartCommand}. The * service will not receive a {@link #onStartCommand(Intent, int, int)} * call with a null Intent because it will only be restarted if * it is not finished processing all Intents sent to it (and any such * pending events will be delivered at the point of restart). */ public static final int START_REDELIVER_INTENT = 3;
二、 系统 Service 机制拉活
根据上述 onStartCommand 方法返回值分析 , 只要返回值是 START_STICKY , 那么被杀掉的应用就会被重新拉起 ;
1、 Service 代码
package kim.hsl.keep_progress_alive.stick_service; import android.app.Service; import android.content.Intent; import android.os.IBinder; public class StickService extends Service { public StickService() { } @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } }
2、 清单配置
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="kim.hsl.keep_progress_alive"> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Keep_Progress_Alive"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 设置最近任务列表中不显示该 Activity 组件 ( 不要被用户察觉 ) android:excludeFromRecents="true" 设置 Activity 亲和性 让该界面在一个独立的任务栈中 , 不要与本应用的其它任务栈放在一起 避免解除锁屏后 , 关闭 1 像素界面 , 将整个任务栈都唤醒 android:taskAffinity="kim.hsl.keep_progress_alive.alive" --> <activity android:name=".one_pixel_activity.OnePixelActivity" android:excludeFromRecents="true" android:taskAffinity="kim.hsl.keep_progress_alive.onepixel" android:theme="@style/OnePixelActivityTheme" /> <!-- 用于提权的前台进程 --> <service android:name=".foreground_service.ForegroundService" android:enabled="true" android:exported="true" /> <!-- 用于提权的前台进程, 关闭通知操作 --> <service android:name=".foreground_service.CancelNotificationService" android:enabled="true" android:exported="true" /> <!-- 系统 Service 机制拉活 --> <service android:name=".stick_service.StickService" android:enabled="true" android:exported="true" /> </application> </manifest>
3、启动服务
package kim.hsl.keep_progress_alive; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import kim.hsl.keep_progress_alive.foreground_service.ForegroundService; import kim.hsl.keep_progress_alive.one_pixel_activity.KeepProgressAliveManager; import kim.hsl.keep_progress_alive.stick_service.StickService; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 1. 1 像素 Activity 提升应用权限 // 注册广播接收者 , 1 像素 Activity 启动的 广播接收者 //KeepProgressAliveManager.getmInstance().registerReceiver(this); // 2. 通过前台 Service 提升应用权限 // 启动普通 Service , 但是在该 Service 的 onCreate 方法中执行了 startForeground // 变成了前台 Service 服务 //startService(new Intent(this, ForegroundService.class)); // 3. 使用 Service 机制拉活 startService(new Intent(this, StickService.class)); } @Override protected void onDestroy() { super.onDestroy(); // 1. 取消注册广播接收者, 也可以不取消注册 //KeepProgressAliveManager.getmInstance().registerReceiver(this); } }