Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/227.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 自定义ContentProvider-openInputStream(),openOutputStream()_Android_File Io_Android Contentprovider - Fatal编程技术网

Android 自定义ContentProvider-openInputStream(),openOutputStream()

Android 自定义ContentProvider-openInputStream(),openOutputStream(),android,file-io,android-contentprovider,Android,File Io,Android Contentprovider,内容提供者/解析器API使用URI和openInputStream()和openOutputStream()方法提供了一种复杂但健壮的在进程之间传输数据的方法。自定义内容提供程序能够使用自定义代码覆盖openFile()方法,以有效地将URI解析为流;但是,openFile()的方法签名有一个ParcelFileDescriptor返回类型,不清楚如何为从该方法返回的动态生成的内容生成适当的表示 是否有在现有代码库中为动态内容实现ContentProvider.openFile()方法的示例?

内容提供者/解析器API使用URI和
openInputStream()
openOutputStream()
方法提供了一种复杂但健壮的在进程之间传输数据的方法。自定义内容提供程序能够使用自定义代码覆盖
openFile()
方法,以有效地将URI解析为
;但是,
openFile()
的方法签名有一个
ParcelFileDescriptor
返回类型,不清楚如何为从该方法返回的动态生成的内容生成适当的表示


是否有在现有代码库中为动态内容实现
ContentProvider.openFile()
方法的示例?如果没有,您能推荐源代码或流程吗?

MemoryFile支持这一点,但公共API尚未最终确定。

请从总是有用的公共软件中查看这个伟大的示例项目。它允许您创建一个ParcelFileDescriptor管道,其中一端包含所需的任何InputStream,另一端包含接收应用程序:

关键部分是在
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);
        }
    }
}

是否计划在将来包含memoryfile和parcelfiledescriptor之间的转换?沿着这些思路做的事情比用具有未知生命周期的临时文件混乱/污染文件系统要好。也许有某种方法可以检测到内容提供商内的流关闭,这可以提供一种更安全的方法来在您之后进行清理?我关心的是将附件发送到(gmail/standaed)电子邮件客户端,尽管我确信还有其他地方可能出现这些问题。是的,MemoryFile.java目前有一个
公共ParcelFileDescriptor getParcelFileDescriptor()
方法。这是作为甜甜圈的一部分承诺的,但正如杰夫所说,还没有最终确定。我已经证实了“概念”至少是有效的,并且目前可以使用反射来完成。但是它非常脏,不推荐使用:)不幸的是,即使是
ParcelFileDescriptor.fromSocket()
也不能使用,因为
Memory.isMemoryFile()
会引发异常,因为套接字既不是PFD也不是内存文件。请小心使用MemoryFile。如果我理解正确,它会将文件的全部内容存储在内存中,因此您不能使用比可用内存大的文件。我使用第三方库,通过内容提供商请求文件,出于某种原因,另一端的数据会到达(我在这里谨慎地说)以这种方式返回ParcelFileDescriptor或使用真实文件(如:ParcelFileDescriptor.open(privateFile,ParcelFileDescriptor.MODE_READ_))时会出现不同的情况。知道为什么在使用此提供程序处理大量请求时有时会出现错误吗:java.io.IOException:写入失败:Epie(断管)在libcore.io.IoBridge.write(IoBridge.java:502)和java.io.FileOutputStream.write(FileOutputStream.java:186)中,我遇到了与Malachiasz相同的问题。有人在这方面有什么进展吗?同样看到这个错误,您在3年后找到了解决方法吗?这确实有效,但比在文件系统上缓存文件要慢