Android NDK

关于Android NDK:

简单来说,android中的NDK就是可以实现让JAVA调用c/c++程序的一个功能。将c/c++编译成一个库,然后由JAVA来使用,类似与c/c++中链接库或dll的概念。编译生成的库文件.so能够和JAVA应用程序一起打包成.apk。


至于使用NDK的一些利弊

优点:

(1)在反编译过程中,如果纯JAVA代码编写,那么很容易通过apk反编译出源程序,但是c/c++的反编译难度更高,确保了源代码的安全性

(2)就运行速度和效率上说,c/c++要优于JAVA

(3)编译成库文件后,还可以移植到其它平台上使用

缺点:

(1)虽然c/c++能提高速度和效率,但内部存在JAVA与c/c++相互调用的机制,增加了开销


个人见解:

Android开发基本上都是基于JAVA语言,但也支持NDK等交叉编译方式,将c/c++编译成库的形式,供JAVA来调用。但在NDK机制中,其c/c++的写法比一般的c程序要复杂(下面例子会有介绍),定义了不少规范。在编程语言中,JAVA的定义就是完全的面向对象,而c++为了向下兼容c,也支持面向过程式编程,所以其面向对象的特性比JAVA稍弱。在一般的Android开发中,其实纯JAVA代码便可以满足设计的需要,NDK的引进的好处,实际上还是有利于防止我们的apk被反编译。


下面我们以一个例子来看看NDK的编写流程,在此之前,我们应该还要进行NDK的下载,及配置NDK的环境。但在此处不涉及此流程,具体参照网上的教程即可。


我用的开发环境是Android Studio 1.3

1、我们新建了一个工程后,在此工程目录下新建一个名为jni的文件(注意,文件名字必须以jni命名),并且在jni文件中新建.c和.mk文件(我的是Hello.c和Android.mk)

2、在.mk文件中加入


LOCAL_PATH := $(call my-dir)            
include $(CLEAR_VARS)
LOCAL_MODULE    := Hello      //要生成的.so库的名字
LOCAL_SRC_FILES := Hello.c        //你的c文件
include $(BUILD_SHARED_LIBRARY)


在.c文件中加入代码,就是编辑自己想要实现的功能,例如这个例子就打印出HelloWorld

#include <string.h>
#include <jni.h>

jstring
Java_com_example_cheng_myapplication_MainActivity_helloWorld( JNIEnv* env,
                                                  jobject thiz )
{
    return (*env)->NewStringUTF(env, "HelloWorld");
}
其中

jstring代表返回值

Java_com_example_cheng_myapplication_MainActivity_helloWorld代表的是函数名,此函数名的命名有严格的规范性

必须以Java开头

com_example_cheng_myapplication为包名,点用下划线代替

MainActivity为类名

helloWorld为函数名


3、回到我们的Android工程

先是xml文件吧,随便定义一个TextView吧,比较简单

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:id="@+id/str_tv"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />


4、然后就是对我们的MainActivity类的处理


public class MainActivity extends ActionBarActivity {

    static {
        System.loadLibrary("Hello");
    }
    public native String helloWorld();
    private TextView str_tv;
    private String str = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        str = helloWorld();
        str_tv = (TextView) findViewById(R.id.str_tv);
        str_tv.setText(str);
    }
}

首先我们看static,一个类在刚开始构造的时候,最开始调用的并不是构造函数,而是静态代码块。而此处的静态代码块所做的工作就是加载库(就是在Android.mk中声明的Hello)

然后就是helloWorld方法,这个方法用native修饰,表示的就是本地方法,其实就是我们的c函数了,就是第2个步骤中的Java_com_example_cheng_myapplication_MainActivity_helloWorld方法


5、所有的准备工作都做完,可以编译我们的库了,然后就是运行我们的Android程序

打开cmd,进入工程目录,输入ndk-builder,然后去工程目录中的libs文件,看看是否多了个Hello.so文件,如果有,说明编译成功了。接着运行我们的Android工程,就可以看见我们熟悉的HelloWorld。





       

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值