Android プラットフォーム (ICS で確認済み) では、クライアントがクエリの途中である (つまり、開いているカーソルがある) 間にコンテンツ プロバイダーが停止した場合、フレームワークは、開いているカーソルを保持しているクライアント プロセスを強制終了することを決定します。
これは、クエリを実行した後にスリープするダウンロード マネージャー クエリでこれを試したときの logcat 出力です。「スリープ」は問題を再現することでした。プロバイダーが正しい/間違ったタイミングで停止した場合、通常のユース ケースで発生することが想像できます。そして、com.android.media (downloadProvider をホストする) を kill します。
「プロバイダー com.android.providers.downloads.DownloadProvider が死にかけているプロセス android.process.media であるため、com.example (pid 12234) を強制終了します」
ActivityManagerService::removeDyingProviderLocked でこのコードを追跡しました
10203 private final void removeDyingProviderLocked(ProcessRecord proc,
10204 ContentProviderRecord cpr) {
10205 synchronized (cpr) {
10206 cpr.launchingApp = null;
10207 cpr.notifyAll();
10208 }
10210 mProvidersByClass.remove(cpr.name);
10211 String names[] = cpr.info.authority.split(";");
10212 for (int j = 0; j < names.length; j++) {
10213 mProvidersByName.remove(names[j]);
10214 }
10215
10216 Iterator<ProcessRecord> cit = cpr.clients.iterator();
10217 while (cit.hasNext()) {
10218 ProcessRecord capp = cit.next();
10219 if (!capp.persistent && capp.thread != null
10220 && capp.pid != 0
10221 && capp.pid != MY_PID) {
10222 Slog.i(TAG, "Kill " + capp.processName
10223 + " (pid " + capp.pid + "): provider " + cpr.info.name
10224 + " in dying process " + (proc != null ? proc.processName : "??"));
10225 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10226 capp.processName, capp.setAdj, "dying provider "
10227 + cpr.name.toShortString());
10228 Process.killProcessQuiet(capp.pid);
10229 }
10230 }
10231
10232 mLaunchingProviders.remove(cpr);
10233 }
これはポリシーの決定ですか、それともプロバイダーが終了した後のカーソル アクセスは安全ではありませんか?
クライアント カーソルが、CP によって設定された ashmem の場所の fd を保持しているようです。これが、サーバー (プロバイダー) が停止したときに Binders のような例外をスローするのではなく、クライアントが強制終了される理由ですか?