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.