SharedPreferences$Editor.startCommit()
Adds a fire-and-forget save method (startCommit) to the
SharedPreferences.Editor, which is the way most people use it anyway.
This commit adds the implementation. The previous commit added the
interface and docs:
previous change: Idf9934b445da1fb72b79f0192218b47c0a7f5a34
git commit: edf32d01316bd3432c023f17747461b08ae36375
In addition, this change:
-- adds a generic "runPendingWorkFinishers" mechanism to
ActivityThread to wait on async operations that are still
in flight and use it for this.
-- ties runPendingWorkFinishers into Activity.onPause,
BroadcastReceiver, and Service.
-- makes sSharedPreferences keyed on name, not File, to avoid
unnnecessary allocations
-- documents and guarantees what thread
OnSharedPreferenceChangeListener callbacks run on
-- makes a few things in frameworks/base use startCommit(), notably
Preference.java (which was ignoring the return value anyway)
Change-Id: I1c8db60ad45643226fe6d246d3e513eeb7bd0ebd
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index c07e3d3..084f637 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -152,7 +152,7 @@
= new ArrayList<Application>();
// set of instantiated backup agents, keyed by package name
final HashMap<String, BackupAgent> mBackupAgents = new HashMap<String, BackupAgent>();
- static final ThreadLocal sThreadLocal = new ThreadLocal();
+ static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal();
Instrumentation mInstrumentation;
String mInstrumentationAppDir = null;
String mInstrumentationAppPackage = null;
@@ -186,6 +186,8 @@
final GcIdler mGcIdler = new GcIdler();
boolean mGcIdlerScheduled = false;
+ static Handler sMainThreadHandler; // set once in main()
+
private static final class ActivityClientRecord {
IBinder token;
int ident;
@@ -1111,7 +1113,7 @@
}
public static final ActivityThread currentActivityThread() {
- return (ActivityThread)sThreadLocal.get();
+ return sThreadLocal.get();
}
public static final String currentPackageName() {
@@ -1780,6 +1782,8 @@
}
}
+ QueuedWork.waitToFinish();
+
try {
if (data.sync) {
if (DEBUG_BROADCAST) Slog.i(TAG,
@@ -2007,6 +2011,9 @@
data.args.setExtrasClassLoader(s.getClassLoader());
}
int res = s.onStartCommand(data.args, data.flags, data.startId);
+
+ QueuedWork.waitToFinish();
+
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, 1, data.startId, res);
@@ -2035,6 +2042,9 @@
final String who = s.getClassName();
((ContextImpl) context).scheduleFinalCleanup(who, "Service");
}
+
+ QueuedWork.waitToFinish();
+
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
token, 0, 0, 0);
@@ -3598,6 +3608,9 @@
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
+ if (sMainThreadHandler == null) {
+ sMainThreadHandler = new Handler();
+ }
ActivityThread thread = new ActivityThread();
thread.attach(false);