Reliability of the Android content provider in the event of a provider failure

On Android platforms (confirmed on ICS), if the content provider dies when the client is in the middle of the request (i.e. has an open cursor), the environment decides to kill the client processes with an open cursor.

Here is the logcat output when I tried this with the request of the boot manager, which falls asleep after executing the request. "Sleep" was supposed to reproduce the problem. You can imagine that this happens in the usual case when the supplier dies at the right / wrong moment. And then do kill com.android.media (which hosts downloadProvider).

"Killing com.example (pid 12234) because the provider com.android.providers.downloads.DownloadProvider is in the dying android.process.media process"

I tracked the code for this in 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 } 

Is this a political decision or cursor access is not available after the provider has died?

It looks like the client cursor holds fd for the location of the ashtray filled with CP. Is this the reason why clients are killed instead of throwing an exception such as Binders when the server (provider) dies?

+4
source share
1 answer

Cursor unsafe. Although I think that most of the time Cursor used only for “read access” to the data, it is more complex than that.

A brief explanation in Android docs describing Cursor :

This interface provides random read and write access to the result set returned by the database query.

So Cursor is not just data stored in an object. They take your place in the ResultSet through a database connection. ResultSet uses JDBC to access the database. Thus, Cursor only acts as a "Java-friendly" database call. Here is the Android for ResultSet docs:

When reading data using appropriate retrieval methods, the JDBC driver maps the SQL data retrieved from the database to a Java type, implied by the method called by the application. The JDBC specification has a table for SQL type mappings for Java types.

ResultSet maintains a database connection. Data is not “copied” to the interface (both Cursor and ResultSet are interfaces, not objects; some implementations can copy data, but I did not test it, because leaving Statement and ResultSet resources open through a closed Connection can cause problems with database resources).

Java provides an interface for JDBC to access the “result table” in the database for the ResultSet , as described in the Java docs here:

A data table representing a set of database results that is typically generated by executing a statement that queries the database.

http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html

You cannot grant "database access" to a ContentProvider that died because there is no connection to the ResultSet table in the database, so Cursor should be deleted.

EDIT:

One comment suggests that Android does not use JDBC' or ResultSet` - the SQLite implementation for Android is a very similar implementation for JDBC, and the concepts are essentially the same without convenient names and descriptions.

The fact that Android uses a custom implementation makes it difficult to describe the problem, although I should have made a reference to this in my original post. Here is a list of Google Groups about JDBC status and SQLite implementation on Android, if more detailed links and information are required:

https://groups.google.com/forum/#!topic/android-developers/zz3qlNL2JDw

From the discussion, you could probably ask Jörg Pleumann in more detail ...

-1
source

All Articles