Android(java)学习笔记257:JNI之helloword案例(利用NDK工具)
2015-09-15 21:31
686 查看
1.逻辑思路过程图:
2.下面通过一个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,如下:
布局效果如下:
(2)来到Android工程的MainActivity.java,如下:
就这样一个Android工程的就搭建好了,接下来关于C代码:
(3)接下来在[b]"HelloWorld"工程目录下,新建一个文件夹命名为" jni ",如下:[/b]
(4)在刚刚新建的" jni "文件夹下,我们新建一个hello.c文件,同时我们拷贝 jni.h 文件到 jni文件下,如下:
• hello.c :
代码中,上面的getHello()是C语言代码;
下面的定义的 Java_com_himi_helloworld_MainActivity_getHelloFromC()方法是JNI协议的规范,这样写java才能调用getHello()方法,[b]Java_com_himi_helloworld_MainActivity_getHelloFromC()起到过渡作用。[/b]
[b][b]Java_com_himi_helloworld_MainActivity_getHelloFromC()方法的密码法则如下:[/b][/b]
[b][b][b] Java_com_himi_helloworld_MainActivity_getHelloFromC()[/b][/b][/b]
[b][b][b] Java_(包名,包名使用'_'分割)_类名_Android(java)调用的方法名()[/b][/b][/b]
备注:jni.h文件作用是数据类型翻译,将JAVA语言的数据类型利用C的语法重新定义,实现2种不同的语法之间的数据类型转换。
• jni.h(导入进来的,NDK中platform有):
文件内容太多,截图一部分让大家感受一下
(5)上面准备好的hello.c 和jni.h都是在Win7系统下编写的,但是我们想让它在Android(Linux2.6.6)环境下运行,不得不介绍一个工具:NDK
搜索下载NDK,我的是win7 32位系统,下载的是android-ndk-r9c_x86.zip,大家看到了这是一个压缩文件,只要解压即可(无需安装),解压效果如下:
接下来要在环境变量中配置PATH路径,这样才能直接在Win7 系统的命令行下运行,我的配置完毕了,下面进入命令行窗口使用 "ndk-build",如下:
出现这样的问题,一方面说明ndk工具配置正确,另一方面说明没有正确运行。这个问题是因为:这需要在工程目录下运行命令行才能,什么工程呢?就是我们编写的Android工程”HelloWorld",让我们先找到”HelloWorld"的工程目录,如下:
然后,在上面的工程目录下,运行" ndk-build"的cmd命令,如下:
虽然,出现了警告,但是说明之前的错误解决了。现在出现这个问题是因为红色部分:我们的Android工程下jni文件夹下找不到Android.mk文件,该怎么办呢?我们自己在jni文件下创建这个Android.mk文件即可,如下:
新建完了Android.mk,但是内部的内容该写什么呢?不急,大家来到ndk的解压目录中docs(帮助文档)文件夹下,如下:
打开之后的效果图如下:
复制到Android工程的Android.mk文件下,如下:
修改之后,文件如下:
这时候我们再来运行"ndk-build"命令如下:
刷新工程,看到如下结果,Window下动态库文件(.dll) Linux下动态库文件(.so):
上面我们是在win7系统下,生成了可以在Linux系统下运行的代码libhellojni.so,这就是前面提到的交叉编译,这里使用的交叉编译的工具是NDK.
(6)接下来就是让java代码调用" libhellojni.so",进入MainActivity,如下:
(7)布署这个Android的"HelloWorld"工程到模拟器下,效果如下:
点击"问C要Hello",如下:
2.下面通过一个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,如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.himi.helloworld.MainActivity" > <Button android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="问C要Hello" android:onClick="getHello"/> </RelativeLayout>
布局效果如下:
(2)来到Android工程的MainActivity.java,如下:
package com.himi.helloworld; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Toast; public class MainActivity extends Activity { //通过JNI,调用C/C++代码,在C中实现的 (不是在Java层实现的) public native String getHelloFromC(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } /** * 按钮点击事件,获取C的hello问候 * @param view */ public void getHello(View view) { Toast.makeText(this, "C代码问候:"+getHelloFromC(), 0).show(); } }
就这样一个Android工程的就搭建好了,接下来关于C代码:
(3)接下来在[b]"HelloWorld"工程目录下,新建一个文件夹命名为" jni ",如下:[/b]
(4)在刚刚新建的" jni "文件夹下,我们新建一个hello.c文件,同时我们拷贝 jni.h 文件到 jni文件下,如下:
• hello.c :
#include <jni.h> char* getHello() { //////// return "hello Android From C"; } //jni协议给java调用 // 返回类型 方法名(Java_包名(使用"_"把包名分割)_类名_方法名 (参数) //JNIEnv* env jni的结构体数据,jni系统实现 ; obj java对象 调用该jni方法的对象 jstring Java_com_himi_helloworld_MainActivity_getHelloFromC(JNIEnv* env, jobject obj) { char* res = getHello();//获取到C代码字符串结果 /** * (**env).GetVersion(env); * (*env)->GetVerison(env); */ //jstring (*NewStringUTF)(JNIEnv*, const chat*); jstring jres = (**env).NewStringUTF(env,res); return jres; }
代码中,上面的getHello()是C语言代码;
下面的定义的 Java_com_himi_helloworld_MainActivity_getHelloFromC()方法是JNI协议的规范,这样写java才能调用getHello()方法,[b]Java_com_himi_helloworld_MainActivity_getHelloFromC()起到过渡作用。[/b]
[b][b]Java_com_himi_helloworld_MainActivity_getHelloFromC()方法的密码法则如下:[/b][/b]
[b][b][b] Java_com_himi_helloworld_MainActivity_getHelloFromC()[/b][/b][/b]
[b][b][b] Java_(包名,包名使用'_'分割)_类名_Android(java)调用的方法名()[/b][/b][/b]
备注:jni.h文件作用是数据类型翻译,将JAVA语言的数据类型利用C的语法重新定义,实现2种不同的语法之间的数据类型转换。
• jni.h(导入进来的,NDK中platform有):
文件内容太多,截图一部分让大家感受一下
(5)上面准备好的hello.c 和jni.h都是在Win7系统下编写的,但是我们想让它在Android(Linux2.6.6)环境下运行,不得不介绍一个工具:NDK
搜索下载NDK,我的是win7 32位系统,下载的是android-ndk-r9c_x86.zip,大家看到了这是一个压缩文件,只要解压即可(无需安装),解压效果如下:
接下来要在环境变量中配置PATH路径,这样才能直接在Win7 系统的命令行下运行,我的配置完毕了,下面进入命令行窗口使用 "ndk-build",如下:
出现这样的问题,一方面说明ndk工具配置正确,另一方面说明没有正确运行。这个问题是因为:这需要在工程目录下运行命令行才能,什么工程呢?就是我们编写的Android工程”HelloWorld",让我们先找到”HelloWorld"的工程目录,如下:
然后,在上面的工程目录下,运行" ndk-build"的cmd命令,如下:
虽然,出现了警告,但是说明之前的错误解决了。现在出现这个问题是因为红色部分:我们的Android工程下jni文件夹下找不到Android.mk文件,该怎么办呢?我们自己在jni文件下创建这个Android.mk文件即可,如下:
新建完了Android.mk,但是内部的内容该写什么呢?不急,大家来到ndk的解压目录中docs(帮助文档)文件夹下,如下:
打开之后的效果图如下:
复制到Android工程的Android.mk文件下,如下:
修改之后,文件如下:
这时候我们再来运行"ndk-build"命令如下:
刷新工程,看到如下结果,Window下动态库文件(.dll) Linux下动态库文件(.so):
上面我们是在win7系统下,生成了可以在Linux系统下运行的代码libhellojni.so,这就是前面提到的交叉编译,这里使用的交叉编译的工具是NDK.
(6)接下来就是让java代码调用" libhellojni.so",进入MainActivity,如下:
(7)布署这个Android的"HelloWorld"工程到模拟器下,效果如下:
点击"问C要Hello",如下:
相关文章推荐
- import opencv for Android 例程总是显示错去
- android学习笔记(三)——Activity
- Android笔记 Activity&Intent
- Android——SoundPool的使用
- Android 多媒体——音频播放录制、视频播放、相机
- 0915Android基础之SoundPool
- android之gradle构建工具学习之路(二)
- Android 五种存储方式个人总结
- Android开发-Listview中显示不同的视图布局
- Android开发-Listview中显示不同的视图布局
- Android之Xutils
- [转]Android 中fill_parent与wrap_content的区别
- Android 多媒体应用:视频播放之Vitamio
- 字体的自动补全功能
- 反汇编android apk文件
- Android开发
- Android 学习第16课,java 包、类等相关的一些基础知识
- Android之ViewPager使用(用美女做的背景,给你疲惫的眼睛视觉冲击)
- android 图片裁剪,显示 指定压缩
- 关于android.support.v7.internal.widget.ActionBarOverlayLayout问题的解决