如何通过Android中的信号处理程序函数通过JNI调用Java函数 [英] How to call a Java function via JNI from a signal handler function in Android

查看:182
本文介绍了如何通过Android中的信号处理程序函数通过JNI调用Java函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是将信号从内核发送到运行在用户空间中的Android服务,接收到该信号后,该服务应向内核进行IOCTL调用.通过此ioctl调用从内核获取数据后,它必须显示给用户.为此,我从Java服务中调用了本机方法,该方法注册了sigaction结构,其中包括该信号的处理函数.该处理函数将进行IOCTL调用,并调用Java函数将字符串传递给Java服务.

My objective is to send a signal from kernel to a Android service running in the userspace.On receiving this signal, the service should make an IOCTL call back to the kernel. After it gets data from the kernel through this ioctl call,it has to display to the user. For this, i call a native method from my Java Service, which registers the sigaction structure, which includes the handler function for this signal. This handler function will make the IOCTL call and call a Java Function to pass the string to the Java service.

这是signal.java类

Here is the signal.java class

public class signal {
static{
    System.loadLibrary("signal");
}
public native String hello();

public String messageMe(String s)
{
    if(null != MainActivity.mUiHandler)
    {
        Message msgToActivity = new Message();
        msgToActivity.what = 0;

            msgToActivity.obj  = s; // you can put extra message here

        MainActivity.mUiHandler.sendMessage(msgToActivity);
    }

    System.out.println(s);
        return s;
}

}

我需要从信号处理程序中调用此"messageMe"函数. 这是本地的hello()函数,用于注册sigaction结构.

I need to call this "messageMe" function from the signal handler. Here is the native hello() function which registers the sigaction structure.

JNIEXPORT jstring JNICALL Java_com_example_service_signal_hello
(JNIEnv * env, jobject obj) {

 int configfd;
char buf[10];
/* setup the signal handler for SIG_TEST
 * SA_SIGINFO -> we want the signal handler function with 3 arguments
 */
struct sigaction sig;
sig.sa_sigaction = receiveData;
sig.sa_flags = SA_SIGINFO;
sigaction(SIG_TEST, &sig,NULL);
}

receiveData是处理程序函数.在这里.

The receiveData is the handler function. Here it goes.

void receiveData(int n, siginfo_t *info,void* unused) {
    char buf[200];
    char *msg = "hello world";
    int fd = -1;
    if ((fd = open("/dev/my_device", O_RDWR)) < 0) {
            perror("on");
            return;
    }
    if(ioctl(fd, READ_IOCTL, buf) < 0)
            perror("second ioctl");

     jstring jstr = (*env)->NewStringUTF(env, buf);
     jclass *clazz = (*env)->GetObjectClass(env, obj);
     jmethodID messageMe = (*env)->GetMethodID(env,clazz, "messageMe", "(Ljava/lang/String;)Ljava/lang/String;");
     jobject result = (*env)->CallObjectMethod(env,obj, messageMe, jstr);

    printf("message: %s\n", buf);

} 该处理函数应调用Java函数"messageMe",并将从内核读取的字符串作为参数传递.但是它没有环境变量JNIEnv *和jobject obj.当我在hello()函数中维护指向这些变量的全局指针,并在此处使用它们时,它给出了NoClassDefFoundError. 现在如何将字符串从该信号处理程序发送到Java函数?

} This handler function should call the Java function "messageMe" and pass the string it read from the kernel as an argument. But it does not have Environment variables JNIEnv * and jobject obj. When I maintained a global pointers to these variables in the hello() function, and used them here, it was giving NoClassDefFoundError. How do I now send the string from this signal handler to the Java function?

推荐答案

我有以下全局变量.我缓存了这些对象以备将来使用.

I have the following global variables. I cached these objects for future use.

JavaVM* vm;
static jclass cl;
static jobject ob;

在hello函数中,我为上述变量进行了全局引用.

In the hello function, i made global references for the above variables.

JNIEXPORT jstring JNICALL Java_com_example_service_signal_hello
(JNIEnv * env, jobject obj) {
(*env)->GetJavaVM(env,&vm);
ob = (*env)->NewGlobalRef(env,obj);
jclass clazz = (*env)->FindClass(env,"com/example/service/signal");
cl = (*env)->NewGlobalRef(env,clazz);
}

现在我在处理程序函数中使用了这些

Now I used these in the handler function

void receiveData(int n, siginfo_t *info,void* unused) {
//other code
JNIEnv* env = NULL;
    if(vm==NULL)
        return;
    (*vm)->AttachCurrentThread(vm,&env,0);
 jmethodID messageMe = (*env)->GetStaticMethodID(env,cl, "messageMe", "(Ljava/lang/String;)Ljava/lang/String;");
jobject result = (*env)->CallStaticObjectMethod(env,cl, messageMe, jstr);
}

我所做的一项更改是使用静态方法而不是常规方法.因此,我不必使用该类的特定实例.如果该方法不是静态的,则可以在CallObjectMethod中使用全局变量"ob".

One change I made was the use of static method instead of a normal one. So i didn't have to use a specific instance of the class. If the method is not static, the global variable "ob" can be used in the CallObjectMethod.

这篇关于如何通过Android中的信号处理程序函数通过JNI调用Java函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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