简体   繁体   中英

Android not able to find my JNI native library function

I used javah to generate a native JNI function:

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

For the following Java class:

package com.ttm.zpay;

public class zPayTestTool
{
   public native byte[] KiziStartTransaction();
}

I verified that the native function is successfully compiled into my final *.so file packaged with my APK. I did so by using readelf -Ws lib.so (readelf provided by the NDK):

5: 0015fa15    10 FUNC    GLOBAL DEFAULT    8 Java_com_ttm_zpay_zPayTestTool_KiziStartTransaction

In the logcat output, I get the following:

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

What's even more odd is I already have another native method in this library using the same naming convention but for a different java class that works perfectly fine. It's only the one above that causes problems.

See the code for the working JNI function below.

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

So at the end of the day: Native methods mapped for my zPayTestTool java class do not work, but the one native method mapped to zPayService java class works fine.

What on earth am I doing wrong? Is this an issue with my AndroidManifest.xml? I'm out of ideas at this point and results on Google and other seemingly duplicate questions on SO aren't helping.

you need to add this in your build.gradle

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

OR

You can right click on app folder in project pane which is on right side of android studio go to option link c/c++ code to your project

I figured out what the issue was. In my AndroidManifest.xml, I had the process attribute set to my <service> element but not <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>

For whatever reason, this causes any JNI methods defined in the activity class or classes it uses to not work. I moved the process attribute to <application> and it seems to work now:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM