8

如果应用程序线程被任务管理器杀死,它就会关闭。需要重新调用应用程序,就好像它被其他应用程序或任务管理器杀死一样。任何想法?

4

5 回答 5

4

您必须使用 START_STICKY 命令运行后台服务。只需像这样扩展 Service 并覆盖 onCommand :

@Override
public int onStartCommand(Intent intent,int flags,int startId) {
    super.onStartCommand(intent, flags, startId);

    return START_STICKY;
}

像这样,您的服务在关闭时重新启动(通过系统或其他任何方式)

如果应用程序正在运行,您现在只需检查您的服务(例如 onCreate),如果没有,则再次启动它。我想 PackageManager 可以让您检查这一点,或者简单地放置一个静态布尔 is_alive 来查看您的活动是否一直在运行。

问候吉姆

于 2012-09-23T16:59:06.097 回答
3

带有 START_STICKY 的 Android 2.3 中的错误

我需要用我所有的力量来维持一个服务。如果服务随时运行,您可以弹出 UI。

onDestroy()

它将重新启动。

无法卸载该应用程序,因为它具有设备管理员。

这是一种家长控制,用户知道它就在那里。停止的唯一方法是删除设备管理员,然后将其卸载,但删除设备管理员会像卡巴斯基一样锁定手机。

有很多广播接收器,例如启动完成,用户呈现,屏幕开启,屏幕关闭......等等,所有启动服务,您也可以使用UI来完成。或者在服务中检查您的活动是否存在、可见,如果没有,则弹出它。

我希望您有充分的理由使用这些信息!

编辑:重新启动服务代码片段:

    // restart service:
    Context context = getApplicationContext();
    Intent myService = new Intent(context, MyService.class);
    context.startService(myService);

Edit2:添加 spippet 以检查服务是否正在运行...大量广播

   public static  boolean isMyServiceRunning(Context context) {
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (MyService.class.getName().equals(service.service.getClassName())) {
                Log.d("myTag", "true");
                return true;
            }
        }
        Log.d("myTag", "false");
        return false;
    }

Edit3 其他服务启动:

   public static void startTheService(Context context) {
         Intent myService = new Intent(context, MyService.class);
         context.startService(myService);
   }

不要忘记 Android 2.3 的错误:做初始化的逻辑

@Override
public void onCreate()

而不是:

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
于 2012-09-23T17:12:04.583 回答
2

在查看 Google IO 官方产品源代码时,我发现了以下内容

((AlarmManager) context.getSystemService(ALARM_SERVICE))
            .set(
                    AlarmManager.RTC,
                    System.currentTimeMillis() + jitterMillis,
                    PendingIntent.getBroadcast(
                            context,
                            0,
                            new Intent(context, TriggerSyncReceiver.class),
                            PendingIntent.FLAG_CANCEL_CURRENT));

代码网址

您可以启动一个粘性服务并注册一个警报管理器,该管理器将一次又一次地检查您的应用程序是否处于活动状态,如果没有,它将运行它。

您还可以制作一个接收器并注册它,<action android:name="android.intent.action.BOOT_COMPLETED" />然后您可以从您的接收器启动您的服务。我认为当操作系统或杀死某些服务/应用程序时应该有一些广播消息。

只是为了给你一个粗略的想法,我已经完成了这个及其工作 1)注册接收器接收器代码:

@Override public void onReceive(Context context, Intent intent) {

    try {
        this.mContext = context;
        startService(intent.getAction());

        uploadOnWifiConnected(intent);

    } catch (Exception ex) {
        Logger.logException(ex);
        Console.showToastDelegate(mContext, R.string.msg_service_starup_failure, Toast.LENGTH_LONG);
    }
}

private void startService(final String action) {
    if (action.equalsIgnoreCase(ACTION_BOOT)) {

        Util.startServiceSpawnProcessSingelton(mContext, mConnection);

    } else if (action.equalsIgnoreCase(ACTION_SHUTDOWN)) {

    }
}

服务代码:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    Logger.logInfo("Service Started onStartCommand");
    return Service.START_STICKY;
}

我更喜欢在 onStartCommand 中什么都不做,因为每次启动服务时都会调用它,但 onCreate 仅在第一次启动服务时被调用,所以我在 onCreate 中执行大部分代码,这样我就不再关心天气服务了跑步与否。

于 2012-09-25T07:51:02.630 回答
1

根据来自 Google 的 @RetoMeyer 的说法,解决方案是让应用程序“粘性”。

为此,您必须在您的意图服务管理中建立 START_STICKY。

从开发人员 android检查此参考

于 2012-09-26T21:37:18.770 回答
0

是的,一旦出现内存不足的问题,android os 就会开始杀死应用程序以补偿所需的内存。使用服务可以实现这一点,您的服务应该与您的应用程序并行运行,但是请注意,在某些情况下,甚至您的服务也会同时被终止。如果内存足够,则杀死后,android os 本身会尝试重新启动应用程序,但并非在所有情况下都如此。最后,在所有情况下,一旦被操作系统杀死,就没有硬性规定重新调用您的应用程序,这取决于操作系统和内部行为。

于 2012-09-13T06:40:51.523 回答