安卓在应用程序关闭后正确重启服务



我目前正在开发一个电子邮件应用程序,该应用程序依赖于后台service,以便能够自动获取新的电子邮件。当应用程序打开(或在应用程序的运行列表中)时,这非常有效,但一旦我关闭应用程序/将其从最近的应用程序列表中删除,service也会停止。这可以通过进入设备上的"开发人员设置"并查看没有为我的应用程序运行的进程或服务来确认。

我在StackOverflow上读过无数个线程,但似乎没有一个能起到作用。有时调用onTaskRemoved()并重新启动服务,但其他时候根本不调用它或调用它,日志显示操作系统已计划重新启动service,但随后service由操作系统获得forced closed,而我总是需要运行此服务来检索新的电子邮件。

我当前的代码如下:

我的服务:

@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.i(TAG, "onStartCommand()");
...
Log.d(TAG, "SERVICE IS RUNNING");
if (host != null) {
Log.d(TAG, "STARTING PUSH SERVICE");
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
Log.d(TAG, "BR: " + ((BugReporting) getApplication()));
sharedRunnable = ((BugReporting) getApplication()).getSharedRunnable();
MailPush mailPush = new MailPush(getApplicationContext(), sharedRunnable);
Log.d(TAG, "sharedRunnable 1: " + sharedRunnable);
mailPush.checkInboxEmail(host, email, password);
//mailPush.checkSentEmail(host, email, password);
}
};
handler.postDelayed(runnable, 5000);//0.5 seconds
}
return START_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate()");
}
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.i(TAG, "onTaskRemoved()");
PendingIntent service = PendingIntent.getService(
getApplicationContext(),
1001,
new Intent(getApplicationContext(), MyService.class),
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy()");
startService(new Intent(this, MyService.class));
}

重新启动接收器:

public class AutoStart extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, MyService.class));
}
}

清单:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
<receiver
android:name="uk.co.tundracorestudios.securemail.notification.AutoStart"
android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name="uk.co.tundracorestudios.securemail.notification.MyService"
android:enabled="true"
android:exported="true"
android:label="@string/mail_service"
android:stopWithTask="false"/>

我确实尝试将MyService作为不同的process运行,但这限制了我获得保存在应用程序类中的sharedRunnable,否则可以通过访问

updateListRunnable = ((BugReporting) getApplication()).getSharedRunnable();

因此,我想问的是,即使在应用程序关闭或设备为rebooted时,我如何确保我的service持续运行/工作,同时仍然可以访问位于getApplication()中的组件?

当我尝试将MyService作为单独的process运行时,上述updateListRunnable将始终返回null,而当应用程序和service在同一process中运行时,它将返回正确的runnable

我不久前遇到了类似的问题,并在我的服务的onDestroy()方法中使用了这个问题:

public void onDestroy() {
Intent restartService = new Intent(getApplicationContext(),this.getClass());
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(),1,restartService,PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME,5000,pendingIntent);
super.onDestroy();
}

当服务被破坏时,我设置了5秒的警报,这将再次启动我的服务。这样,当用户从最近的服务中删除时,您的服务将停止,但它将重新启动。

对我来说,从onDestroy使用AlarmManager重新启动服务不起作用,但从onTaskRemoved启动服务起作用。当您在服务运行时终止应用程序时,会触发onTaskRemoved函数。

@Override
public void onTaskRemoved(Intent rootIntent) {
Log.d(TAG, "onTaskRemoved: removed");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis() + 10000);
((AlarmManager) getSystemService(Context.ALARM_SERVICE)).setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), PendingIntent.getService(getApplicationContext(), 0, new Intent(getApplicationContext(), RegisterReceiverService.class), 0));
super.onTaskRemoved(rootIntent);
}

因此,基本上,一旦你杀死应用程序,服务将在10秒后启动。注意:如果您想使用

AlarmManager.ELAPSED_REALTIME_WAKEUP

您能够重新启动服务的最短时间为15分钟。

请记住,您还需要在重新启动时使用BroadcastReceiver启动服务。

相关内容

  • 没有找到相关文章

最新更新