在 android 平台上(在 ICS 上已确认),如果内容提供者在客户端处于查询中间(即有一个打开的游标)时死亡,则框架决定终止持有打开游标的客户端进程。
这是我尝试使用下载管理器查询时的 logcat 输出,该查询在执行查询后休眠。“睡眠”是为了重现问题。当提供者在正确/错误的时间死亡时,您可以想象它发生在常规用例中。然后杀掉 com.android.media(它承载了 downloadProvider)。
“杀死 com.example(pid 12234),因为提供者 com.android.providers.downloads.DownloadProvider 正在死亡进程 android.process.media”
我在 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这样的异常的原因吗?