SyncAdapter process killed when app process is terminated

时间:2016-01-27 16:05:42

标签: android android-syncadapter

Why the SyncAdapter process (:sync) is killed when the app is swiped from the app switcher list ? i thought the whole intention here is to keep them decoupled.

EDIT:

Following is the code used. mUploadTask is a AsyncTask im executing that reads information from a sqlite table (using getContext().getContentResolver()) and uploads relevant data to a backend (using HttpPost). Very straight forward.

Also, i implemented only one onSyncCanceled() since my SyncAdapter doesnt support syncing of multiple accounts in parallel.

public class SyncAdapter extends AbstractThreadedSyncAdapter implements UploadTaskListener {

private static final String TAG = SyncAdapter.class.getSimpleName();

private static volatile UploadTask mUploadTask;

/**
 * Set up the sync adapter
 */
public SyncAdapter(Context context, boolean autoInitialize) {
    super(context, autoInitialize);
}

/**
 * Set up the sync adapter. This form of the
 * constructor maintains compatibility with Android 3.0
 * and later platform versions
 */
public SyncAdapter(
        Context context,
        boolean autoInitialize,
        boolean allowParallelSyncs) {
    super(context, autoInitialize, allowParallelSyncs);
}

@Override
public void onPerformSync(Account account, Bundle extras, String authority,
        ContentProviderClient provider, SyncResult syncResult) {

    MHLog.logI(TAG, "onPerformSync");

    ContentResolver.setSyncAutomatically(account, authority, true);

    if (mUploadTask == null) {
        synchronized (SyncAdapter.class) {
            if (mUploadTask == null) {
                mUploadTask = new UploadTask(getContext(), this).executeOnSettingsExecutor();
                MHLog.logI(TAG, "onPerformSync - running");
            }
        }
    }
}

@Override
public void onSyncCanceled() {
    MHLog.logI(TAG, "onSyncCanceled");
    if(mUploadTask != null){
        mUploadTask.cancel(true);
        mUploadTask = null;
    }
}

2 个答案:

答案 0 :(得分:3)

来自文档:

  

框架可以随时取消同步。例如,非用户启动且持续时间超过30分钟的同步将被视为超时并取消。类似地,框架将尝试通过在一分钟内监视其网络活动来确定适配器是否正在取得进展。如果此窗口上的网络流量接近零,则同步将被取消。您还可以通过cancelSync(Account, String)cancelSync(SyncRequest)请求同步。

     

通过在同步主题上发出interrupt()来取消同步。您onPerformSync(Account, Bundle, String, ContentProviderClient, SyncResult)中的代码必须检查interrupted(),或者您必须覆盖onSyncCanceled(Thread) / onSyncCanceled()中的一个(取决于您的适配器是否支持并行同步多个帐户) )。如果你的适配器不尊重框架发出的取消,你就会冒着应用程序整个过程被杀的风险。

您是否确保遵守SyncAdapter框架的规则?

此外,很高兴看到您的一些代码深入了解框架取消同步的原因......

答案 1 :(得分:1)

onPerformSync()在单独的线程上工作。因此,您无需创建任何执行程序变量即可实现后台工作。

我遇到了同样的问题-我的适配器一直在onPerformSync()方法中使用执行程序,该执行程序可以执行操作(现在-还有一个线程)。 原因-如果系统在其线程的onPerformSync()方法中看不到任何作业(因为您已经创建了在另一个线程中执行操作的执行程序)- onSyncCanceled( )方法将被调用-这只是时间问题。

将完成短时操作,但 onSyncCanceled()将终止长时间(10分钟)。

您可以在适配器中覆盖 onSyncCanceled()-但您应该了解真正的问题并避免。

这是项目示例https://github.com/Udinic/SyncAdapter。在onPerformSync()方法中执行客户端-服务器实现,没有问题。