4141import android .os .Binder ;
4242import android .os .Bundle ;
4343import android .os .Environment ;
44+ import android .os .Handler ;
45+ import android .os .HandlerThread ;
4446import android .os .IBinder ;
47+ import android .os .Looper ;
4548import android .os .Process ;
4649import android .os .RemoteException ;
4750import android .os .SystemClock ;
@@ -180,6 +183,8 @@ public void disconnect() {
180183 boolean mStateLoaded ;
181184 int mMaxWidgetBitmapMemory ;
182185
186+ private final Handler mSaveStateHandler ;
187+
183188 // These are for debugging only -- widgets are going missing in some rare instances
184189 ArrayList <Provider > mDeletedProviders = new ArrayList <Provider >();
185190 ArrayList <Host > mDeletedHosts = new ArrayList <Host >();
@@ -189,6 +194,10 @@ public void disconnect() {
189194 mPm = AppGlobals .getPackageManager ();
190195 mAlarmManager = (AlarmManager ) mContext .getSystemService (Context .ALARM_SERVICE );
191196 mUserId = userId ;
197+
198+ HandlerThread handlerThread = new HandlerThread ("AppWidgetServiceImpl -- Save state" );
199+ handlerThread .start ();
200+ mSaveStateHandler = new Handler (handlerThread .getLooper ());
192201 computeMaximumWidgetBitmapMemory ();
193202 }
194203
@@ -236,7 +245,7 @@ void onConfigurationChanged() {
236245 updateProvidersForPackageLocked (cn .getPackageName (), removedProviders );
237246 }
238247 }
239- saveStateLocked ();
248+ saveStateAsync ();
240249 }
241250 }
242251 }
@@ -286,7 +295,7 @@ void onBroadcastReceived(Intent intent) {
286295 providersModified |= addProvidersForPackageLocked (pkgName );
287296 }
288297 }
289- saveStateLocked ();
298+ saveStateAsync ();
290299 }
291300 } else {
292301 Bundle extras = intent .getExtras ();
@@ -297,7 +306,7 @@ void onBroadcastReceived(Intent intent) {
297306 ensureStateLoadedLocked ();
298307 for (String pkgName : pkgList ) {
299308 providersModified |= removeProvidersForPackageLocked (pkgName );
300- saveStateLocked ();
309+ saveStateAsync ();
301310 }
302311 }
303312 }
@@ -411,7 +420,7 @@ void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
411420
412421 private void ensureStateLoadedLocked () {
413422 if (!mStateLoaded ) {
414- loadAppWidgetList ();
423+ loadAppWidgetListLocked ();
415424 loadStateLocked ();
416425 mStateLoaded = true ;
417426 }
@@ -432,7 +441,7 @@ public int allocateAppWidgetId(String packageName, int hostId) {
432441 host .instances .add (id );
433442 mAppWidgetIds .add (id );
434443
435- saveStateLocked ();
444+ saveStateAsync ();
436445 if (DBG ) log ("Allocating AppWidgetId for " + packageName + " host=" + hostId
437446 + " id=" + appWidgetId );
438447 return appWidgetId ;
@@ -445,7 +454,7 @@ public void deleteAppWidgetId(int appWidgetId) {
445454 AppWidgetId id = lookupAppWidgetIdLocked (appWidgetId );
446455 if (id != null ) {
447456 deleteAppWidgetLocked (id );
448- saveStateLocked ();
457+ saveStateAsync ();
449458 }
450459 }
451460 }
@@ -457,7 +466,7 @@ public void deleteHost(int hostId) {
457466 Host host = lookupHostLocked (callingUid , hostId );
458467 if (host != null ) {
459468 deleteHostLocked (host );
460- saveStateLocked ();
469+ saveStateAsync ();
461470 }
462471 }
463472 }
@@ -476,7 +485,7 @@ public void deleteAllHosts() {
476485 }
477486 }
478487 if (changed ) {
479- saveStateLocked ();
488+ saveStateAsync ();
480489 }
481490 }
482491 }
@@ -592,7 +601,7 @@ private void bindAppWidgetIdImpl(int appWidgetId, ComponentName provider, Bundle
592601
593602 // schedule the future updates
594603 registerForBroadcastsLocked (p , getAppWidgetIds (p ));
595- saveStateLocked ();
604+ saveStateAsync ();
596605 }
597606 } finally {
598607 Binder .restoreCallingIdentity (ident );
@@ -656,8 +665,8 @@ public void setBindAppWidgetPermission(String packageName, boolean permission) {
656665 } else {
657666 mPackagesWithBindWidgetPermission .remove (packageName );
658667 }
668+ saveStateAsync ();
659669 }
660- saveStateLocked ();
661670 }
662671
663672 // Binds to a specific RemoteViewsService
@@ -894,6 +903,20 @@ public void updateAppWidgetIds(int[] appWidgetIds, RemoteViews views) {
894903 }
895904 }
896905
906+ private void saveStateAsync () {
907+ mSaveStateHandler .post (mSaveStateRunnable );
908+ }
909+
910+ private final Runnable mSaveStateRunnable = new Runnable () {
911+ @ Override
912+ public void run () {
913+ synchronized (mAppWidgetIds ) {
914+ ensureStateLoadedLocked ();
915+ saveStateLocked ();
916+ }
917+ }
918+ };
919+
897920 public void updateAppWidgetOptions (int appWidgetId , Bundle options ) {
898921 synchronized (mAppWidgetIds ) {
899922 options = cloneIfLocalBinder (options );
@@ -914,7 +937,7 @@ public void updateAppWidgetOptions(int appWidgetId, Bundle options) {
914937 intent .putExtra (AppWidgetManager .EXTRA_APPWIDGET_ID , id .appWidgetId );
915938 intent .putExtra (AppWidgetManager .EXTRA_APPWIDGET_OPTIONS , id .options );
916939 mContext .sendBroadcastAsUser (intent , new UserHandle (mUserId ));
917- saveStateLocked ();
940+ saveStateAsync ();
918941 }
919942 }
920943
@@ -1215,7 +1238,7 @@ void pruneHostLocked(Host host) {
12151238 }
12161239 }
12171240
1218- void loadAppWidgetList () {
1241+ void loadAppWidgetListLocked () {
12191242 Intent intent = new Intent (AppWidgetManager .ACTION_APPWIDGET_UPDATE );
12201243 try {
12211244 List <ResolveInfo > broadcastReceivers = mPm .queryIntentReceivers (intent ,
0 commit comments