AbstractThreadedSyncAdapter不会立即触发

时间:2016-02-03 10:10:29

标签: android android-syncadapter

我一直想知道为什么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 个答案:

答案 0 :(得分:1)

Android SyncManager的重点是让它决定何时进行同步。这是为了提高电池效率,因此系统可以灵活地将来自不同应用程序的操作批量同步。这样做意味着当所有应用程序同步时,系统可以在较长时间内关闭耗电量大的无线电。

因此,如果你使用Android SyncManager(通过实现SyncAdapter模式),那么你必须期望它在你无法控制的时候调用SyncAdapter.onPerformSync()

根据我的理解,你的Activity崩溃了,因为它正在读取空表?您希望表格已经由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将数据写入数据库之前,结果将需要一些时间,从几毫秒到几秒甚至几分钟。在此期间,您的活动已经启动并正在读取空表......

因此,请确保您的活动不会在空表上崩溃。