Android Studio下用NDK,JNI技术实现java和C/C++互调(初探)

一、Andriod NDK原理

什么是NDK(android native develop kits ):android 本地开发工具集 ,可以把c/c++ ->编译成一个 linux下可以执行的二进制文件 java代码里面就可以通过jni 调用执行二进制的文件.
什么是JNI (Java Native Interface):java本地开发接口,JNI是一个协议这个协议用来沟通java代码和外部的本地代码(c/c++).通过这个协议,java代码就可以调用外部的c/c++,代码外部的c/c++代码也可以调用java代码。

二、进入Demo实战

1. 在Android Studio下创建HelloNativeWorld工程

此时工程中有MainActivity.java源文件。代码如下:

package com.pxhero.hellonativeworld;

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

public class MainActivity extends AppCompatActivity {

    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView)findViewById(R.id.myText);
        textView.setText(new NativeUtil().getStringFromC());
        textView.setTextColor(Color.RED);
    }
}

再创建一个java类,名为NativeUtil类。代码如下:

package com.pxhero.hellonativeworld;

/**
 * Created by pengxianheng on 2016/10/26.
 */
public class NativeUtil {
    static {
        System.loadLibrary("NativeUtil");
    }

    public native  String getStringFromC();
}

此时需要点击Bulid-Make Project。生成NativeUtil.class文件。后面生成.h文件的时候会用到它。

2. 下载NDK,在AS中配置NDK相关参数

  • 首先需要下载NDK,下载地址:Android官方NDK下载地址
    下载完成后,解压到本地路径。
  • 然后在AS中,打开File ->ProjectStructure,输入ndk所在的路径,如下图所示:
    Android Studio下用NDK,JNI技术实现java和C/C++互调(初探)_第1张图片
    点击ok之后,会自动在local.properties中设置android ndk的路径:
apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.2"

    defaultConfig {
        applicationId "com.pxhero.hellonativeworld"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"

        ndk {
            moduleName "NativeUtil"            //生成的so名字(可自己进行指定)
            abiFilters "armeabi", "armeabi-v7a", "x86"    //输出指定三种abi体系结构下的so库。目前可有可无(默认是全选的)。
            //ldLibs "log"                                //如果要使用log就把这个加上
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.2.1'
}

  • 最后在gradle.properties(Project Propertie)中输入下面这行:
android.useDeprecatedNdk=true

3. 在命令行模式下,使用javah命令生成.h文件

调出AS的Terminal界面,切换到app/src/main目录。输入

javah -d jni -classpath E:\android-sdk\platforms\android-24\android.jar;..\..\build\intermediates\classes\debug
        com.pxhero.hellonativeworld.NativeUtil

命令行的参数含义如下
javah
java jni提供的程序,负责生成.class文件对应的.h文件。
-d jni
在工程下生成jni目录,到时会在这个目录下建JNI开始的C/C++源文件的。
-classpath E:\android-sdk\platforms\android-24\android.jar;
这个就是你SDK文件下android.jar所在的文件位置,找到后复制即可。
….\build\intermediates\classes\debug
..表示返回上级目录,….表示返回上两级目录,最后进入的目录如下图所示:
Android Studio下用NDK,JNI技术实现java和C/C++互调(初探)_第2张图片
这个目录是NativeUtil.class所在的目录。
com.pxhero.hellonativeworld.NativeUtil
标识了NativeUtil.class的完整包名

执行javah命令后,便会在main目录下创建jni目录,jni目录里面生成了一个com_pxhero_hellonativeworld_NativeUtil.h头文件。如下图所示:
Android Studio下用NDK,JNI技术实现java和C/C++互调(初探)_第3张图片

4. 创建.c文件,实现C文件

在jni目录下创建c文件,如下图所示:
Android Studio下用NDK,JNI技术实现java和C/C++互调(初探)_第4张图片
命令为NativeUtil。如下图所示:
Android Studio下用NDK,JNI技术实现java和C/C++互调(初探)_第5张图片
在c文件中,把.h文件内容复制进来,修改部分代码,修改后的代码如下所示:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class com_pxhero_hellonativeworld_NativeUtil */

#ifndef _Included_com_pxhero_hellonativeworld_NativeUtil
#define _Included_com_pxhero_hellonativeworld_NativeUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_pxhero_hellonativeworld_NativeUtil
 * Method:    getStringFromC
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_pxhero_hellonativeworld_NativeUtil_getStringFromC
        (JNIEnv *env, jobject obj){
    jstring jstr;
    char greeting[] ="hello, Native world\n";
    jstr = (*env)->NewStringUTF(env,greeting);
    return jstr;
}

#ifdef __cplusplus
}
#endif
#endif

最后点击rebuild project ,待工程build完毕以后进入到buil的intermediates文件夹下面看看是否生成了ndk文件夹,接着再看看ndk文件夹里面是否有.so文件,如果有就说明快大功告成了。如下图所示:
Android Studio下用NDK,JNI技术实现java和C/C++互调(初探)_第6张图片

5. 在AS中运行Demo

在AS中打开genymotion模拟器,运行Demo,运行结果如下图所示:
Android Studio下用NDK,JNI技术实现java和C/C++互调(初探)_第7张图片
ok,Done!

你可能感兴趣的:(android开发)