Android - 在本机和Java应用程序之间使用管道 [英] Android - Using pipe between native and java apps

查看:162
本文介绍了Android - 在本机和Java应用程序之间使用管道的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发SGS2 api v.16



我有两个应用程序:native和Java



从本机应用程序我打开一个带有mkfifo()函数的Unix管道并写一些字符串。



在java应用程序中我试图读取字符串,但不知何故应用程序块和我不知道为什么,没有迹象在logcat中为什么它被阻止。



这2个应用程序有android:sharedUserId清单中的my.Id,并且该份额肯定有效。



在logcat中我可以看到打开输入流日志,但之后没有日志那个..
是否有推荐的方法从Java中读取管道文件?
注意:如果我用open(...)打开常规文件而不是使用mkfifo(...)我成功从文件中读取,问题是只有当我打开一个管道文件时mkfifo()



这是从原生应用程序运行的函数:

  jint Java_com_example_ndkfoo_NdkFooActivity_writeToPipe(JNIEnv * env,jobject javaThis){
const char * PATH =/ data / data / com.example.ndkfoo / v_pipe8;
char * line =Hello Pipe!;
int pipe;
errno = 0;

//打开命名管道
mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
pipe = mkfifo(PATH,mode);
if(errno!= 0){
__android_log_write(ANDROID_LOG_ERROR,NDK_FOO_TAG,strerror(errno));
返回错误;
}
__android_log_write(ANDROID_LOG_DEBUG,NDK_FOO_TAG,文件成功打开);

//实际写出数据并关闭管道
int err = write(pipe,line,strlen(line));

//关闭管道
close(管道);
返回错误;

}

这是试图从管道中读取的java

  package com.example.secondparty; 

import java.io.FileDescriptor;
import java.io.FileInputStream;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;

公共类MainActivity扩展Activity {
private static final String TAG = MainActivity.class.getSimpleName();
// public final static String PATH2 =/ sdcard / fifo9001;
public final static String PATH =/ data / data / com.example.ndkfoo / v_pipe8;

@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

readFromPipe();

}

@Override
public boolean onCreateOptionsMenu(菜单菜单){
getMenuInflater()。inflate(R.menu.main,menu);
返回true;
}

private void readFromPipe(){
Log.i(TAG,Attempt started);
FileInputStream fis;
String message =;
byte buffer [] = new byte [256];

try {
Log.i(TAG,openning input stream);
fis = new FileInputStream(PATH);
Log.i(TAG,输入流已打开);
FileDescriptor fd = fis.getFD();
int len = 0;
do {
len = fis.read(buffer);
if(len> 0){
String newmessage = new String(buffer,0,len,US-ASCII);
message + = newmessage;
}
} while(len == buffer.length);
Log.i(TAG,message:+ message);
fis.close();
} catch(例外e){
e.printStackTrace();
}


}
}


BufferedReader 而不是`FileInputStream


I'm developing on SGS2 api v.16

I have two applications: native and Java

From the native app I open a Unix pipe with mkfifo() function and write some string to it.

And in the java app I'm trying to read the string, but somehow the app blocks and I don't know why, no indication in the logcat for why it blocked.

The 2 apps have android:sharedUserId="my.Id" in the manifest, and the share worked for sure.

In the logcat I can see the "opening input stream" log, but no log after that.. Is there a recommended way to read from a pipe file in Java? NOTE: if I open a regular file with open(...) instead of using mkfifo(...) I succeed to read from the file, the problem is only when I open a pipe file with mkfifo()

Here is the function runs from the native app:

jint Java_com_example_ndkfoo_NdkFooActivity_writeToPipe(JNIEnv* env, jobject javaThis) {
   const char* PATH = "/data/data/com.example.ndkfoo/v_pipe8";
   char* line = "Hello Pipe!";
   int pipe;
   errno = 0;

   // open a named pipe
   mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
   pipe = mkfifo(PATH, mode);
   if(errno != 0) {
        __android_log_write(ANDROID_LOG_ERROR, "NDK_FOO_TAG", strerror(errno));
        return errno;
    }
    __android_log_write(ANDROID_LOG_DEBUG, "NDK_FOO_TAG", "file opened successfully");

   // actually write out the data and close the pipe
   int err = write(pipe, line, strlen(line));

    // close the pipe
   close(pipe);
   return err;

}

And here is the java that tries to read from the pipe

package com.example.secondparty;

import java.io.FileDescriptor;
import java.io.FileInputStream;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity {
     private static final String TAG = MainActivity.class.getSimpleName();
     //public final static String PATH2 = "/sdcard/fifo9001";
     public final static String PATH = "/data/data/com.example.ndkfoo/v_pipe8";

     @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        readFromPipe();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    private void readFromPipe() {
        Log.i(TAG, "Attempt started");
        FileInputStream fis;
        String message = "";
        byte buffer[] = new byte[256];

        try {
            Log.i(TAG, "openning input stream");
            fis = new FileInputStream(PATH);
            Log.i(TAG, "input stream opened");
            FileDescriptor fd =  fis.getFD();
            int len = 0;
            do {
                len = fis.read(buffer);
                if(len > 0) {
                    String newmessage = new String(buffer,0, len, "US-ASCII");
                    message += newmessage;
                }
            } while (len == buffer.length);
            Log.i(TAG, "message: "+message);
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

解决方案

Use BufferedReader instead `FileInputStream

这篇关于Android - 在本机和Java应用程序之间使用管道的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆