Android:如何在“强制关闭”后自动重启应用程序?
Posted
技术标签:
【中文标题】Android:如何在“强制关闭”后自动重启应用程序?【英文标题】:Android: How to auto-restart an application after it has been "force closed"? 【发布时间】:2011-02-10 12:14:13 【问题描述】:在 android 应用程序中,如果我们没有正确处理异常,我们通常会收到“强制关闭”错误。
如果我的应用程序被强制关闭,如何自动重启?
是否为此使用了任何特定权限?
【问题讨论】:
尝试正确处理异常。自动重启的应用程序可能会让用户感到厌烦。 如果我的应用程序崩溃了,我只想重新启动它。我认为它会比烦人更友好,尤其是当用户在我的应用程序中时。是的,我正在努力纠正每个例外情况。 :) @Johnny : 请分享您的问题的解决方案。 检查 this article 以在出现任何异常时重新启动您的应用程序。 【参考方案1】:要做到这一点,你必须做两件事:
-
避免“强制关闭” - 应用程序崩溃的标准方式。
在崩溃发生时设置重启机制。
请参阅下面的操作方法:
调用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()
方法中显示一个对话框“对不起,应用程序崩溃了,希望再也不会 :)”。
【讨论】:
我想通了。现在的问题是在哪里实现 uncaughtException 方法?请帮忙。谢谢。 @MayuMayooresan 您可以扩展应用程序类或 Activity 并在 onCreate() 中执行以下操作: Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler()...); 如果您扩展活动,值得注意的是,您需要对每个可以充当应用程序入口点的活动(包括 Android 操作系统可能决定启动的活动 - 例如当窗口死亡等) 通过管理应用程序菜单强制停止进程后,它似乎在 ICS 中不起作用。 YourApplication 是什么意思?我使用了@Mahesh 的建议,但没有奏效。请有人解释一下。【参考方案2】:诀窍是首先确保它不会强制关闭。
如果您使用the Thread.setDefaultUncaughtExceptionHandler()
method,您可以捕获导致您的应用程序强制关闭的异常。
查看at this question 以获取使用UncaughtExceptionHandler
记录应用程序引发的异常的示例。
【讨论】:
感谢您的提示。一个后续问题是何时调用 UncaughtExceptionHandler.uncaughtException?如果用户没有点击“强制关闭”按钮,UncaughtExceptionHandler.uncaughtException 还会被调用吗? @Johnny 当应用程序引发未处理的异常时,您将获得强制关闭。如果您使用 UncaughtExceptionHandler,那么您的应用程序可以处理其所有异常,并且用户将永远不会看到强制关闭对话框。换句话说,当将显示强制关闭对话框时调用 UncaughtExceptionHandler。但是,您需要小心处理应用程序捕获的任何意外异常;继续并假装什么都没发生显然是有风险的。 感谢您的解释。它很好地解释了 UncaughtExceptionHandler。但我见过强制关闭后会自动重启的应用程序。例如。启动器(也许不是一个很好的例子,但我已经看到第三方应用程序也以这种方式工作)。如果我希望我的应用程序像这样工作怎么办?我必须使用某种系统权限吗?【参考方案3】:如果您使用 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);
);
【讨论】:
【参考方案4】:只需在你的包中添加这个类
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);
在您的应用程序或每个活动类中,在 onCreate() 方法中,然后简单地调用:
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this,
SplashScreenActivity.class));
【讨论】:
【参考方案5】: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();
【讨论】:
此代码获取“Thread.setDefaultUncaughtExceptionHandler”并在关闭后调用..【参考方案6】:以下是对我有用的代码。你应该在MainActivity
的onCreate()
方法中调用appInitialization()
/*
* 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);
;
【讨论】:
感谢您提供答案。您能否编辑您的答案以包括对您的代码的解释?这将帮助未来的读者更好地理解正在发生的事情,尤其是那些不熟悉该语言并努力理解这些概念的社区成员。与 OP 的问题相关的关键线是什么?为什么它们比现有五个答案中的建议更受欢迎?以上是关于Android:如何在“强制关闭”后自动重启应用程序?的主要内容,如果未能解决你的问题,请参考以下文章