Android Studio2.3NDK的简单配置及快速开发

摘要

基本原理:为什么要用jni,此处就不讲了,网上已经很详细了。写本文的原因是在网上没有发现用最新版AS2.3进行ndk开发的,所以抛砖引玉一下。在java代码中调用c代码,大致步骤如下:
1.在需要调用c代码的地方声明native方法。
2.在c代码中对该native方法进行实现。
3.通过ndk开发工具包和gradle进行编译。
4.在调用的地方,加载生成的so库文件,调用方法。
5.下面详细讲解,写的不对的地方欢迎大家提出来。

GitHub地址

第一步:修改Project的build.gradle文件

首先修改project工程文件的build.gradle文件,把gradle换成实验gradle-exprimental。具体请看详情图。

这里写图片描述
接下来需要修改这个文件,见图:
这里写图片描述

第二步:修改app的build.gradle文件

此处修改较大,先上一个效果图,然后直接上代码:

这里写图片描述

// 注意:此处已修改,原来为apply plugin: 'com.android.application'
apply plugin: 'com.android.model.application'

// 用model包裹android的内容
model{
    android {
        compileSdkVersion 25
        buildToolsVersion "25.0.0"
        defaultConfig {
            applicationId "com.wangjin.hellondkdemo"
            minSdkVersion.apiLevel 19    // 此处需要修改,添加 .apiLevel   原来为minSdkVersion 14
            targetSdkVersion.apiLevel 25 // 此处需要修改,添加 .apiLevel
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
        buildTypes {
            release {
                minifyEnabled false
                // 此处需要修改,原来为 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
                // 修改成下面这句话
                proguardFiles.add(file('proguard-android.txt'))
            }
        }
        ndk {
            moduleName "hello"
        }
    }
}


dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.2.0'
    compile 'com.android.support.constraint:constraint-layout:1.0.0-beta2'
    testCompile 'junit:junit:4.12'
}

第三步:配置项目的NDK开发工具包

话说,还是图片深得我心,直接上图最可靠。。。
这里写图片描述
关键代码来了:
这里写图片描述

编译完成后,打开local.propertices文件,显示如下图 则成功
这里写图片描述

此时,说明项目的ndk配置基本完成。
接下来,需要在app的build.gradle文件中添加要生成的so库文件的文件名,代替Android.mk文件,也就是说,以后直接在gradle中配置一句话,直接省略了mk文件的编写,是不是很爽。
这里写图片描述

至此,配置的终于完成了 ,哇咔咔,不过话说回来,也不是特别难吗,相信第二次只要3分钟绝对能配置完成。

第四步:关键点来了,新建jni文件夹,编写c文件

还是贴图把吧,最后会把代码demo地址发出来
1.首先在app/src/main文件夹下新建一个和java同级的jni文件夹
这里写图片描述

2.在jni文件夹下新建c文件

这里写图片描述

3.各种扯皮结束了,是时候开始撸代码
大家都知道,第一步肯定是手撕native方法。我们在MainActivity中新建了两个方法,第一个helloFromJni,调用c代码返回一个字符串;第二个callBackJavafromC,是调用c代码,然后在c代码中调用我们定义好的logout方法在控制台打印一句话。

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       // 调用native方法
    }

    static {
        // 加载so库文件,这个是固定写法,需要调用so库文件的方法,首先需要加载so库
        System.loadLibrary("hello"); // hello是我们在build.gradle中定义的,要一致
    }


    public native String helloFromJni();

    public native void callBackJavafromC();


    public void logout() {
        System.out.println("hahahahahahahahahah===");
    }
}

4.定义了native方法后,方法名会报红,是因为没有在c代码中实现,所以接下来是实现c代码,并处理相应的逻辑,此处需要一定的c语言基础,
只要看懂就行,基本的操作也不难,大家找个速成的c语言视频look一下。先上两张图,解释一下怎样快速生成c代码。
这里写图片描述

5.此时,在我们新建的hello.c中就实现了我们的方法,只需要处理相应的逻辑就行了。

这里写图片描述

6.上面4和5两步基本上讲清楚了我们native方法的声明和c代码的实现,下面贴一下 我们自己定义的两个方法的实现,一个是返回一个字符串,另一个是回调java的方法,打印一句话。下面看c代码的实现,在我们新建的hello.c文件中:

#include <jni.h>

/**
 * 这个是返回一个字符串的c代码
 */
JNIEXPORT jstring JNICALL
Java_com_wangjin_hellondkdemo_MainActivity_helloFromJni(JNIEnv *env, jobject instance) {

    char* c ="hello from c";

    return (*env)->NewStringUTF(env, c);
}

/**
 * 这个是回调java方法打印一句话的代码
 */
JNIEXPORT void JNICALL
Java_com_wangjin_hellondkdemo_MainActivity_callBackJavafromC(JNIEnv *env, jobject obj) {
    // 1.通过反射找到类
    jclass clazz = (*env) -> FindClass(env, "com/wangjin/hellondkdemo/MainActivity");
    // 2. 找到方法ID
    jmethodID methodId = (*env) -> GetMethodID(env, clazz, "logout", "()V");
    // 3.调用方法,obj就是调用的类实例,所以不用再次创建了
    (*env)->CallVoidMethod(env, obj, methodId);
}

7.此时,native方法和c的实现都写好了,只需要在oncreat()方法diao用就行了。


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 调用c中的方法弹出Toast
        Toast.makeText(this, helloFromJni(), Toast.LENGTH_LONG).show();
        // java调用c然后回调java方法,在logcat中打印  hahahahaahah====
        callBackJavafromC();
    }

大功告成

看到此处是不是觉得jni的逻辑也是很简单的,有什么不明白的随时留言联系,我会很快处理的。最后让我打一波广告,我的淘宝店顺利开业,地址程序员潮流店铺地址
,大家点击进去瞅一瞅,多多支持,谢谢各位猿猿们。

最后github地址:
GitHub地址,点我就行

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值