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;
}
}
From the documentation:
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...
The onPerformSync() works on a separate thread. So, you don't need to create any executor variables to implement the background work.
I had the same problem - my adapter has been using executor in onPerformSync() method, that perform operations (now - the one more thread). That's a reason - in case the system doesn't see any job in onPerformSync() method in it's thread (because you've created executor that perform actions in another thread) - the onSyncCanceled() method will be invoked - it is just a question of time.
The short time operations will be done, but the long time (10 min) will be terminated by onSyncCanceled().
You can override onSyncCanceled() in your adapter - but you should understand the real problem and avoid it.
Here is the project sample https://github.com/Udinic/SyncAdapter. Do the client-server implementation in onPerformSync() method and have no problem.