4

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 のような例外をスローするのではなく、クライアントが強制終了される理由ですか?

4

1 に答える 1