从最近一次刷卡时,SyncAdapter进程被终止

时间:2014-07-31 14:27:32

标签: android android-service android-syncadapter kill-process android-recents

我正在尝试创建运行后台操作的SyncAdapter(没有前台通知)。

除了从最近的应用程序中删除触发ContentResolver.requestSync(...)的活动(任务)的情况之外,它正在工作。在这种情况下,进程被终止并且onPerformSync(...)未完成。

我知道,这是预期的Android行为,但在常规Service我会设置

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

    return START_REDELIVER_INTENT;
}

或者可以使用

@Override
public void onTaskRemoved(Intent rootIntent) {
    super.onTaskRemoved(rootIntent);

    restartSynchronization();
}

重试同步,但这在SyncAdapterService中不起作用。

如何在活动从最近的应用程序中删除后,确保继续/重试同步?

提前谢谢。

1 个答案:

答案 0 :(得分:0)

经过一些研究后我发现,onTaskRemoved(...)仅在调用startService(...)时调用,而不是在有人仅绑定它时调用。

所以我通过在onBind(...)中启动服务并在onUnbind(...)方法中停止它及其过程来解决问题。

这是最终代码:

public class SyncAdapterService extends Service {
private static final Object sSyncAdapterLock = new Object();
private static MySyncAdapter sSyncAdapter = null;

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

    synchronized (sSyncAdapterLock) {
        if (sSyncAdapter == null) {
            sSyncAdapter = new MySyncAdapter(getApplicationContext());
        }
    }
}

@Override
public void onTaskRemoved(Intent rootIntent) {
    super.onTaskRemoved(rootIntent);

    /*
     * Rescheduling sync due to running one is killed on removing from recent applications.
     */
    SyncHelper.requestSyncNow(this);
}

@Override
public IBinder onBind(Intent intent) {
    /*
     * Start service to watch {@link @onTaskRemoved(Intent)}
     */
    startService(new Intent(this, SyncAdapterService.class));

    return sSyncAdapter.getSyncAdapterBinder();
}

@Override
public boolean onUnbind(Intent intent) {
    /*
     * No more need watch task removes.
     */
    stopSelf();

    /*
     * Stops current process, it's not necessarily required. Assumes sync process is different
     * application one. (<service android:process=":sync" /> for example).
     */
    Process.killProcess(Process.myPid());

    return super.onUnbind(intent);
}
}