【问题标题】:Android not able to find my JNI native library functionAndroid 无法找到我的 JNI 本机库函数
【发布时间】:2017-01-17 22:53:58
【问题描述】:

我用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 提供的 readelf)来做到这一点:

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 的问题吗?在这一点上我没有想法,Google 上的结果和其他看似重复的 SO 问题都没有帮助。

【问题讨论】:

  • 在哪里调用 Initialize 方法?
  • zPayService.onCreate() 调用初始化。从我的活动类中的 onClickListener 调用 zPayTestTool.KiziStartTransaction() 函数 (public class zPayActivity extends Activity)
  • 在这种特殊情况下,我创建了一个服务和一个活动 (onCreate)。从 Activity 调用的 JNI 方法不起作用,在 Service 中调用的方法正在起作用。

标签: java android c++ android-ndk java-native-interface


【解决方案1】:

你需要在你的 build.gradle 中添加这个

externalNativeBuild {
        ndkBuild {
            path '<path to you android.mk file>'
        }
}

您可以右键单击 android studio 右侧的项目窗格中的应用程序文件夹 转到选项 将 c/c++ 代码链接到您的项目

【讨论】:

  • 我用的是ant,不是gradle。
【解决方案2】:

我发现了问题所在。在我的 AndroidManifest.xml 中,我将 process 属性设置为我的 &lt;service&gt; 元素,但没有设置为 &lt;application&gt;

<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 属性移动到&lt;application&gt;,它现在似乎可以工作了:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-12
    • 1970-01-01
    • 2014-08-25
    • 1970-01-01
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    • 2013-04-08
    相关资源
    最近更新 更多