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 }
@@ -410,7 +419,7 @@ void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
410419
411420 private void ensureStateLoadedLocked () {
412421 if (!mStateLoaded ) {
413- loadAppWidgetList ();
422+ loadAppWidgetListLocked ();
414423 loadStateLocked ();
415424 mStateLoaded = true ;
416425 }
@@ -431,7 +440,7 @@ public int allocateAppWidgetId(String packageName, int hostId) {
431440 host .instances .add (id );
432441 mAppWidgetIds .add (id );
433442
434- saveStateLocked ();
443+ saveStateAsync ();
435444 if (DBG ) log ("Allocating AppWidgetId for " + packageName + " host=" + hostId
436445 + " id=" + appWidgetId );
437446 return appWidgetId ;
@@ -444,7 +453,7 @@ public void deleteAppWidgetId(int appWidgetId) {
444453 AppWidgetId id = lookupAppWidgetIdLocked (appWidgetId );
445454 if (id != null ) {
446455 deleteAppWidgetLocked (id );
447- saveStateLocked ();
456+ saveStateAsync ();
448457 }
449458 }
450459 }
@@ -456,7 +465,7 @@ public void deleteHost(int hostId) {
456465 Host host = lookupHostLocked (callingUid , hostId );
457466 if (host != null ) {
458467 deleteHostLocked (host );
459- saveStateLocked ();
468+ saveStateAsync ();
460469 }
461470 }
462471 }
@@ -475,7 +484,7 @@ public void deleteAllHosts() {
475484 }
476485 }
477486 if (changed ) {
478- saveStateLocked ();
487+ saveStateAsync ();
479488 }
480489 }
481490 }
@@ -591,7 +600,7 @@ private void bindAppWidgetIdImpl(int appWidgetId, ComponentName provider, Bundle
591600
592601 // schedule the future updates
593602 registerForBroadcastsLocked (p , getAppWidgetIds (p ));
594- saveStateLocked ();
603+ saveStateAsync ();
595604 }
596605 } finally {
597606 Binder .restoreCallingIdentity (ident );
@@ -655,8 +664,8 @@ public void setBindAppWidgetPermission(String packageName, boolean permission) {
655664 } else {
656665 mPackagesWithBindWidgetPermission .remove (packageName );
657666 }
667+ saveStateAsync ();
658668 }
659- saveStateLocked ();
660669 }
661670
662671 // Binds to a specific RemoteViewsService
@@ -893,6 +902,20 @@ public void updateAppWidgetIds(int[] appWidgetIds, RemoteViews views) {
893902 }
894903 }
895904
905+ private void saveStateAsync () {
906+ mSaveStateHandler .post (mSaveStateRunnable );
907+ }
908+
909+ private final Runnable mSaveStateRunnable = new Runnable () {
910+ @ Override
911+ public void run () {
912+ synchronized (mAppWidgetIds ) {
913+ ensureStateLoadedLocked ();
914+ saveStateLocked ();
915+ }
916+ }
917+ };
918+
896919 public void updateAppWidgetOptions (int appWidgetId , Bundle options ) {
897920 synchronized (mAppWidgetIds ) {
898921 options = cloneIfLocalBinder (options );
@@ -913,7 +936,7 @@ public void updateAppWidgetOptions(int appWidgetId, Bundle options) {
913936 intent .putExtra (AppWidgetManager .EXTRA_APPWIDGET_ID , id .appWidgetId );
914937 intent .putExtra (AppWidgetManager .EXTRA_APPWIDGET_OPTIONS , id .options );
915938 mContext .sendBroadcastAsUser (intent , new UserHandle (mUserId ));
916- saveStateLocked ();
939+ saveStateAsync ();
917940 }
918941 }
919942
@@ -1214,7 +1237,7 @@ void pruneHostLocked(Host host) {
12141237 }
12151238 }
12161239
1217- void loadAppWidgetList () {
1240+ void loadAppWidgetListLocked () {
12181241 Intent intent = new Intent (AppWidgetManager .ACTION_APPWIDGET_UPDATE );
12191242 try {
12201243 List <ResolveInfo > broadcastReceivers = mPm .queryIntentReceivers (intent ,
0 commit comments