Android NDK JNI开发<2>
其他不废话!
步骤如下:
<1> : eclipse 启动/cgywin启动(目录已经设定好了,就等着输入编译命令);
<2> : 新建一个hellojnidemo android工程,在工程文件夹下新建一个jni文件夹,然后新建一个c扩展名的源文件,输入:
#include<jni.h> #include<stdio.h> #include<string.h> jstring Java_com_example_hellojnidemo_MainActivity_messageshow(JNIEnv* env, jobject thiz) { #if defined(__arm__) #if defined(__ARM_ARCH_7A__) #if defined(__ARM_NEON__) #define ABI "armeabi-v7a/NEON" #else #define ABI "armeabi-v7a" #endif #else #define ABI "armeabi" #endif #elif defined(__i386__) #define ABI "x86" #elif defined(__mips__) #define ABI "mips" #else #define ABI "unknown" #endif return (*env)->NewStringUTF(env, "ABI : " ABI" ->test jni demo !"); }
source code中预定义可以不要(在单一设备情况下).
忘了说了函数名一般的命名格式:
Java_packagename(点'.'换成下换线'_')_app工程名_函数名;
带参数的,前面两个固定参数保持不变,自己的参数从第三个开始,依次下去添加.
调用的时候只需要写出函数名和自己的参数列表就可以了.
<3> : 配置Android.mk文件如下:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := jni LOCAL_SRC_FILES := jni.c include $(BUILD_SHARED_LIBRARY)
如果不只是编译一个c文件,继续往后面加module可以只要一个,后面再废话这个地方.
<6> : Application.mk文件如下:
APP_ABI := all
<7> : 上面搞完了以后,android里面的activity等下写,先编译一下:切换到demo目录下
Administrator@LBDZ-20130822BY /cygdrive/d/ADB/android-ndk-r9d/samples/HelloJnidemo $ $NDK/ndk-build Android NDK: WARNING: APP_PLATFORM android-18 is larger than android:minSdkVersion 8 in ./AndroidManifest.xml [armeabi-v7a] Compile thumb : jni <= jni.c [armeabi-v7a] SharedLibrary : libjni.so [armeabi-v7a] Install : libjni.so => libs/armeabi-v7a/libjni.so [armeabi] Compile thumb : jni <= jni.c [armeabi] SharedLibrary : libjni.so [armeabi] Install : libjni.so => libs/armeabi/libjni.so [x86] Compile : jni <= jni.c [x86] SharedLibrary : libjni.so [x86] Install : libjni.so => libs/x86/libjni.so [mips] Compile : jni <= jni.c [mips] SharedLibrary : libjni.so [mips] Install : libjni.so => libs/mips/libjni.so
看到生成一堆so就代表成功了,然后看一看android工程下面的libs文件夹对应的各个子目录下是否都有了so文件,如果有了,就.so生成没什么问题了.
<7> : 接着把android activity里面的写完:添加一个Button用来测试就可以了,xml就不给了
package com.example.hellojnidemo; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity { private Button mShowJniBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mShowJniBtn=(Button)findViewById(R.id.button1); mShowJniBtn.setOnClickListener(new OnClickListener(){ @Override public void onClick(View arg0) { // TODO Auto-generated method stub Toast.makeText(MainActivity.this, messageshow(), Toast.LENGTH_SHORT).show(); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public native String messageshow(); static{ System.loadLibrary("jni"); } }
在java程序中要注意一个地方的是:so文件名和库名是两回事,库名是在android.mk文件中写好的,与.so文件名没有直接关系.所以java程序调用库时,使用android.mk约定的就可以了.
运行效果就是按button后一个气泡冒出来,显示jni返回的字符.
总结上面需要注意:
<1> : 函数名的命名方式和调用时的名字的区别;
<2> : 库名;
<3> : 调用方式.

浙公网安备 33010602011771号