内容提供者/解析器 API 提供了一种复杂但稳健的方式,使用 URI 和 openInputStream()
和 openOutputStream()
方法在进程之间传输数据。自定义内容提供者能够使用自定义代码覆盖 openFile()
方法,从而有效地将 URI 解析为 Stream
;但是,openFile()
的方法签名具有 ParcelFileDescriptor
返回类型,并且不清楚如何为从该方法返回的动态生成的内容生成适当的表示。
Returning a memory mapped InputStream from a content provider?
现有代码库中是否有实现动态内容的ContentProvider.openFile()
方法的例子?如果没有,您能建议这样做的源代码或流程吗?
最佳答案
从总是很有帮助的 CommonsWare 中查看这个很棒的示例项目。它允许您创建一个 ParcelFileDescriptor 管道,其中一侧带有您想要的任何 InputStream,另一侧带有接收应用程序:
https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider/Pipe
关键部分是在openFile
中创建管道:
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
ParcelFileDescriptor[] pipe=null;
try {
pipe=ParcelFileDescriptor.createPipe();
AssetManager assets=getContext().getResources().getAssets();
new TransferThread(assets.open(uri.getLastPathSegment()),
new AutoCloseOutputStream(pipe[1])).start();
}
catch (IOException e) {
Log.e(getClass().getSimpleName(), "Exception opening pipe", e);
throw new FileNotFoundException("Could not open pipe for: "
+ uri.toString());
}
return(pipe[0]);
}
然后创建一个保持管道满的线程:
static class TransferThread extends Thread {
InputStream in;
OutputStream out;
TransferThread(InputStream in, OutputStream out) {
this.in = in;
this.out = out;
}
@Override
public void run() {
byte[] buf = new byte[8192];
int len;
try {
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.flush();
out.close();
} catch (IOException e) {
Log.e(getClass().getSimpleName(),
"Exception transferring file", e);
}
}
}
关于android - 自定义 ContentProvider - openInputStream()、openOutputStream(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2148301/