For Android APIs, Think Streams, Not Files
If you are creating a library for Android — JAR,
Android library project, etc. — if you want your public API to
take File
objects as parameters, that’s fine.
However, those should be convenience methods, for the “real” API that takes streams as parameters.
There are many data sources in Android that surface themselves as streams instead of files:
-
Raw resources are available as
InputStream
s, not files -
Assets are available as
InputStream
s, not files -
content://
Uri
values that you handle withContentResolver
are available asInputStream
s (and sometimesOutputStream
s), not files -
Encrypted stores, like IOCipher, will sometimes work with streams instead of files
-
Network operations, such as HTTPS transfers, work with streams instead of files
-
And so on
A Java File
object is a useful handle to a bit of persistent data,
but it is only that: a handle. Even with a File
, often you are going to
be working with streams, or working with layers atop of streams
(e.g., InputStreamReader
).
This extends Google’s new recommendations, where they are steering you away from sending
out file:///
Uri
values in Intent
s, in favor of
FileProvider
:
Apps should generally avoid sending raw filesystem paths across process boundaries, since the receiving app may not have the same access as the sender.
So, I’m not saying that your API should not support File
objects.
Just be sure to support InputStream
and OutputStream
options as
well, to allow the caller to have more control over where the data
comes from.