以前重启App的代码在Android 12(API 33),经过研究,以下代码可以实现重启App,新的方法更快更好用. 其它啥都不说了,详细请看代码注释,上代码.
java
package cn.kuncb.photograph.activity.main;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import androidx.activity.OnBackPressedCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.MenuProvider;
import cn.kuncb.photograph.R;
import cn.kuncb.photograph.databinding.ActivityRestartBinding;
/**
* androidx 使用最新的方法实现标题栏设置、菜单、重启App功能
*/
public class RestartActivity extends AppCompatActivity implements MenuProvider, View.OnClickListener {
/**
* 使用viewBinding,在模块build.gradle->android中添加buildFeatures { viewBinding true }
*/
ActivityRestartBinding mBind;
/**
* 重启app的Launcher
*/
ActivityResultLauncher<Intent> mRestartlauncher;
//region TODO:Activity重写的方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.mBind = ActivityRestartBinding.inflate(getLayoutInflater());
setContentView(this.mBind.getRoot());
this.mBind.button.setOnClickListener(this);
//region TODO:Activity响应back,如果是使用Fragment请在Fragment中处理,不要在Activity处理
getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
try {
//什么都不做表示屏蔽back键,也就是按下back键和标题栏上的返回按钮均没有任何响应
//finish();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
//endregion
//region TODO:设置标题\返回箭头\菜单,如果是使用Fragment请在Fragment中处理,Activity除非公共菜单,否则不做处理
setTitle("Restart application");//设置标题
//Fragment.setHasOptionsMenu(true);已经过时,不要再使用
ActionBar actionBar = getSupportActionBar();
if (null != actionBar)
actionBar.setDisplayHomeAsUpEnabled(false); //显示或关闭标题栏上的back按钮
addMenuProvider(this); //新版本增加菜单的方式,以前的添加菜单的方法已经过时
//endregion
}
@Override
protected void onStart() {
super.onStart();
//region TODO:注册回调的方法
/*
onActivityResult方法已经过时,因此建议不要使用startActivity或startActivityForResult方法启动Activity
请改用registerForActivityResult,registerForActivityResult必须在OnStart或之前的方法中调用,否则会抛出以下异常
IllegalStateException: LifecycleOwner cn.kuncb.xxx.activity.main.RestartActivity@4701fd0 is attempting to register while current state is STARTED. LifecycleOwners must call register before they are STARTED.
registerForActivityResult可以参看我的另一篇博客:https://blog.csdn.net/kmblack1/article/details/108781468
*/
this.mRestartlauncher = registerForActivityResult(new ActivityResultContract<Intent, Void>() {
@NonNull
@Override
public Intent createIntent(@NonNull Context context, Intent input) {
if (null == input) {
/**
* MainActivity.class是AndroidManifest->application->activity中的exported必须为true
*/
input = new Intent(context, MainActivity.class);
input.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
return input;
}
@Override
public Void parseResult(int resultCode, @Nullable Intent intent) {
return null;
}
}, result -> {
this.finish(); //关闭当前Activity,如果是在Fragment中重启使用:requireActivity().finish();
System.exit(0); //退出当前系统
});
//endregion
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
//endregion
//region TODO:Click
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
do {
this.mRestartlauncher.launch(null); //为方便使用intent在createIntent中创建
} while (false);
break;
}
}
//endregion
//region TODO:menu
@Override
public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) { //创建菜单
//如果需要创建菜单:menuInflater.inflate(R.menu.main, menu);
}
@Override
public void onPrepareMenu(@NonNull Menu menu) { //菜单弹出之前,一般不使用(如动态菜单项就在这个方法中修改)
//region TODO:显示菜单图标,菜单xml文件item中必须包含android:icon
// String name = menu.getClass().getSimpleName();
// if (name.equals("MenuBuilder")) {
// try {
// Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
// m.setAccessible(true);
// m.invoke(menu, true);
// } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// //Log.e(getClass().getSimpleName(), "onMenuOpened...unable to set icons for overflow menu", e);
// e.printStackTrace();
// }
// }
//endregion
//region TODO:动态菜单项,this.mThemeMode保存当前模式,如果是日间模式则菜单图标和文件显示为"夜间模式",反之显示"日间模式"
// MenuItem item = menu.findItem(R.id.menuMode);
// if (AppCompatDelegate.MODE_NIGHT_NO == this.mThemeMode) { //如果是日间模式
// item.setIcon(R.drawable.ic_baseline_nights_stay_24);
// item.setTitle(getString(R.string.NIGHT_MODE));
// } else { //夜间模式
// item.setIcon(R.drawable.ic_baseline_wb_sunny_24);
// item.setTitle(getString(R.string.DAY_MODE));
// }
//endregion
MenuProvider.super.onPrepareMenu(menu);
}
@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {//选择了菜单中的项
try {
int id = menuItem.getItemId();
switch (id) {
case android.R.id.home:
do {
this.onBackPressed(); //响应标题栏和back按键
} while (false);
break;
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
return false;
}
@Override
public void onMenuClosed(@NonNull Menu menu) {//菜单关闭后,一般不使用
MenuProvider.super.onMenuClosed(menu);
}
//endregion
}
layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:context=".activity.main.RestartActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="restart" />
</androidx.appcompat.widget.LinearLayoutCompat>