在Android应用程序中,如果我们没有得到正确的例外,我们通常会收到“强制关闭”错误。
如果应用程序强制关闭,如何自动重启我的应用程序?
是否有任何特定的权限用于此?
答案 0 :(得分:93)
要做到这一点,你必须做两件事:
请参阅以下内容:
调用Thread.setDefaultUncaughtExceptionHandler()
以捕获所有未捕获的异常,在这种情况下将调用uncaughtException()
方法。 “强制关闭”将不会出现,应用程序将无法响应,这不是一件好事。
为了在崩溃时重新启动应用程序,您应该执行以下操作:
在onCreate
方法中,在您的主要活动中初始化PendingIntent
成员:
Intent intent = PendingIntent.getActivity(
YourApplication.getInstance().getBaseContext(),
0,
new Intent(getIntent()),
getIntent().getFlags());
然后在您的uncaughtException()
方法中添加以下内容:
AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 2000, intent);
System.exit(2);
您还必须致电System.exit()
,否则将无效。
这样,您的应用程序将在2秒后重新启动。
最终,您可以在应用程序崩溃的意图中设置一些标记,并在onCreate()
方法中显示对话框“对不起,应用程序崩溃了,希望永远不会再次:)”。
答案 1 :(得分:17)
诀窍是确保它首先不会强制关闭。
如果您使用the Thread.setDefaultUncaughtExceptionHandler()
method,则可以捕获导致您的应用程序强制关闭的异常。
查看at this question,了解使用UncaughtExceptionHandler
记录应用程序引发的异常的示例。
答案 2 :(得分:8)
如果你使用Crittercism或其他一些错误报告服务,接受的答案几乎是正确的..
final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
public void uncaughtException(Thread thread, Throwable ex) {
Intent launchIntent = new Intent(activity().getIntent());
PendingIntent pending = PendingIntent.getActivity(CSApplication.getContext(), 0,
launchIntent, activity().getIntent().getFlags());
getAlarmManager().set(AlarmManager.RTC, System.currentTimeMillis() + 2000, pending);
defaultHandler.uncaughtException(thread, ex);
}
});
答案 3 :(得分:2)
public class ForceCloseExceptionHandalingActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setContentView(MyLayout());
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
myHandaling(paramThread, paramThrowable);
}
});
}
private ViewGroup MyLayout(){
LinearLayout mainLayout = new LinearLayout(this);
mainLayout.setOrientation(LinearLayout.VERTICAL);
Button btnHello =new Button(this);
btnHello.setText("Show all button");
btnHello.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setContentView(MyLayout2());
}
});
mainLayout.addView(btnHello);
return mainLayout;
}
private ViewGroup MyLayout2(){
LinearLayout mainLayout = new LinearLayout(this);
mainLayout.setOrientation(LinearLayout.VERTICAL);
Button btnHello =new Button(this);
btnHello.setText("I am a EEROR uncaughtException");
btnHello.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.e("Alert","btn uncaughtException::");
Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert uncaughtException222",Toast.LENGTH_LONG).show();
View buttone = null;
setContentView(buttone);
}
});
Button btnHello2 =new Button(this);
btnHello2.setText("I am a EEROR Try n catch");
btnHello2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try{
View buttone = null;
setContentView(buttone);
}
catch (Exception e) {
Log.e("Alert","Try n catch:::");
Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert Try n catch",Toast.LENGTH_LONG).show();
setContentView(MyLayout());
}
}
});
mainLayout.addView(btnHello);
mainLayout.addView(btnHello2);
return mainLayout;
}
public void myHandaling(Thread paramThread, Throwable paramThrowable){
Log.e("Alert","Lets See if it Works !!!" +"paramThread:::" +paramThread +"paramThrowable:::" +paramThrowable);
Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert uncaughtException111",Toast.LENGTH_LONG).show();
Intent in =new Intent(ForceCloseExceptionHandalingActivity.this,com.satya.ForceCloseExceptionHandaling.ForceCloseExceptionHandalingActivity.class);
startActivity(in);
finish();
android.os.Process.killProcess(android.os.Process.myPid());
}
@Override
protected void onDestroy() {
Log.e("Alert","onDestroy:::");
Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert onDestroy",Toast.LENGTH_LONG).show();
super.onDestroy();
}
答案 4 :(得分:1)
只需在包中添加此类
即可public class MyExceptionHandler implements
java.lang.Thread.UncaughtExceptionHandler {
private final Context myContext;
private final Class<?> myActivityClass;
public MyExceptionHandler(Context context, Class<?> c) {
myContext = context;
myActivityClass = c;
}
public void uncaughtException(Thread thread, Throwable exception) {
StringWriter stackTrace = new StringWriter();
exception.printStackTrace(new PrintWriter(stackTrace));
System.err.println(stackTrace);// You can use LogCat too
Intent intent = new Intent(myContext, myActivityClass);
String s = stackTrace.toString();
//you can use this String to know what caused the exception and in which Activity
intent.putExtra("uncaughtException", "Exception is: " + stackTrace.toString());
intent.putExtra("stacktrace", s);
myContext.startActivity(intent);
//for restarting the Activity
Process.killProcess(Process.myPid());
System.exit(0);
}}
然后简单地致电:
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this,
SplashScreenActivity.class));
答案 5 :(得分:0)
以下是对我有用的代码。您应该在 appInitialization()
onCreate()
方法中调用 MainActivity
/*
* App Restart on crash logic
* */
public void triggerRestart(Activity context) {
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
if (context instanceof Activity) {
finish();
}
Runtime.getRuntime().exit(0);
}
private void appInitialization() {
defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(_unCaughtExceptionHandler);
}
//make crash report on ex.stackreport
private Thread.UncaughtExceptionHandler defaultUEH;
// handler listener
private Thread.UncaughtExceptionHandler _unCaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
// You can code here to send crash analytics
ex.printStackTrace();
triggerRestart(currentActivity);
}
};