1

我的 android 应用程序中有一个后台服务。其中一个线程正在侦听经常运行的最近任务。我的服务覆盖了onCreate()onStartCommand()方法。当我试图打开一些应用程序,如GalleryCamera等等......时,该服务将被停止。onCreate()它只调用该方法而不是onDestroy()onStartCommand()。我试图在此服务中覆盖 onLowMemory() 但它什么也不记录。通过指定在内部保存的应用程序

 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;
    }


}

并像这样启动服务

Intent intent = new Intent(getApplicationContext(), MyService.class);
getApplicationContext().startService(intent);
4

4 回答 4

2

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

于 2013-05-13T04:12:40.973 回答
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)

于 2013-05-13T04:22:10.047 回答
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 的代码只是为了简化它。

于 2015-09-21T12:51:15.120 回答
0

你有这个代码在你的Service.onStartCommand()

if(intent != null){

您确实意识到,如果 Android 终止托管您的进程Service,它将创建一个新进程并创建您的新实例Service并重新启动它,调用onCreate()然后onStartCommand()使用null Intent. 这可能是正在发生的事情,也是您认为onStartCommand()没有被调用的原因。

于 2017-01-17T11:29:03.167 回答