Android找不到我的JNI原生库函数
Android not able to find my JNI native library function
我使用javah
生成本地JNI函数:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_ttm_zpay_zPayTestTool */
#ifndef _Included_com_ttm_zpay_zPayTestTool
#define _Included_com_ttm_zpay_zPayTestTool
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_ttm_zpay_zPayTestTool
* Method: KiziStartTransaction
* Signature: ()[B
*/
JNIEXPORT jbyteArray JNICALL Java_com_ttm_zpay_zPayTestTool_KiziStartTransaction
(JNIEnv * env, jobject)
{
return env->NewByteArray(10);
}
#ifdef __cplusplus
}
#endif
#endif
对于以下Java类:
package com.ttm.zpay;
public class zPayTestTool
{
public native byte[] KiziStartTransaction();
}
我验证了本机函数已成功编译到我的APK打包的最终*.so文件中。我使用readelf -Ws lib.so
(NDK提供的自述):
5: 0015fa15 10 FUNC GLOBAL DEFAULT 8 Java_com_ttm_zpay_zPayTestTool_KiziStartTransaction
在logcat输出中,我得到以下内容:
01-17 01:06:02.306 7017 7017 W dalvikvm: No implementation found for native Lcom/ttm/zpay/zPayTestTool;.KiziStartTransaction:()[B
01-17 01:06:02.306 7017 7017 D AndroidRuntime: Shutting down VM
01-17 01:06:02.311 7017 7017 W dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x40ccd930)
01-17 01:06:02.316 3556 3758 D AudioHardware: openPcmOut_l() mPcmOpenCnt: 0
01-17 01:06:02.321 7017 7017 E AndroidRuntime: FATAL EXCEPTION: main
01-17 01:06:02.321 7017 7017 E AndroidRuntime: java.lang.UnsatisfiedLinkError: Native method not found: com.ttm.zpay.zPayTestTool.KiziStartTransaction:()[B
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at com.ttm.zpay.zPayTestTool.KiziStartTransaction(Native Method)
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at com.ttm.zpay.zPayActivity.OnKiziStartTransaction(zPayActivity.java:97)
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at com.ttm.zpay.zPayActivity.access$1(zPayActivity.java:95)
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at com.ttm.zpay.zPayActivity$1.onClick(zPayActivity.java:90)
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at android.view.View.performClick(View.java:4204)
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at android.view.View$PerformClick.run(View.java:17355)
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:725)
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:92)
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at android.os.Looper.loop(Looper.java:137)
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5041)
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at java.lang.reflect.Method.invokeNative(Native Method)
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:511)
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
01-17 01:06:02.321 7017 7017 E AndroidRuntime: at dalvik.system.NativeStart.main(Native Method)
01-17 01:06:02.331 3837 3848 W ActivityManager: Force finishing activity com.ttm.zpay/.zPayActivity
更奇怪的是,我在这个库中已经有了另一个本机方法,使用相同的命名约定,但用于不同的java类,效果非常好。这只是上面的一个导致了问题。
请参阅下面工作的JNI函数的代码。
Java:
package com.ttm.zpay;
public class zPayService extends Service
{
public native boolean Initialize();
}
C++:
extern "C"
{
JNIEXPORT bool JNICALL Java_com_ttm_zpay_zPayService_Initialize(JNIEnv* env, jobject obj)
{
// Do stuff
}
}
因此,归根结底:为我的zPayTestTool
java类映射的本机方法不起作用,但映射到zPayService
java类的一个本机方法起作用很好。
我到底做错了什么?这是我的AndroidManifest.xml的问题吗?在这一点上,我没有想法,谷歌上的结果和SO上其他看似重复的问题也于事无补。
您需要将其添加到您的build.gradle 中
externalNativeBuild {
ndkBuild {
path '<path to you android.mk file>'
}
}
或
你可以右键点击android工作室右侧项目窗格中的应用程序文件夹转到选项将c/c++代码链接到您的项目
我发现了问题所在。在我的AndroidManifest.xml中,我将process
属性设置为<service>
元素,但没有设置<application>
:
<application
android:name="com.ttm.zpay.zPayApplication"
android:allowBackup="true"
android:label="@string/app_name"
android:persistent="true" >
<service
android:name="com.ttm.zpay.zPayService"
android:exported="true"
android:process="com.ttm.zPayService" >
</service>
<activity
android:name="com.ttm.zpay.zPayActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
无论出于何种原因,这都会导致在活动类或其使用的类中定义的任何JNI方法都无法工作。我将process
属性移到了<application>
,现在它似乎可以工作了:
<application
android:name="com.ttm.zpay.zPayApplication"
android:allowBackup="true"
android:label="@string/app_name"
android:persistent="true"
android:process="com.ttm.zPayService">
<service
android:name="com.ttm.zpay.zPayService"
android:exported="true">
</service>
<activity
android:name="com.ttm.zpay.zPayActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
相关文章:
- 库函数需要一个 std::function<void(void)>,如何传入类函数?
- 有没有一个 c++ gmp 库函数与 python gmpy2 库 divm(..) 函数相同?
- 好友库函数可以访问子数据
- 覆盖程序中的标准 C 库函数C++
- VS2017 #error: : snprintf 的宏定义与标准库函数声明冲突
- Android NDK - C++ 异常会导致第三方原生库崩溃
- 在不使用内置库函数的情况下添加字符串,我做错了什么?
- 返回time()库函数的数据类型
- 将C++中的多个参数传递给MatLab共享库函数
- 从另一个动态链接库项目调用静态库函数
- 如何将.cpp C++原生库导入 Android Studio
- 导入的库函数是否可以在内存中移动
- 带参数的线程调用库函数
- 在 MASM 中调用标准库函数
- char concat c++ 没有库函数
- 为什么C++ std::min_element 库函数接受采用布尔返回类型的函数对象的函子,而不是像 C 中那样的 in
- 如何在将指针传递给库函数时处理内存管理
- 使库函数模板化以避免编译器指令是否有益?
- 如何链接和调用安卓工作室预构建静态原生库的函数
- Android找不到我的JNI原生库函数