Android NDK开发入门
来源:互联网 发布:百度知道刷赞软件 编辑:程序博客网 时间:2024/05/17 23:15
网上一大堆的都是使用javah命令来生成头文件来完成JNI编写,但其实ADT集成NDK后,点点鼠标就可以了,懒人方法网上介绍很少,这边主要讲懒人JNI开发。
对于ADT配置NDK,请个人google或查看Android developer,这边不多做介绍。
1. 新建一个Android工程,我这边取名为JNI_Learn,一键生成后代码片段如下:
- public class JNI extends ActionBarActivity {
- static{
- System.loadLibrary("JNI_Learn");
- }
- public native int plus(int x, int y);
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_jni);
- if (savedInstanceState == null) {
- getSupportFragmentManager().beginTransaction()
- .add(R.id.container, new PlaceholderFragment())
- .commit();
- }
- Log.d("JNITest", "3+5=" + plus(3, 5));
- }
loadLibrary的话,里面的名字稍后我会再标注一下,这边主要是native层生成的so库的名字,需要去掉lib前缀和.so后缀。
声明native方法要在访问权限之后,其他声明之前,加一个native标记此方法实现在native层。
使用plus方法与正常使用无异。
2. 之后就是懒人操作了,在工程上右击鼠标,选择Android Tools->Add Native Support...
之后查看工程里面有两个文件
第一个是JNI_Learn.cpp,这个稍后详述。第二个是Android.mk,在Android编译中,都会寻找目录下是否存在Android.mk,然后根据这个文件进行编译。里面编写了具体的编译规则,打开文件后,内容如下:
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_LDLIBS := -llog
- LOCAL_MODULE := JNI_Learn
- LOCAL_SRC_FILES := JNI_Learn.cpp
- include $(BUILD_SHARED_LIBRARY)
其中LOCAL_PATH表示编译源文件的路径,LOCAL_LDLIBS表示编译模块时需要附加的连接器选项,LOCAL_MODULE表示最终编译出来模块的名称,LOCAL_SRC_FILES表示需要编译的源文件,include $(BUILD_SHARED_LIBRARY)表示最终编译成一个共享库文件。
3. 下面具体添加native层对plus方法的实现代码
- #include <jni.h>
- #include <android/log.h>
- #define LOG_TAG "JNITest"
- //log func
- //int __android_log_print(int prio, const char *tag, const char *fmt, ...)
- #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
- extern "C"
- JNIEXPORT int Java_com_example_jni_1</span>learn_JNI_plus");
- return x + y;
- }
使用了Android log将log打印到了logcat一样,想了解的可以自行查阅相关知识,这边没太大关系,这个也是在Android.mk中为什么需要增加LOCAL_LDLIBS原因。
extern “C”是必须要加的,因为C++和C编译后的导出函数原型不同,java只能call C类型的,所以需要将C++转化为C类型的,增加extern "C"声明。
JNIEXPORT声明他是一个导出函数。
方法名字必须以Java开头,然后包名和类名及方法名之间下划线隔开,如果不巧刚好你的包名中有下划线,那如何处理JNI中java包名含下划线情况呢?在前面加一个“1”。
这么简单程序,遇到几个错误:
第一个是说JNI Load Library失败,因为apk中可以看到so是不是被压缩进去了(更改apk后缀为rar,解压rar可以看到有个lib文件夹内有这个so),我这边看到压缩进去了,结果还是加载失败。原因在于loadLibrary的参数必须要不带前缀lib不加后缀.so才可以。
爆出undefined reference to,原因是由于我没有声明extern "C",java找不到C++声明方式的。
还有就是包名中恰好出现下划线,比如JNI_Learn,需要更改为_1才可以规避。
还有就是使用LOG,必须要在Android.mk中增加LOCAL_LDLIBS。
- Android ndk开发入门
- Android NDK开发入门
- Android -- NDK开发入门
- Android NDK开发入门
- Android NDK开发入门
- Android NDK开发入门
- Android NDK开发入门
- Android NDK开发入门
- Android NDK开发入门实例
- Android NDK开发入门实例
- Android NDK开发轻松入门
- Android NDK开发轻松入门
- Android NDK开发入门实例
- Android NDK开发轻松入门
- Android NDK开发轻松入门
- Android NDK开发轻松入门
- Android NDK开发轻松入门
- Android NDK开发轻松入门
- select函数详解及实例分析
- maven里的setting文件详解
- 设计模式-----命令模式
- MYsql 查询 查询当前月份的数据
- iOS网络监测如何区分2、3、4G(Reachability)
- Android NDK开发入门
- 【程序员项目经理】成功经理人的34个好习惯
- iOS开源库--最全的整理
- 安卓开发中Theme.AppCompat.Light的解决方法
- Selenium WebDriver java 简单实例
- Oracle中connect by...start with...的使用
- 录制脚本badboy工具使用手册
- iOS应用程序生命周期(前后台切换,应用的各种状态)详解
- 客户端开发与服务器端开发的区别