Reputation: 2837
I've a SyncAdapter that gets called during the initial onboarding process (Login/Signup) that deals with contacts to find a user's contacts already using the system.
While the SyncAdapter is running, the app gets killed almost every time (9 out of 10 times) on a particular device (Moto G).
My initial thoughts were the app is getting killed due to the limited available RAM of the device. So, I tried this to confirm the theory:
@Override
public void onPerformSync(Account account, Bundle extras, String authority,
ContentProviderClient provider, SyncResult syncResult) {
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
ActivityManager activityManager = (ActivityManager) getContext()
.getSystemService(Context.ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
long availableMegs = mi.availMem / 1048576L;
Log.d(TAG, "Available: " + availableMegs);
Log.d(TAG, "Low Memory: " + mi.lowMemory);
}
And turns out the RAM might not be an issue, since the Logs looks like this:
03-09 11:38:34.444 19193-21339/mypackage.sandbox D/SyncAdapter: Available: 252
03-09 11:38:34.445 19193-21339/mypackage.sandbox D/SyncAdapter: Low Memory: false
Futher in logs I found this:
03-09 11:38:35.233 865-1610/? I/ActivityManager: Killing 19193:mypackage.sandbox/u0a579 (adj 0): depends on provider com.android.providers.contacts/.ContactsProvider2 in dying proc android.process.acore
It seems like the application is being killed since the contacts application/provider is getting killed.
I'm not sure how much relevant is this thread I found on reddit.
One way I think its possible is if I can defer the notification that the contacts have been modified. It will prevent contacts provider from firing up and getting killed, in turn my application won't get killed. Please refer to point no 7 on this answer. If so, how can I defer the notification ?
I have even made sure that the notification to contacts is deferred by not changing any contact. Still the problem persists.
Any help is appreciated. Thanks
Upvotes: 4
Views: 1008
Reputation: 1294
Maybe you're running into a TransactionTooLargeException? It occurs when data bundled with an Intent is taking more space than the 1MB limit. Seeing the ContactsProvider in your log, it may have happened because the user's contacts database is too large. The sad thing about this exception is that it happens at the system level. Your app gets killed without ever getting a chance to catch (or: report) the problem. The only way to catch this exception is by keeping a close eye on logcat.
As for your question of how to prevent the SyncAdapter from crashing your app. Are you running the SyncAdapter in a separate process? If you just followed the sample/tutorial code then you are. If not, look up android:process=":sync"
in the training page. When run in a separate process, crashes in your SyncAdapter shouldn't affect the rest of your app. At least not directly. Your users will see an 'app has crashed' dialog, but app components running in other processes will continue running normally.
Upvotes: 3