Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SyncAdapter process killed when app process is terminated

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;
    }
}
like image 340
AsafK Avatar asked Sep 25 '22 13:09

AsafK


1 Answers

From the documentation:

Syncs can be cancelled at any time by the framework. For example a sync that was not user-initiated and lasts longer than 30 minutes will be considered timed-out and cancelled. Similarly the framework will attempt to determine whether or not an adapter is making progress by monitoring its network activity over the course of a minute. If the network traffic over this window is close enough to zero the sync will be cancelled. You can also request the sync be cancelled via cancelSync(Account, String) or cancelSync(SyncRequest).

A sync is cancelled by issuing a interrupt() on the syncing thread. Either your code in onPerformSync(Account, Bundle, String, ContentProviderClient, SyncResult) must check interrupted(), or you you must override one of onSyncCanceled(Thread)/onSyncCanceled() (depending on whether or not your adapter supports syncing of multiple accounts in parallel). If your adapter does not respect the cancel issued by the framework you run the risk of your app's entire process being killed.

Are you making sure your honoring the rules of the SyncAdapter framework?

Additionally, it would be nice to see some of your code to drill down to why the framework is cancelling your Sync...

like image 62
kandroidj Avatar answered Oct 11 '22 13:10

kandroidj