当前位置: 首页 > 知识库问答 >
问题:

如何通过JNI从Android中的信号处理函数调用Java函数

华修永
2023-03-14

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

这里是signal.java班

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”函数。这里是注册sigaction结构的本机hello()函数。

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);
}

接收器数据是处理函数。开始了。

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*和jject obj。当我在hello()函数中维护指向这些变量的全局指针并在这里使用它们时,它会给出NoClassDefFoundError。我现在如何将字符串从这个信号处理程序发送到Java函数?

共有2个答案

简景焕
2023-03-14

据我所知,GetObjectClass方法返回的是jclass,而不是jclass*

receiveData 函数中,应将

jclass *clazz = (*env)->GetObjectClass(env, obj);

通过

jclass clazz = (*env)->GetObjectClass(env, obj);
甘兴学
2023-03-14

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

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

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

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);
}

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

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”。

 类似资料:
  • 问题内容: 我想在我的Android应用程序中对某些Java代码进行同步调用。 我的Java代码: 我的JavaScript代码: 当我点击按钮时,按钮进入按下状态。我可以在控制台日志中看到。一切正常,直到这里。 问题是,按钮永远不会回到其正常状态。它保持在按下状态。也许JavaScript执行中断了还是什么? 为什么按钮从不返回其正常状态? 问题答案: 我认为这不是让JavaScript执行Ja

  • 问题内容: 我真的很难弄清楚如何使用JNI从Objective-C调用Java函数。 我首先要说的是,我对Java并不了解很多,但是对Obj- C非常熟悉。我有一个带有单个方法的Java类,需要从我的应用程序包中调用它。该jar位于包中的Resources文件夹内,并且我将其设置为,它被检查并包含2个jar文件的名称(主要是一个,一个依赖)。 我正在通过调用来启动虚拟机,然后尝试使用该类来查找类,

  • 我实现了一个自定义POSIX信号处理程序参考:http://blog.httrack.com/blog/2013/08/23/catching-posix-signals-on-android/ 它们似乎是艺术的平台限制。 通过信号处理程序方法从JNI调用java方法,是否有变通方法或任何其他实现方法。 如果没有,那么是否有替代方案来捕获本机崩溃并传播到应用程序?

  • 问题内容: 我正在尝试从外部PHP文件将JavaScript函数调用为JavaScript脚本。我的代码又大又不同,所以我在这里编写示例代码。 这是我的PHP代码: 这是我的JavaScript代码: 这就是我想要做的。 我 原来的 PHP文件不包含这些数学函数,但是想法是相同的。 如果一些它怎么没有一个妥善的解决办法,那么可能你 请 提出一种替代,但它应该从外部PHP调用值。 问题答案: 是的,

  • 问题内容: 我是AWS Lambda的新手,我已使用处理程序创建了Lambda函数 这是自定义处理程序,现在我想从我的Java程序中调用它,我需要如何做。 问题答案: 此类中的2种方法应该可以为您提供帮助。一种是用于需要传递有效负载的情况,另一种是用于有效负载为null的情况。 但是,您需要记住一件事:函数名称可能与处理程序不同(后者在)。调用其功能时 不 使用该处理程序名称。 因此,如果您有一个

  • 问题内容: 表: 有了答案,我在这里得到了利用$ compile的这种方式 现在,当单击按钮时,我什至调用一个模态,并命令对象使用ng-model 感谢您的帮助,它运作良好。 问题答案: 编辑 :添加了用于演示 $ compile 用法的代码段 在html中,只有一个用于初始化应用程序的标签和一个用于初始化控制器的div。 在controller中,两个链接被创建为简单字符串,但分别具有两个,然后