Android JNI开发(一)

首先,JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C/C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通+常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的。例如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少要保证本地代码能工作在任何Java 虚拟机环境下。

本文的JNI开发是建立在Android Studio平台上的,在Android Studio上开发比在Eclpise上步骤更加简单,毕竟是Google的亲生骨肉啊,自然会对JNI开发提供更加简洁的方案。接下来,直接进入主题。

1. 创建项目
在Androd Studio上新建一个项目,命名为:NdkTest。直接创建一个包名:com.luo.ndk。在该目录项新建一个专门调用本地方法的类:JniUtils.java,如下:

package com.luo.ndk;

public class JniUtils {

    public native String getCiphertext(); //声明一个本地方法,获得密文

}

然后在MainActivity里面调用JniUtils的getCiphertext()的方法,将结果显示在UI上。如下:

public class MainActivity extends AppCompatActivity {
    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextView = (TextView) findViewById(R.id.textView);
        JniUtils jniUtils = new JniUtils();
        mTextView.setText(jniUtils.getCiphertext());
    }
}

2. NDK的集成
打开SDK Manager,点击“SDK Tools”可以在下方看到Android NDK,点击下载,等待即可完成NDK的下载步骤,比起Eclpise的NDK下载安装,这步骤简单的不行。
Android NDK
下载好以后,打开工程目录下的local.properties文件,可以看到如下信息,其中ndk.dir=/Users/luoyingxing/Library/Android/sdk/ndk-bundle这行表明NDK已经下载并且配置好了路径。

## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Thu Mar 17 15:42:51 CST 2016
ndk.dir=/Users/luoyingxing/Library/Android/sdk/ndk-bundle
sdk.dir=/Users/luoyingxing/Library/Android/sdk

3. 编译Java代码,生成头文件
点击Build—>Rebuild Project,将java代码编译成.class文件,编译完成后,利用Android Studio的Terminal命令工具,切换到debug目录下:
cd app/build/intermediates/classes/debug/

再执行javah命令生成本地方法的.h头文件,命令很简单,就是java -jni 加上类的全路径名+类名:
javah -jni com.luo.ndk.JniUtils

执行完成后,你可以在NdkTest/app/build/intermediates/classes/debug/目录下看到生成的
com_luo_ndk_JniUtils.h头文件:

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

#ifndef _Included_com_luo_ndk_JniUtils
#define _Included_com_luo_ndk_JniUtils
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_luo_ndk_JniUtils
 * Method:    getCiphertext
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_luo_ndk_JniUtils_getCiphertext
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

可以看到,其中的JNIEXPORT jstring JNICALL Java_com_luo_ndk_JniUtils_getCiphertext(JNIEnv *, jobject)这个方法就是我们刚才创建的本地方法,接下来我们只需去实现它即可。

4. 编写c/c++代码
在当前工程目录下新建一个文件夹为jni,将刚才生成的com_luo_ndk_JniUtils.h头文件剪切到该目录下。然后在jni目录下新建一个getCiphertextFromC.c文件。创建后,看的如下:

 #include "getCiphertextFromC.h"

可以看到,只是一个单纯的.c文件,我们将头文件里面的getCiphertext()方法复制过来,然后重写该方法,记得包含相应的头文件,如下:

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

JNIEXPORT jstring JNICALL Java_com_luo_ndk_JniUtils_getCiphertext
        (JNIEnv *env, jobject key){

    char jName[10] = {"Hello JNI"};
    return (*env)->NewStringUTF(env, jName);
}

5. 调用so库
在app/build.gradle文件中配置静态加载so库的名字为Ciphertext,如下ndk{}部分:

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.luo.ndk"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        ndk{
            moduleName "Ciphertext"  //生成的so库名字
            abiFilters "armeabi", "armeabi-v7a", "x86"  //输出指定三种abi体系结构下的so库。
        }
    }
}

然后在JniUtils类中添加加载静态so库的代码:

package com.luo.ndk;

public class JniUtils {

    static {
        System.loadLibrary("Ciphertext");
    }

    public native String getCiphertext(); //获得密文

}

到此整个项目准备完毕,运行看看效果吧。

7. 运行效果
可以看到,前端显示出了在.c文件里面编写的代码:Hello JNI。整个基本的JNI开发似乎很简单有木有。
这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值