为什么后台服务在运行时会停止?

时间:2013-05-13 04:09:09

标签: android android-service background-process

我在我的android应用程序中有一个后台服务。其中一个线程监听最近经常运行的任务。我的服务会覆盖onCreate()onStartCommand()方法。当我尝试打开某些应用程序,例如GalleryCamera等等时,服务将停止。它仅调用onCreate()方法,而不是onDestroy()或{{ 1}}。我试图在这个服务中覆盖onLowMemory(),但它没有记录任何内容。通过指定

内部保存的应用程序
onStartCommand()
清单文件中的

注意:此问题在 android:installLocation="internalOnly" 注意到。

为什么后台服务有时停止?这个问题有什么解决方案吗?

Micromax A54 2.3.5

然后像这样启动服务

public class MyService extends Service {

    public MyService() {
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        try {
            if(intent != null){
                //......
            }
        } catch (Throwable e) {
        }
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        //......
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


}

4 个答案:

答案 0 :(得分:2)

Android可以出于任何原因随时停止任何服务。一个典型的原因是内存不足(杀死服务以在其他地方提供内存),但我已经看到至少有一些设备每X小时就会杀死它们,无论如何。没有办法确保你总是跑步。您可以做的最好的事情是让您的所有活动都尝试启动您的服务(如果它没有运行),编写您的服务以便重新加载所需的数据,并将自己设置为START_STICKY,这样如果它有足够的内存,框架将重新启动你以后。

答案 1 :(得分:1)

Android在内存需要时停止服务。你可以使用

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    try {
        if(intent != null){
            //......
        }
    } catch (Throwable e) {
    }
    return START_REDELIVER_INTENT;
}

START_REDELIVER_INTENT可以使用。如果此服务的进程在启动时被终止(从onStartCommand(Intent, int, int))返回后,它将被安排重新启动并且最后一次传递的Intent重新传递给它再次通过onStartCommand(Intent, int, int)

答案 2 :(得分:0)

我遇到了同样的问题。在某些设备上,Android会杀死我的服务,甚至startForeground()也无济于事。我的客户不喜欢这个问题。

我使用SharedPreferences来保持标志服务是否应该运行。 我还使用AlarmManager来创建一种看门狗定时器。它会不时检查服务是否应该运行并重新启动它。

创建/取消我的看门狗定时器:

void setServiceWatchdogTimer(boolean set, int timeout)
{
    Intent intent;
    PendingIntent alarmIntent;
    intent = new Intent(); // forms and creates appropriate Intent and pass it to AlarmManager
    intent.setAction(ACTION_WATCHDOG_OF_SERVICE);
    intent.setClass(this, WatchDogServiceReceiver.class);
    alarmIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    AlarmManager am=(AlarmManager)getSystemService(Context.ALARM_SERVICE);
    if(set)
        am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + timeout, alarmIntent);
    else
        am.cancel(alarmIntent);
}

从看门狗定时器接收和处理意图:

/** this class processes the intent and
 *  checks whether the service should be running
 */
public static class WatchDogServiceReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {

        if(intent.getAction().equals(ACTION_WATCHDOG_OF_SERVICE))
        {
            // check your flag and 
            // restart your service if it's necessary
        }
    }
}

确实,我使用WakefulBroadcastReceiver代替BroadcastReceiver。我用BroadcastReceiver给你的代码只是为了简化它。

答案 3 :(得分:0)

您的Service.onStartCommand()

中有此代码
if(intent != null){

您确实意识到,如果Android杀死了托管Service的进程,它将创建一个新进程并创建Service的新实例并重新启动它,调用onCreate()然后使用onStartCommand() null来呼叫Intent。这可能是正在发生的事情以及您认为onStartCommand()未被调用的原因。