android NDK实现

来源:互联网 发布:linux删除一个目录 编辑:程序博客网 时间:2024/04/28 02:45

前言:

前段时间一直研究android的Framework层代码,其中基本都设计到JNI,自己项目中有时候也用到这种技术,当然很多apk的一些关键性代码都用C/C++代码来实现,这样也提高了代码的安全性。所以在这里记录下,这里仅仅只是一个小小demo实现。
NDK的环境配置这里就不细说了,网上有很多文章关于NDK的环境配置。
先上我们的实现图:(调用C/C++代码,获取一段文字信息显示到界面上)


1.我们先创建一个android项目,这里仅仅只有一个activity,其中包含了一个textview。Activity代码:
public class MainActivity extends Activity {private TextView text;static{//加载我们的so库,通过Android.mk生成的so文件System.loadLibrary("jniTest");}//声明一个native修饰的方法,这个方法就是java层来调用C/C++代码的public native String get();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        text = (TextView) findViewById(R.id.text);        text.setText(get());    }}

2.然后项目中创建jni文件夹,在其中创建3个文件,分别是Android.mk、Application.mk、test.cpp。

这是我们生成的目录结构。
然后就是对我们生成的3个文件进行编译:
个人习惯,首先是实现我们的C++代码,也就是在Activity中get()方法要调用的C++代码。test.cpp代码:
#include <jni.h>#include <stdio.h>extern "C"{jstring Java_com_ndk01_MainActivity_get(JNIEnv *env,jobject thiz){printf("invoke get in c++\n");return env->NewStringUTF("Hello form Jni in !");}}

其中的jobject就是我们java层的对象,而JNIEnv就是与VM来交互,通过它来访问JNI提供的接口方法。
其中NewStringUTF()的方法中,返回的就是我们Activity中显示的信息。

然后就是我们的Android.mk了
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := jniTestLOCAL_SRC_FILES := test.cppinclude $(BUILD_SHARED_LIBRARY)
其中LOCAL_MODULE代表的就是我们Activity中的静态代码块所加载的库,而LOCAL_SRC_FILES代表的就是我们的C++代码实现的function。(这两个是必须要记住的,mk如果要做深入了解的可以自行去网上搜索文档进一步了解,这里仅仅分析下NDK实现流程)

接下来就是我们的Application.mk了
APP_ABI := armeabi
APP_ABI所代表的是当前CPU的架构平台的类型有以下几类,我这里只用了最常见的。


好了,我们基本工作都完成了,其实都是为了生成so文件来做准备的,然后我们执行cmd跳到当前项目的目录中;例如这就是我的目录:F:\Users\workspace\NDK01;
然后我们再执行ndk-build。这样就能在我们的工程目录的libs目录下生成我们的so文件了,这样就完成了我们一次JNI的实现。

这是我整个项目的目录结构,然后就可以运行我们的项目,接下来就可以看到界面显示C++返回java层的string信息了。
当然,JNI并非仅仅是这么简单,很多东西都非常重要列入mk文件的声明,这个如果代码写错了那我们就生成不了我们的so文件了,还有一些变量的命名为什么string变成了jstring,JNIEnv如何支撑java层与底层的交互等等这些都是非常关键的,对于了解android系统有很好的借鉴;如果有兴趣的可以去查阅相关资料。


0 0
原创粉丝点击