logo头像

博学广问,自律静思

第一个android studio+NDK程序

NDK(android native develop kits ):android 本地开发工具集 ,可以把c/c++ ->编译成一个 linux下可以执行的二进制文件 java代码里面就可以通过jni 调用执行二进制的文件。 什么是JNI :java本地开发接口,JNI是一个协议这个协议用来沟通java代码和外部的本地代码(c/c++).通过这个协议,java代码就可以调用外部的c/c++,代码外部的c/c++代码也可以调用java代码。 java可以实现上层应用的开发,但是不能写底层驱动,有些android项目必须和底层硬件打交道,比如要精确快速的获取某种传感器的值,那么java是不能办到的,那怎么办,就通过JNI开发,通过c/c++完成底层驱动或者值得获取,然后将值传回到java层。同样java层也可以将数据传递给c/c++层,这样通过JNI完成数据的交互。 android_studio_NDK android_studio_NDK

为何要用到NDK?

概括来说主要分为以下几种情况:

  • 1. 代码的保护,由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。
  • 2. 在NDK中调用第三方C/C++库,因为大部分的开源库都是用C/C++代码编写的。
  • 3. 便于移植,用C/C++写的库可以方便在其他的嵌入式平台上再次使用。

MainActivity:

package cn.wangbaiyuan.ndktest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

public native String getStringFromNative();
@Override
protected void onCreate(Bundle savedInstanceState) {
    System.loadLibrary("hello");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

TextView hello=(TextView)findViewById(R.id.hello);
hello.setText(getStringFromNative());
}

}

下面是通过javah命令自动生成的

cn_wangbaiyuan_ndktest_MainActivity.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class cn_wangbaiyuan_ndktest_MainActivity */

#ifndef _Included_cn_wangbaiyuan_ndktest_MainActivity
#define _Included_cn_wangbaiyuan_ndktest_MainActivity
#ifdef __cplusplus
extern “C” {
#endif
#undef cn_wangbaiyuan_ndktest_MainActivity_BIND_ABOVE_CLIENT
#define cn_wangbaiyuan_ndktest_MainActivity_BIND_ABOVE_CLIENT 8L
#undef cn_wangbaiyuan_ndktest_MainActivity_BIND_ADJUST_WITH_ACTIVITY
#define cn_wangbaiyuan_ndktest_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L
#undef cn_wangbaiyuan_ndktest_MainActivity_BIND_ALLOW_OOM_MANAGEMENT
#define cn_wangbaiyuan_ndktest_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
#undef cn_wangbaiyuan_ndktest_MainActivity_BIND_AUTO_CREATE
#define cn_wangbaiyuan_ndktest_MainActivity_BIND_AUTO_CREATE 1L
#undef cn_wangbaiyuan_ndktest_MainActivity_BIND_DEBUG_UNBIND
#define cn_wangbaiyuan_ndktest_MainActivity_BIND_DEBUG_UNBIND 2L
#undef cn_wangbaiyuan_ndktest_MainActivity_BIND_IMPORTANT
#define cn_wangbaiyuan_ndktest_MainActivity_BIND_IMPORTANT 64L
#undef cn_wangbaiyuan_ndktest_MainActivity_BIND_NOT_FOREGROUND
#define cn_wangbaiyuan_ndktest_MainActivity_BIND_NOT_FOREGROUND 4L
#undef cn_wangbaiyuan_ndktest_MainActivity_BIND_WAIVE_PRIORITY
#define cn_wangbaiyuan_ndktest_MainActivity_BIND_WAIVE_PRIORITY 32L
#undef cn_wangbaiyuan_ndktest_MainActivity_CONTEXT_IGNORE_SECURITY
#define cn_wangbaiyuan_ndktest_MainActivity_CONTEXT_IGNORE_SECURITY 2L
#undef cn_wangbaiyuan_ndktest_MainActivity_CONTEXT_INCLUDE_CODE
#define cn_wangbaiyuan_ndktest_MainActivity_CONTEXT_INCLUDE_CODE 1L
#undef cn_wangbaiyuan_ndktest_MainActivity_CONTEXT_RESTRICTED
#define cn_wangbaiyuan_ndktest_MainActivity_CONTEXT_RESTRICTED 4L
#undef cn_wangbaiyuan_ndktest_MainActivity_MODE_APPEND
#define cn_wangbaiyuan_ndktest_MainActivity_MODE_APPEND 32768L
#undef cn_wangbaiyuan_ndktest_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
#define cn_wangbaiyuan_ndktest_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
#undef cn_wangbaiyuan_ndktest_MainActivity_MODE_MULTI_PROCESS
#define cn_wangbaiyuan_ndktest_MainActivity_MODE_MULTI_PROCESS 4L
#undef cn_wangbaiyuan_ndktest_MainActivity_MODE_PRIVATE
#define cn_wangbaiyuan_ndktest_MainActivity_MODE_PRIVATE 0L
#undef cn_wangbaiyuan_ndktest_MainActivity_MODE_WORLD_READABLE
#define cn_wangbaiyuan_ndktest_MainActivity_MODE_WORLD_READABLE 1L
#undef cn_wangbaiyuan_ndktest_MainActivity_MODE_WORLD_WRITEABLE
#define cn_wangbaiyuan_ndktest_MainActivity_MODE_WORLD_WRITEABLE 2L
#undef cn_wangbaiyuan_ndktest_MainActivity_DEFAULT_KEYS_DIALER
#define cn_wangbaiyuan_ndktest_MainActivity_DEFAULT_KEYS_DIALER 1L
#undef cn_wangbaiyuan_ndktest_MainActivity_DEFAULT_KEYS_DISABLE
#define cn_wangbaiyuan_ndktest_MainActivity_DEFAULT_KEYS_DISABLE 0L
#undef cn_wangbaiyuan_ndktest_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL
#define cn_wangbaiyuan_ndktest_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
#undef cn_wangbaiyuan_ndktest_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL
#define cn_wangbaiyuan_ndktest_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
#undef cn_wangbaiyuan_ndktest_MainActivity_DEFAULT_KEYS_SHORTCUT
#define cn_wangbaiyuan_ndktest_MainActivity_DEFAULT_KEYS_SHORTCUT 2L
#undef cn_wangbaiyuan_ndktest_MainActivity_RESULT_CANCELED
#define cn_wangbaiyuan_ndktest_MainActivity_RESULT_CANCELED 0L
#undef cn_wangbaiyuan_ndktest_MainActivity_RESULT_FIRST_USER
#define cn_wangbaiyuan_ndktest_MainActivity_RESULT_FIRST_USER 1L
#undef cn_wangbaiyuan_ndktest_MainActivity_RESULT_OK
#define cn_wangbaiyuan_ndktest_MainActivity_RESULT_OK -1L
#undef cn_wangbaiyuan_ndktest_MainActivity_HONEYCOMB
#define cn_wangbaiyuan_ndktest_MainActivity_HONEYCOMB 11L
#undef cn_wangbaiyuan_ndktest_MainActivity_MSG_REALLY_STOPPED
#define cn_wangbaiyuan_ndktest_MainActivity_MSG_REALLY_STOPPED 1L
#undef cn_wangbaiyuan_ndktest_MainActivity_MSG_RESUME_PENDING
#define cn_wangbaiyuan_ndktest_MainActivity_MSG_RESUME_PENDING 2L
/*
* Class: cn_wangbaiyuan_ndktest_MainActivity
* Method: getStringFromNative
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_cn_wangbaiyuan_ndktest_MainActivity_getStringFromNative
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

  在build.gradle(Module:App)加入下列配置可指定生成.so文件的CPU平台类型以及so文件的名称,如果没有指定,android将会生成libapp.so,以及所有平台的so文件;生成so文件路径为:你的项目根目录\app\build\intermediates\ndk\debug\lib

build.gradle(Module:App)

defaultConfig {
    ndk {
        moduleName "hello"
        ldLibs "log", "z", "m"
        abiFilters "armeabi", "armeabi-v7a", "x86"
    }
  …………
    }