项目开发过程中需要实现重启App的功能
方式一:利用IntentService实现APP重启,用完即走
IntentService
IntentService,可以看做是Service和HandlerThread的结合体,在完成了使命之后会自动停止,适合需要在工作线程处理UI无关任务的场景。
- IntentService 是继承自 Service 并处理异步请求的一个类,在 IntentService 内有一个工作线程来处理耗时操作。
- 当任务执行完后,IntentService 会自动停止,不需要我们去手动结束。
- 如果启动 IntentService 多次,那么每一个耗时操作会以工作队列的方式在 IntentService 的 onHandleIntent 回调方法中执行,依次去执行,使用串行的方式,执行完自动结束。
下面看实现类代码
public class RestartIntentService extends IntentService {
private static long stopDelayed = 2000;
private Handler mHandler;
private String PackageName;
public RestartIntentService(){
super("RestartIntentService");
mHandler = new Handler();
}
public static void start(Context context,long Delayed) {
Intent intent = new Intent(context, RestartIntentService.class);
intent.putExtra("PackageName",context.getPackageName());
intent.putExtra("Delayed",Delayed);
context.startService(intent);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
stopDelayed = intent.getLongExtra("Delayed",2000);
PackageName = intent.getStringExtra("PackageName");
mHandler.postDelayed(() -> {
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(PackageName);
startActivity(launchIntent);
LogUtil.d("重启APP成功,包名:"+PackageName);
},stopDelayed);
}
/**
* 重启APP
* @param context˛
*/
public static void restartAPP(Context context){
start(context,1500);
}
@Override
public void onDestroy() {
super.onDestroy();
if (mHandler!=null){
mHandler = null;
}
}
}
然后在AndroidManifest.xml清单文件注册,并添加在独立进程中(不添加系统杀死后无法重启Syetem.exit(0) )
<service android:name=".RestartIntentService"
android:process=":restart"/>
调用
RestartIntentService.restartAPP(this);
方式二:利用Service服务重启,方式跟IntentService差不多,但这种需要在操作完时自行把服务杀死
Service四大组件之一
- 定义、特点:
Service是可以在后台执行长时间(长生命周期)而又不与用户产生UI交互(没有用户界面)的操作。
- 注意事项:
1、只能在后台运行,即便用户切换了其他应用,启动的Service仍可在后台运行。
2、可以和其他组件进行Service绑定并与之交互,甚至是跨进程通信(IPC)。
3、不能运行在一个独立的进程当中,而是依赖与创建服务时所在的应用组件进程。
4、服务不会自动开启线程,我们需要在服务的内部手动创建子线程,并在这里执行具体的任务。
- 应用场景举例:
音乐播放:播放多媒体的时候用户启动了其他Activity,此时要在后台继续播放。
记录检测:比如检测SD卡上文件的变化;在后台记录你的地理信息位置的改变等。
其他操作:网络请求、执行文件读写操作或者与 content provider交互。
-
类型:
本地服务与远程服务本地服务依附在主进程上,在一定程度上节约了资源。本地服务因为是在同一进程,因此不需要IPC,也不需要AIDL。相应bindService会方便很多。缺点是主进程被kill后,服务变会终止。
远程服务是独立的进程,对应进程名格式为所在包名加上你指定的android:process字符串。由于是独立的进程,因此在Activity所在进程被kill的是偶,该服务依然在运行。缺点是该服务是独立的进程,会占用一定资源,并且使用AIDL进行IPC稍微麻烦一点。本文第六部分将会简单的讲述这一进程间通信方式。
对于startService来说,不管是本地服务还是远程服务,我们需要做的工作都一样简单
下面看实现代码
/*
* Description:该服务只用来让APP重启,重启完即自我自杀,服务需在独立进程
*/
public class KillSelfService extends Service {
private static long stopDelayed = 2000;
private Handler mHandler;
private String PackageName;
public KillSelfService(){
mHandler = new Handler();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
stopDelayed = intent.getLongExtra("Delayed",2000);
PackageName = intent.getStringExtra("PackageName");
mHandler.postDelayed(() -> {
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(PackageName);
startActivity(launchIntent);
LogUtil.d("重启APP服务成功");
KillSelfService.this.stopSelf();
},stopDelayed);
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
/*
* Description:此工具类用来重启APP,只是单纯的重启,不做任何处理。
*/
public class RestartAPPTool {
/**
* 重启APP服务
* @param context
* @param Delayed 延迟多少秒
*/
public static void restartApp(Context context,long Delayed){
Intent intent = new Intent(context,KillSelfService.class);
intent.putExtra("PackageName",context.getPackageName());
intent.putExtra("Delayed",Delayed);
LogUtil.d("启动重启KillSelfService服务");
context.startService(intent);
}
/**
* 重启APP
* @param context˛
*/
public static void restartAPP(Context context){
restartApp(context,1500);
}
}
在AndroidManifest.xml清单文件注册
<service android:name=".KillSelfService"
android:process=":restart"/>
Activity中调用
RestartAPPTool.restartAPP(this);
参考:
android比较便捷的重启APP的方法
android Process.killProcess 和 System.exit(0) 区别