1.下面通过一个HelloWorld案例来说明一下JNI利用NDK开发过程(步骤)
分析:我们在Win7系统下编译的C语言代码,我们知道C语言依赖操作系统,不能跨平台,所以我们要通过NDK工具把在Win7系统下编写的C代码,转化为可以在Linux(Linux2.6.6---Android内核)运行的二进制代码,最后通过JNI协议规范,Android中java代码就可以调用这个转化后的二进制代码运行。
(1)在Eclipse中新建一个Android工程,命名为"HelloWorld",如下:
接下来来到Android工程布局文件activity_main.xml,如下:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:paddingBottom="@dimen/activity_vertical_margin" 6 android:paddingLeft="@dimen/activity_horizontal_margin" 7 android:paddingRight="@dimen/activity_horizontal_margin" 8 android:paddingTop="@dimen/activity_vertical_margin" 9 tools:context="com.himi.helloworld.MainActivity" > 10 11 <Button 12 android:layout_centerHorizontal="true" 13 android:layout_centerVertical="true" 14 android:layout_width="wrap_content" 15 android:layout_height="wrap_content" 16 android:text="问C要Hello" 17 android:onClick="getHello"/> 18 19 </RelativeLayout>
布局效果如下:
(2)来到Android工程的MainActivity.java,如下:
1 package com.himi.helloworld; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.Toast; 7 8 public class MainActivity extends Activity { 9 10 //通过JNI,调用C/C++代码,在C中实现的 (不是在Java层实现的) 11 public native String getHelloFromC(); 12 @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.activity_main); 16 } 17 18 19 /** 20 * 按钮点击事件,获取C的hello问候 21 * @param view 22 */ 23 public void getHello(View view) { 24 Toast.makeText(this, "C代码问候:"+getHelloFromC(), 0).show(); 25 } 26 27 }
就这样一个Android工程的就搭建好了,接下来关于C代码:
(3)接下来在"HelloWorld"工程目录下,新建一个文件夹命名为" jni ",如下:
(4)在刚刚新建的" jni "文件夹下,我们新建一个hello.c文件,同时我们拷贝 jni.h 文件到 jni文件下,如下:
• hello.c :
1 #include <jni.h> 2 3 char* getHello() 4 { 5 //////// 6 return "hello Android From C"; 7 } 8 9 10 //jni协议给java调用 11 // 返回类型 方法名(Java_包名(使用"_"把包名分割)_类名_方法名 (参数) 12 13 //JNIEnv* env jni的结构体数据,jni系统实现 ; obj java对象 调用该jni方法的对象 14 jstring Java_com_himi_helloworld_MainActivity_getHelloFromC(JNIEnv* env, jobject obj) 15 { 16 char* res = getHello();//获取到C代码字符串结果 17 /** 18 * (**env).GetVersion(env); 19 * (*env)->GetVerison(env); 20 */ 21 //jstring (*NewStringUTF)(JNIEnv*, const chat*); 22 jstring jres = (**env).NewStringUTF(env,res); 23 24 return jres; 25 }
代码中,上面的getHello()是C语言代码;
下面的定义的 Java_com_himi_helloworld_MainActivity_getHelloFromC()方法是JNI协议的规范,这样写java才能调用getHello()方法,Java_com_himi_helloworld_MainActivity_getHelloFromC()起到过渡作用。
Java_com_himi_helloworld_MainActivity_getHelloFromC()方法的密码法则如下:
Java_com_himi_helloworld_MainActivity_getHelloFromC()
Java_(包名,包名使用‘_‘分割)_类名_Android(java)调用的方法名()
备注:jni.h文件作用是数据类型翻译,将JAVA语言的数据类型利用C的语法重新定义,实现2种不同的语法之间的数据类型转换。
• jni.h(导入进来的,NDK中platform有):
文件内容太多,截图一部分让大家感受一下