Android JNI本机C功能呼叫杀死活动

 2023-01-20    283  

问题描述

什么有效:
我有一个运行TUN/TAP Service的C可执行文件,以及两个Shell Scrips(要配置” IP路由”和” Iptables”),该端子在终端中运行良好,全部运行为root.

什么不起作用:
我正在尝试创建一个Android应用程序,以在按下按钮后运行C可执行文件和Shell脚本.我最初这样做是这样,OnClick将使用ProcessBuilder创建一个过程,如下所示:

Android JNI本机C功能呼叫杀死活动

final Button button1 = ...
...
public void onClick(View v) {
    String ip_address = edIPAddress.getText().toString();
    Process process;
    try {
        process = new ProcessBuilder()
            .command("/system/bin/su", "-c", "/data/tuntapserv/armeabi/mytunserv " + ip_address)
            .redirectErrorStream(true)
            .start();

        InputStream in = process.getInputStream();
        OutputStream out = process.getOutputStream();

        pOutput.append("TUN/TAP IS CONFIGURED!\n");
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();             
    }
}

据我所知,这应该很好,但是实际上,mytunserv会在随机时间后停止工作. MyTunServ将开始我的TUN/TAP,但是几分钟后我去检查” IP路线”时,我会看到Tun/Tap停止并消失了.同样,我尝试了runtime.exec,即使这似乎使用ProcessBuilder,并且遇到了同样的问题.

i然后移动到使用线程而不是进程,这似乎适用于shell脚本.

...
final Button button2 = ...
...
    public void onClick(View v) {
        sThread = new ScriptThread();
        sThread.start();
    }
...

    private class ScriptThread extends Thread {
        @Override
        public void run() {
            Process process;
            try {
                process = new ProcessBuilder()
                    .command("/system/bin/su","-c","/system/bin/sh /data/tuntapserv/armeabi/setup_ip.sh")
                    .redirectErrorStream(true)
                    .start();

                InputStream in = process.getInputStream();
                OutputStream out = process.getOutputStream();

                pOutput.append("SCRIPT FINISHED!\n");

                while(true) {
                    Thread.sleep(0);
                }

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();             
            }
        }
    }

这似乎至少适用于两个外壳脚本.我最终放弃了这种方法,以称MyTunServ认为该过程或线程必须被Java线程处理程序杀死,这在我的研究中似乎是不可预测的.取而代之的是,我搬到了JNI上,因为这似乎比为C可录和外壳脚本的硬编码更合适.

所以这是我最近的问题,也是我在寻求帮助.

这是我的JNI设置:

#include <jni.h>
...
JNIEXPORT jint JNICALL Java_android_1sp_1api_sample_SetupTunTap_runtun(JNIEnv * env,jobject obj,jstring ip_address){
    jchar *ip;
    jboolean iscopy;
    ip=(*env)->GetStringUTFChars(env, ip_address, &iscopy);
    ...
    (*env)->ReleaseStringUTFChars(env, ip_address, ip);
    ...
}
...

上面的C代码变成liblmytunserv.so.

package android_sp_api.sample;...
public class SetupTunTap extends AnotherActivity {

    static 
    {
        System.loadLibrary("lmytunserv");
    }

    public native int runtun(String ip_address);
    ...

        final Button button1 = ...
    ...
    public void onClick(View v) {
        String ip_address = edIPAddress.getText().toString();

        SetupTunTap myTun = new SetupTunTap();

        myTun.runtun(ip_address);

        pOutput.append("TUN/TAP IS CONFIGURED!\n");
    }
...

根据我可以看出的,C代码应该能够调用未jniexport’ED的C代码中的其他函数. jniexport只是使Java代码与C代码相互作用的一种方式.

无论如何,现在我的问题是,在我按Button1关闭”活动”关闭并返回我的主菜单活动后,在调试或运行该应用程序时.在调试中,它说:” …. dalvikvm [localhost:8602]”,在ddms中,设备保持”在线”. LogCat不会输出任何内容,以暗示活动退出/崩溃.并在输入Setuptuntap活动后,通过显示信息来恢复LogCat,但在按下Button1时切勿输出任何内容,并且屏幕会闪烁黑色并将其恢复为我的主菜单活动.这是LiblmyTunServ加载的logcat中的一部分:

logcat输出:

...

07-30 16:30:19.531: D/dalvikvm(4716): Trying to load lib /data/data/android_sp_api.sample/lib/liblmytunserv.so 0x41688d20

07-30 16:30:19.531: D/dalvikvm(4716): Added shared lib /data/data/android_sp_api.sample/lib/liblmytunserv.so 0x41688d20

07-30 16:30:19.531: D/dalvikvm(4716): No JNI_OnLoad found in /data/data/android_sp_api.sample/lib/liblmytunserv.so 0x41688d20, skipping init

如何进一步调试?如果我在” mytun.runtun(ip_address)”上设置一个断点;然后,我可以在Eclipse上看到调试接口中的所有变量.如果我超过了这一点,则活动断开连接,并且我只会在logcat中看到.so lib文件加载.我猜想我的JNI设置一定是错误的,所以我思考过程中任何地方的任何建议都会很棒.

硬件:
三星Galaxy Nexus v4.0.4(根)

文件:

  • mytunserv = C Exectuable

  • setup_ip.sh = shell脚本

  • setup_ip1.sh = shell脚本

  • setuptuntap.java

  • liblmytunserv.so(放置在/libs/armeabi,/libs/armeabi-v7a,/libs/x86)

我需要的东西:
C库中的本机” runtun”功能liblmytunserv.So在一段时间内永远运行(1)无限循环.当Java代码调用函数(按下Button1一次)时,我需要该函数才能永远运行. Costable运行后,运行Shell Scripts setup_ip.sh和setup_ip1.sh.我如何使C可执行直接运行?

让我知道您是否需要更多信息,谢谢您的时间.

推荐答案

在您的jni

JNIEXPORT jint JNICALL Java_android_1sp_1api_sample_SetupTunTap_runtun(JNIEnv * env,jobject obj,jstring ip_address)

活动

package android_sp_api.sample;

这些需要匹配;)

编辑:
五分之四的就是这样.另外,也发布爪哇一侧,但我希望它看起来像

class SetupTunTap
{
   public native int runtun(String ip_address);

///
}

因此,setuptuntap类也是\

edit2:whoopse,不需要编辑.只是包装名称.

以上所述是小编给大家介绍的Android JNI本机C功能呼叫杀死活动,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/25979.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。