Android JNI之静态注册(android studio)

起源

说到JNI,起初是满脸头痛。公司业务,呵呵,opengl,当初是java来写的,后边说是c++效率高,对此,我笑一笑从容。任务到手,没办法,就是干。什么某狗,什么36啊,什么某毒,嗖嗖嗖,嘿嘿,一个Hello JNI告诉我这个JNI还是很友好的。描述一下当时我所接受的第一个JNI程序。

一。创建JNI Floder, 将c++代码放入其中,然后查看头文件

这个地方要注意,是要生成JNI Floder类型的文件夹,如果随便创建一个文件夹叫jni,那么不好意思,我大as是不认识的。一个温馨的提示,让人爱得沉醉。

make.exe: *** No rule to make target .  Stop.
Android JNI之静态注册(android studio)_第1张图片
jni目录代码展示图

Android JNI之静态注册(android studio)_第2张图片
头文件代码展示图

二。根据c++头文件编写java端接口,并使用javah命令生成jni头文件

这个呢,没什么好说的。java要跟c++进行交流,需要一个桥梁,桥的这头是java,那头是c++,中间的是jni,你不搞点事情是不行的。就这样,普通话出现了,你懂我懂大家懂,才能展开深入交流,嘿嘿嘿。回归正题,看代码,看命令:

package net.mapout.jni;

/**
 * Created by Tower on 2017/5/25.
 * java jni 接口申明
 */
public class JNILoader {
    static {
        /**
         * JniDemo 为build的so文件名
         */
        System.loadLibrary("JniDemo");
    }

    public static native String sayHello();
}
打开Terminal,进入/app/src/main/java目录下
D:\Study_Code\JniDemo>   cd app/src/main/java

执行javah命令,生成头文件net_mapout_jni_JNILoader.h到jni目录下
D:\Study_Code\JniDemo\app\src\main\java>  javah -d ../jni net.mapout.jni.JNILoader

三。实现jni头文件net_mapout_jni_JNILoader.h,并调用别人家写的c++代码。

这个实现文件可以瞎命名,但必须是.c/.c++为后缀,实现文件嘛,嗯?嗯。

#include "net_mapout_jni_JNILoader.h"
#include "hello.h"
#include 

/**
 * std::string 转  jstring
 */
jstring str2jstring(JNIEnv* env, std::string str)
{
    const char* pStr = str.c_str();
    int        strLen    = strlen(pStr);
    jclass     jstrObj   = env->FindClass("java/lang/String");
    jmethodID  methodId  = env->GetMethodID(jstrObj, "", "([BLjava/lang/String;)V");
    jbyteArray byteArray = env->NewByteArray(strLen);
    jstring    encode    = env->NewStringUTF("UTF-8");
    env->SetByteArrayRegion(byteArray, 0, strLen, (jbyte*)pStr);
    return (jstring)env->NewObject(jstrObj, methodId, byteArray, encode);
}

/**
 * 实现头文件
 */
JNIEXPORT jstring JNICALL Java_net_mapout_jni_JNILoader_sayHello
  (JNIEnv *env, jclass jclass){
    return str2jstring( env, sayHello() );
}
Android JNI之静态注册(android studio)_第3张图片
项目文件结构图

四。到此,准备工作已经完成。等等,还有配置。配置嘛,一般一般。

首先,在项目的gradle.properties中配置一句:

android.useDeprecatedNdk=true

看字面意思,过时,没错,就是过时了,为啥还要配置呢,怪我咯。时代在进步,从当年的时代在召唤到如今的...今天天气不错,凉风有幸,秋月无边,虽然我不是玉树临风...在打怪升级的路上,免不了有新的boss出现,cmake的火爆,这只是个意外,美丽的意外,这个暂且不提。有了首先,当然还需要然后撑腰。在当前 module 下的 build.gradle 中加入使用ndk,配置如下:

android {
    defaultConfig {
        ndk {
            moduleName "JniDemo"
            abiFilters "armeabi", "armeabi-v7a", "x86"  //输出指定三种abi体系结构下的so库。可有可无。
            cFlags "-std=c++11" //c++版本
            stl "gnustl_static" //支持 stl 标准库
        }
    }
}

ndk,最后,还需要设置ndk环境。这个就是一个F4,千万别手残多按了一个ALT(如果一起按了,那么恭喜你,再接再厉,下次更精彩),进入项目配置界面SDK Location->Android NDK location,设置NDK目录即可。当然也可以通过手动在项目的 local.properties 中添加,举栗如下:

ndk.dir=E\:\\adt-bundle-windows-x86_64-20140321\\android-ndk-r10

激动。想一下,还有什么需要配置?搞事情。忘了就忘了吧,忘一忘,十年笑。

五。收工。

biu biu biu,build apk,见证奇迹的时刻到了,这一刻属于你们,也属于我。缺陷不能不提,比如说jni头文件名称超长。当初java,c++,c三分天下,谁也不服谁。互联网的格局,瞬息万变。合作,随之而来。java要跟c/c++交流,无缝对接,请了一个臭皮匠过来,赶时间。然后这位臭皮匠,啰里啰唆、老生常谈的做法。一个有效的交流,嗨,我来自xx省xx市,祖籍xx。说完这些,恭喜你,接下来,你可以聊天了。吐槽,归吐槽。技术,总是在革新。这种方式,称之为静态注册。那么,相反呢。
附送一张机票,带你领略世界的浩瀚

你可能感兴趣的:(Android JNI之静态注册(android studio))