我正在研究一个需要在所有情况下都能继续运行的多进程企业VOIP应用程序。话虽如此,我们都知道应用程序可能崩溃,并且有许多崩溃恢复选项,以便我的最终用户不受影响(错过电话)。
我已经对我的所有选项进行了大量的研究和测试,以防止用户等应用程序崩溃/强制停止,并确定了以下内容:
停止申请
在Android 3.1中,引入了已停止的应用程序包的概念。 Android仅定义了应用程序包处于“已停止”状态的两种情况:
应用程序在首次安装但尚未启动时以及用户手动停止时(在“管理应用程序”中)处于停止状态。 http://developer.android.com/about/versions/android-3.1.html
请注意,这并未指定应用程序崩溃及其行为方式。
GCM
在支持它的设备上,我可以依赖Google的GCM,以便在应用程序崩溃的情况下可靠地启动我的应用程序。这是通过指定接收器的清单来完成的:
<receiver
android:name=".receiver.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
</intent-filter>
</receiver>
这似乎是100%可靠的,如果我在我的应用程序中触发崩溃,即使在多次崩溃后也会重新启动我的主进程。
服务START_STICKY
不幸的是,我需要支持没有安装Play服务的设备,我不能依靠GCM来安装此设备。在这种情况下,我从我的服务的onSTartComment返回了Service.START_STICKY。根据Android doc,此响应指定:
从onStartCommand(Intent,int,int)返回的常量:如果此服务的进程在启动时被终止(从onStartCommand(Intent,int,int)返回后),则将其保持在启动状态但不要保留这个交付的意图。稍后系统将尝试重新创建服务。 http://developer.android.com/reference/android/app/Service.html#START_STICKY
这对我有部分帮助,因为当我在我的应用程序中触发崩溃时,操作系统将在一段未知时间后(通常在20秒左右)重新启动我的应用程序。但是,它似乎只会重新启动我的应用一次,并且在后续崩溃后我的应用程序没有重新启动。无论我们使用什么门槛,似乎都没有记录在任何地方,但我猜它是以防止不断崩溃的应用程序反复运行。有什么细节?
看门狗定时器 我最后一次尝试解决我的问题是创建一个看门狗定时器,它会触发与上面列出的GCM相同的接收器。由于我已经在一个单独的进程中运行了一个服务,我想我可以检测主应用程序中的崩溃,并安排向我的清单中注册的接收器广播并解决我的问题。
应用程序崩溃后从服务执行的代码:
final Handler handler = new Handler();
Runnable r = new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "Sending broadcast", Toast.LENGTH_SHORT).show();
Intent intentNew = new Intent("GCMBroadcast");
intentNew.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
sendBroadcast(intentNew);
handler.postDelayed(this, 10000);
}
};
handler.postDelayed(r, 10000);
在接收器的清单中定义:
<intent-filter>
<action android:name="GCMBroadcast"/>
</intent-filter>
你会注意到我甚至指定了包含已停止包的标志。此代码在第一次崩溃后正常工作,我的接收器被触发,我的主进程恢复了生命。然而,就像上面一样,在第二次崩溃后我的应用程序已经死了。从接收器中的日志语句和发送看门狗意图所呈现的吐司,我知道继续发送意图,接收器在第二次崩溃后根本不接收广播。
我的问题 我上面有什么问题吗?显然,首要任务是消除我的应用程序崩溃,但是还有其他我可以依赖的后备吗?
如果它们通常崩溃,Android会将“坏”应用程序置于停止状态吗?如果是这样,这些门槛是多少?如果它不是我可以编写代码的东西,我至少需要记录对我的应用程序的影响。显然,当我在我的应用程序中触发崩溃以测试此工作流程时,我在30秒左右的时间内崩溃了2次。
FLAG_INCLUDE_STOPPED_PACKAGES的实际意图是什么?在这种情况下,它似乎并没有真正帮助我,我认为它不会对刚刚安装但尚未被用户启动的应用程序产生任何影响。
同样,这是一个关键任务应用程序,无论发生什么应用程序崩溃,都需要运行和连接服务。