AbstractThreadedSyncAdapter не запускается сразу
Мне было интересно, почему AbstractThreadedSyncAdapter не выполняет синхронизацию, как только я запускаю приложение, но вместо этого он ждет 5-10 минут, затем начинает загружать данные с помощью запроса API и заполняет мои таблицы, что приводит к этой ошибке:
02-03 05:03:34.954 6061-6061/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.moviesapp.app, PID: 6061
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.example.android.moviesapp.app/com.example.android.moviesapp.app.MainActivity}:
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
at com.example.android.moviesapp.app.DetailFragment.ReadTrailersDetailsFromDB(DetailFragment.java:70)
at com.example.android.moviesapp.app.DetailFragment.onCreateView(DetailFragment.java:114)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:330)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:547)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1171)
at android.app.Activity.performStart(Activity.java:5241)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2157)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
1 ответ
Смысл Android SyncManager в том, что вы позволяете ему решать, когда он хочет выполнить синхронизацию. Это для эффективности использования батареи, так что система имеет гибкость для пакетной синхронизации операций из разных приложений вместе. Это означает, что система может отключить энергосберегающее радио на более длительные периоды времени, когда синхронизируются все приложения.
Итак, если вы используете Android SyncManager (реализуя шаблон SyncAdapter), то вы должны ожидать, что он вызовет SyncAdapter.onPerformSync()
время от времени вы не можете контролировать.
Насколько я понимаю, ваша активность падает, потому что она читает пустые таблицы? А вы ожидали, что таблицы уже заполнены вашим SyncAdapter?
Обойти это невозможно, вы должны выполнить свою деятельность, чтобы они могли работать с пустыми таблицами. Вам придется поставить дополнительную проверку для этого.
Обратите внимание, что вы можете запустить немедленную синхронизацию с этим:
/**
* Starts a manual sync operation, i.e. independent of the automatic sync settings.
*
* @param context System's service locator
* @param account The account to sync
* @param expedited Make this sync a priority system wide
*/
public static void requestSync(Context context, Account account, boolean expedited) {
Bundle extras = new Bundle();
extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, expedited);
ContentResolver.requestSync(account, Contract.AUTHORITY, extras);
}
Вы предоставляете учетную запись, которую хотите синхронизировать, и установите для нее значение true, чтобы сделать так, чтобы Android SyncManager синхронизировал вашу учетную запись перед любыми другими приложениями. Поскольку этот запрос на синхронизацию установлен на "ручной", это означает, что SyncManager не будет ждать удобного времени, он просто включит радио и начнет синхронизировать все приложения, в первую очередь.
Но даже если вы выполняете requestSync, вы должны ожидать, что Интернет работает медленно, и результаты могут занять некоторое время от миллисекунд до секунд или даже минут, прежде чем они будут записаны в вашу базу данных вашим SyncAdapter. Между тем ваша активность уже запущена и она читает пустые таблицы...
Поэтому убедитесь, что ваша деятельность не приводит к сбою на пустых столах.