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

作者: 程序员指北 | 来源:发表于2017-04-16 13:32 被阅读2571次

    摘要

    基本原理:为什么要用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地址,点我就行

    相关文章

      网友评论

        本文标题:Android Studio2.3NDK的简单配置及快速开发

        本文链接:https://www.haomeiwen.com/subject/kwjaattx.html