Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/194.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
Java JNI中的ParcelFileDescriptor.createPipe_Java_Android_Java Native Interface - Fatal编程技术网

Java JNI中的ParcelFileDescriptor.createPipe

Java JNI中的ParcelFileDescriptor.createPipe,java,android,java-native-interface,Java,Android,Java Native Interface,我正在试图找出如何在ContentProvider.openFile中传递数据流。要发送的数据是在JNI中创建的。我尝试了createPipe,使用了一个传输线程,但我遇到了大量管道破裂的问题。所以我想我可以将“写入”管道传递给JNI,并将数据直接写入它 爪哇: C: 当我转换为byte[]时,一切正常,只是不在ContentProvider中显然: jbyteArray thumb = env->NewByteArray(jpegSize); env->SetByteArrayRe

我正在试图找出如何在
ContentProvider.openFile
中传递数据流。要发送的数据是在JNI中创建的。我尝试了
createPipe
,使用了一个传输线程,但我遇到了大量管道破裂的问题。所以我想我可以将“写入”管道传递给JNI,并将数据直接写入它

爪哇:

C:

当我转换为byte[]时,一切正常,只是不在
ContentProvider中
显然:

jbyteArray thumb = env->NewByteArray(jpegSize);
env->SetByteArrayRegion(thumb, 0, jpegSize, (jbyte *) jpeg);
free(jpeg);
return thumb;
当我调试到
fwrite
时,堆栈跟踪似乎消失了。从不点击
返回TRUE
返回管道[0]
,但也不会崩溃或抛出。很奇怪

有人做过类似的事情吗?只需将二进制文件写入“写入”管道就足够了吗?我在这里做错了什么吗?谢谢

更新(与@pskink讨论后) 我尝试实现了
PipeDataWriter
。我举了一个例子

@Override
public void writeDataToPipe(@NonNull ParcelFileDescriptor output, @NonNull Uri uri, @NonNull String mimeType, @Nullable Bundle opts, @Nullable byte[] args)
{
    try (FileOutputStream fout = new FileOutputStream(output.getFileDescriptor()))
    {
        fout.write(args, 0, args.length);
    }
    catch (IOException e)
    {
        Log.e(TAG, "Failed transferring", e);
    }
}

但是,当我使用上面的传输线程时,我得到了相同的错误:

java.io.IOException:写入失败:EBADF(错误的文件描述符)
在libcore.io.IoBridge.write中(IoBridge.java:498)
在java.io.FileOutputStream.write(FileOutputStream.java:186)处
在 anthonymandra.content.MetaProvider.WriteDataOppe(MetaProvider.java:273)

java.io.IOException:写入失败:EPIPE(断管)
在libcore.io.IoBridge.write中(IoBridge.java:498)
在java.io.FileOutputStream.write(FileOutputStream.java:186)处
在 anthonymandra.content.MetaProvider.WriteDataOppe(MetaProvider.java:273)


当我仔细检查以确保图像的数据是正确的时,我发现加载的一切都是正确的。在我看来,这实际上是一个线程安全问题。

事实上,有一大堆事情出了问题,所有这些都陷入了混乱:

  • 我不是在最后一次关闭
    ParcelFileDescriptor
  • 我用于图像缓存,当加载
    Uri
    时,它使用两个抓取器,这意味着
    openFile
    正在加载
  • (2) 导致了无休止的管道破裂错误
  • StrictMode
    因为(1)而终止了该应用程序,我在(3)的一系列错误中错过了它

  • 事实上,有很多事情都出了问题,最终导致了混乱:

  • 我不是在最后一次关闭
    ParcelFileDescriptor
  • 我用于图像缓存,当加载
    Uri
    时,它使用两个抓取器,这意味着
    openFile
    正在加载
  • (2) 导致了无休止的管道破裂错误
  • StrictMode
    因为(1)而终止了该应用程序,我在(3)的一系列错误中错过了它

  • 你的意思是?好的,所以仍然需要一个转移线程。这是有道理的。我对自己所做的“神奇记忆支持”假设表示怀疑。这也可能意味着我会遇到同样的管道破裂问题,但我会尽快解决。请参阅
    ContentProvider\openPipeHelper
    然后我没有尝试将
    openPipeHelper
    与jni“结婚”,但我99.99%确定您可以调用
    ImageProcessor.getThumb(fd/*source fd*/,pipe[1].getFd())
    PipeDataWriter#writedatatoppe
    方法中您可以传递
    args
    中的任何内容(openPipeHelper的最后一个参数),您的意思是?好的,因此仍然需要传输线程。这是有道理的。我对自己所做的“神奇记忆支持”假设表示怀疑。这也可能意味着我会遇到同样的管道破裂问题,但我会尽快解决。请参阅
    ContentProvider\openPipeHelper
    然后我没有尝试将
    openPipeHelper
    与jni“结婚”,但我99.99%确定您可以调用
    ImageProcessor.getThumb(fd/*source fd*/,pipe[1].getFd())
    内部
    PipeDataWriter#writedatatoppe
    方法您可以在
    args
    中传递任何内容(openPipeHelper的最后一个参数)很好,但实际上使用
    PipeDataWriter
    时,您不必关闭
    ParcelFileDescriptor
    ,因为“写入端”已关闭,“读取端”正在关闭(当关闭由
    ContentResolver\openInputStream()
    方法创建的
    InputStream
    时),实际上涉及到另一个pfd。拇指数据(通过管道传输)是从原始图像中提取的数据,该原始图像作为PFD通过SAF获取。如果出现错误(坏管道),导致
    StrictMode
    终止应用程序(并在一系列错误消息中丢失),则需要正确关闭。很好,但实际上,当使用
    PipeDataWriter
    时,您不必关闭
    ParcelFileDescriptor
    ,因为“写入端”已关闭,“读取端”已关闭(当关闭由
    ContentResolver#openInputStream()
    方法创建的
    InputStream
    时,实际上涉及到另一个pfd。拇指数据(通过管道传输)是从原始图像中提取的,该图像作为pfd通过可怕的SAF获取。在出现错误时需要正确关闭(坏管道)这导致
    StrictMode
    终止应用程序(并在一系列错误消息中丢失)。
    jbyteArray thumb = env->NewByteArray(jpegSize);
    env->SetByteArrayRegion(thumb, 0, jpegSize, (jbyte *) jpeg);
    free(jpeg);
    return thumb;
    
    @Override
    public void writeDataToPipe(@NonNull ParcelFileDescriptor output, @NonNull Uri uri, @NonNull String mimeType, @Nullable Bundle opts, @Nullable byte[] args)
    {
        try (FileOutputStream fout = new FileOutputStream(output.getFileDescriptor()))
        {
            fout.write(args, 0, args.length);
        }
        catch (IOException e)
        {
            Log.e(TAG, "Failed transferring", e);
        }
    }
    
    byte[] rawData = ImageUtil.getRawThumb(fd.getParcelFileDescriptor().getFd());
    return openPipeHelper(Uri.parse("invalid"), "image/jpg", null, rawData, this);