Android - 在本机和Java应用程序之间使用管道 [英] Android - Using pipe between native and java apps
问题描述
我正在开发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();
}
}
}
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屋!