为什么 app_process run java 方法在调用 JNI 后被杀死

发布于 2025-01-19 17:59:48 字数 1681 浏览 4 评论 0原文

这就是我所做的:

  1. 使用 android studio 模板创建一个 Native C++ 项目
  2. 创建一个类 com.jnitest.app.JNIInterface
package com.jnitest.app;

public class JNIInterface {
    public static native String getString();
    public static native String getName();
}


使用 native-lib.cpp

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_jnitest_app_JNIInterface_getString(JNIEnv *env, jclass thiz) {
    std::string name = "return String from JNIInterface";
    return env->NewStringUTF(name.c_str());
}

extern "C"
JNIEXPORT jstring JNICALL
Java_com_jnitest_app_JNIInterface_getName(JNIEnv *env, jclass clazz) {
    std::string name = "return name from JNIInterface";
    return env->NewStringUTF(name.c_str());
}
  1. 创建一个测试类 com.jnitest.app.JNITest
package com.jnitest.app;

public class JNITest {
    {
        System.loadLibrary("app");
    }
    public static void main(String[] args) {
        System.out.println("Hello from JNITest");
        System.out.println("String from JNI: " + JNIInterface.getString());
    }
}

  1. 构建推送并运行
adb push .\build\intermediates\apk\debug\app-debug.apk /data/local/tmp/app-debug.jar 

adb shell CLASSPATH=/data/local/tmp/app-debug.jar  app_process ./ com.jnitest.app.JNITest
  1. 获取输出
Hello from JNITest
Killed

为什么我无法得到正确的结果?

Here is what I do :

  1. create a Native C++ project use android studio template
  2. create a class com.jnitest.app.JNIInterface
package com.jnitest.app;

public class JNIInterface {
    public static native String getString();
    public static native String getName();
}


with the native-lib.cpp

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_jnitest_app_JNIInterface_getString(JNIEnv *env, jclass thiz) {
    std::string name = "return String from JNIInterface";
    return env->NewStringUTF(name.c_str());
}

extern "C"
JNIEXPORT jstring JNICALL
Java_com_jnitest_app_JNIInterface_getName(JNIEnv *env, jclass clazz) {
    std::string name = "return name from JNIInterface";
    return env->NewStringUTF(name.c_str());
}
  1. create a test class com.jnitest.app.JNITest
package com.jnitest.app;

public class JNITest {
    {
        System.loadLibrary("app");
    }
    public static void main(String[] args) {
        System.out.println("Hello from JNITest");
        System.out.println("String from JNI: " + JNIInterface.getString());
    }
}

  1. build push and run
adb push .\build\intermediates\apk\debug\app-debug.apk /data/local/tmp/app-debug.jar 

adb shell CLASSPATH=/data/local/tmp/app-debug.jar  app_process ./ com.jnitest.app.JNITest
  1. get output
Hello from JNITest
Killed

Why I cannot get the right result ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半城柳色半声笛 2025-01-26 17:59:49

我相信,由于在较新的Android版本(&GT; 23)中,因此在安装后,APK中的SO文件根本不会被压缩。

为确保这些文件不会被压缩,请更改build.gradle脚本,以下是:

android {
    ...
    packagingOptions {
        jniLibs {
            useLegacyPackaging false
        }
    }
    ...
}

在我的项目中,我使用的gradle版本为6.7.1,而相应的com.android.tool.tools.build版本是4.2.0。其他较新的组合也应应用此jnilibs块。

之后,您可以将APK或JAR视为特殊文件夹,通过附加拼写标记()。

如果要访问APK中的文件夹的内容(包含SO文件的文件夹),则可以运行一个命令,例如:

ld_library_path =/path/to/apk/apk/temp.ap.ap.ap.ap./lib/abi class =/ path/to/apk/temp.ap.apk app_process/system/bin com.package.name.name.main

其中lib/abi insem temp.ap.apk包含您想在com中使用的so files .package.name.main。

一个很棒的技巧。就像魅力一样。

I believe since in newer android version(>23), the so files inside apk will not be compressed at all for fewer space occupation after installation.

To make sure those so files will not be compressed, change the build.gradle script of the app module to this:

android {
    ...
    packagingOptions {
        jniLibs {
            useLegacyPackaging false
        }
    }
    ...
}

In my project, the gradle version I used is 6.7.1, and the corresponding com.android.tools.build version is 4.2.0. Other newer combination should also apply this jniLibs block.

After this, you could treat the apk or jar as a special folder by appending an exclamation mark(!).

If you want to access the content of the folder inside apk (a folder containing so files), you could run a command like:

LD_LIBRARY_PATH=/path/to/apk/temp.apk!/lib/abi CLASSPATH=/path/to/apk/temp.apk app_process /system/bin com.package.name.Main

Where the lib/abi inside temp.apk contains the so files you wanna use in com.package.name.Main.

A fantastic trick. Works like a charm.

心碎无痕… 2025-01-26 17:59:48

我也遇到了这个问题。 Classloader找不到本地库。尝试以下内容。

  1. uselegacyPackaging false需要添加到build.gradle,以便不压缩LIB,并且可以直接从内部APK加载。
android {
    packagingOptions {
        jniLibs {
            useLegacyPackaging false
        }
    }
}
  1. 以这种方式加载您的本地库。
package com.jnitest.app;

public class JNITest {
    public static void main(String[] args) {
        System.out.println("Hello from JNITest");
        System.out.println("String from JNI: " + JNIInterface.getString());
    }
    static {
        String libPath = System.getenv("CLASSPATH") +
                "!/lib/" + Build.SUPPORTED_ABIS[0] +
                "/libapp.so";
        System.err.println("Loading shared library: " + libPath);
        System.load(libPath);
    }
}

I had this problem too. Native library is not found by ClassLoader. Try the following.

  1. The useLegacyPackaging false needs to be added to build.gradle so that libs are not compressed and can be directly loaded from inside apk.
android {
    packagingOptions {
        jniLibs {
            useLegacyPackaging false
        }
    }
}
  1. Load your native library this way.
package com.jnitest.app;

public class JNITest {
    public static void main(String[] args) {
        System.out.println("Hello from JNITest");
        System.out.println("String from JNI: " + JNIInterface.getString());
    }
    static {
        String libPath = System.getenv("CLASSPATH") +
                "!/lib/" + Build.SUPPORTED_ABIS[0] +
                "/libapp.so";
        System.err.println("Loading shared library: " + libPath);
        System.load(libPath);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文