文档章节

Android studio NDK成长记录(二)ndk-build

风哲
 风哲
发布于 2017/02/06 11:07
字数 1438
阅读 45
收藏 0

Android studio NDK开发第二种方法 ndk-build:

  1.    首先环境配置必不可少,包括下载安装CMake,ndk-build插件,在上一篇“Android studio NDK成长记录(一)“中已经有详细介绍.
  2. 创建.c或者cpp源文件,和头文件,这一步可以先只是创建出.c和.h文件,不用急着书写.c源文件,只需搭好架子即可,书写c代码可以放到将gradle和ndk-build关联好之后,也就是第六步。(下面以c语言为例)
    第一种方式:
    在mian目录下新建jni文件夹。
    选中Android Studio的左下角Terminal面板,输入命令“cd app/src/main/java”进入java目录,执行命令“javah 包名+类名“,这个命令是调用jdk中的javah.exe程序对native方法所在的Java类生成一个对应的.h头文件。这种方式生成的.h头文件中,自动将native方法在C语言中所对应的方法名全部生成出来了。然后将生成的.h文件剪切到cpp文件夹,并将.h文件中放方法名称copy到c文件中,将参数补全即可。
    生成.h文件的命令如:“javah com.picovr.justndkbuild.nativeclass.JNI”
    第二种方式:
    在main目录新建文件夹jni,右键新建C/C++ Source File 勾选上Create an asscoiated hearder,这样就会生成一个.c文件和.h的头文件,这个.h文件不会像第一种方式那样自动生成native方法在C语言中所对应的方法名,需要自己手动去写。在学习阶段建议手动去做,更好地了解并熟悉jni的一些规则。
  3. 书写Android.mk文件,该文件名字必须为“Android.mk”,用于关联gradle和ndk-build,关联成功之后书写C代码时会有提示,否则不会有提示。Android.mk文件放在c资源文件所在module根目录中(比如app根目录)。书写好Android.mk文件后在module根目录下的build.gradle文件中配置ndk属性。Android.mk文件和build.gradle文件可配置如下:

    build.gradle :
    android {
        compileSdkVersion 25
        buildToolsVersion "25.0.0"
        defaultConfig {
            applicationId "com.picovr.justndkbuild"
            minSdkVersion 15
            targetSdkVersion 25
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    
            ndk {
                ldLibs "log"  moduleName "hello"  }
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }

    Android.mk :
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    
    #生成的so库的名字,必须跟module(如app:)下的build.gradle中配置的moduleName名字相同
    LOCAL_MODULE := hello
    
    LOCAL_LDFLAGS := -Wl,--build-id
    
    #需要在C代码中打印log到studio的控制台,第一步就需要配置该属性
    LOCAL_LDLIBS += -llog
    
    #本地 source file的地址,必须配置,Java代码才能找到源文件,并关联起来,最后面的'\'是换行,有多个文件直接按下面形式列出即可
    LOCAL_SRC_FILES := \
       E:\AndroidStudioProjects\JustNDKBuild\app\src\main\jni\hello.c \
    
    #本地 source file所在的目录
    LOCAL_C_INCLUDES += E:\AndroidStudioProjects\JustNDKBuild\app\src\main\jni
    LOCAL_C_INCLUDES += E:\AndroidStudioProjects\JustNDKBuild\app\src\main\jni
    
    include $(BUILD_SHARED_LIBRARY)
  4.     将gradle和ndk-build关联起来   ,可以手动关联,也可以自动关联,最后的结果是一样的。<1.>自动关联 : 将工程改为Android视图,右键选中module(如app),选择Link C++     Project with Gradle,下拉选项中选择ndk-build,浏览找到你的项目中的Android.mk文件,点击确定即可,studio会自动在该module下的build.gradle文件中配置好externalNativeBuild属性,最终结果与手动关联是一样的

    <2.>手动关联 : 在module下的build.gradle中按照下方的模板配置externalNativeBuild属性,该属性是指向你的Android.mk文件,让gradle编译的时候能找到该文件,按照该文件的配置进行编译
    配置好之后的build.gradle应该如下模样,注意看externalNativeBuild属性
    android {
        compileSdkVersion 25
        buildToolsVersion "25.0.0"
        defaultConfig {
            applicationId "com.picovr.justndkbuild"
            minSdkVersion 15
            targetSdkVersion 25
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    
            ndk {
                ldLibs "log"  moduleName "hello"  }
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    
        externalNativeBuild {
            ndkBuild {
                path 'Android.mk'  }
        }
    }
  5. 书写java中的native方法,创建一个类,在该类中声明一个native方法,不需要实现。
    package com.picovr.justndkbuild.nativeclass;
    
    /**
     * Created by PICO-USER Dragon on 2017/2/6.
     */
    
    public class JNI {
        public native String getString();
    }
  6. 书写c源代码
    java中的native方法对应C语言中的方法的规则在下面的代码中已经详细解释:
    copy下面的代码的时候,导包hello.h和jni.h分别copy,因为每个人的头文件名字不一样。ndk安装路径也不一样,所以jni.h所在目录不一样。
    /* Created by PICO-USER Dragon on 2017/1/17.
      导包的时候要注意
      1.你自己创建的.h文件必须要
      2.jni.h必须要,这个导包的时候,studio应该会提示,其实就是你安装ndk所在目录下的platforms目录中的任意
      一个版本中,可以在电脑中按照下面jni.h的那个路径中找来看看
     */
    
    #include "hello.h"
    #include "../../../../../../Android/SDK/ndk-bundle/platforms/android-21/arch-x86_64/usr/include/jni.h"
    #include <stdio.h>
    #include <stdlib.h>
    /**
     * 命名规则:返回值类型 + 方法名
     * 方法名:是Javanative方法的包名+类名+方法名,并且把'.'给为'_'
     *
     * JNIEXPORTJNICALL 可要可不要string Java_com_picovr_ndksupporttest_mynative_JNI_getString(JNIEnv *env, jobject jobj)也行
     *
     * jstring 是返回值对应java中的String
     * JNIEnv *env 必须参数,在C中必须要用到这个参数去调用方法
     * jobject jobj 必须参数 不一定用到
     */
    JNIEXPORT jstring JNICALL
    Java_com_picovr_ndksupporttest_mynative_JNI_getString(JNIEnv *env, jobject jobj) {
    
        //jstring     (*NewStringUTF)(JNIEnv*, const char*);其实是在调用ndk-build中的jni.h中的方法
        return (*env)->NewStringUTF(env, "The first jinDemo for Dragon !");
    
    }
  7. 加载动态链接库,调用c代码
    在native方法所在类中增加静态代码块,加载动态链接库
    package com.picovr.justndkbuild.nativeclass;
    
    /**
     * Created by PICO-USER Dragon on 2017/2/6.
     */
    
    public class JNI {
    
        // Used to load the 'hello' library on application startup. 
        static {
            //"hello"是so库的名字,也就是CMakeLists.txt文件中add_library()属性中的第一个参数 
            System.loadLibrary("hello");
        }
    
        public native String getString();
    }
  8. 调用native方法,看看是否成功!
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            String string = new JNI().getString();
            Log.i("MainActivity", "onCreate string :" + string);
        }
    }

 

© 著作权归作者所有

风哲
粉丝 0
博文 13
码字总数 12513
作品 0
海淀
私信 提问
在android studio中集成javah, ndk-build进行JNI开发

最近在搞一个android上控制LED灯闪烁的功能,用到了串口编程,搜索了一下,发现Google发布了一个demo,android-serialport-api。有现成的代码和APK,要想自己改JNI也比较简单,就一个C文件。...

LeoLiang
2018/08/04
0
0
Android Studio之NDK环境搭建,so文件打包以及使用

本篇入门教程开发环境为mac + Android Studio + gradle 2.14.1,主要包含以下3块内容: NDK环境搭建 编写第一个JNI项目 打包出动态so文件,在其他项目中使用 一、NDK环境搭建 从Android Stu...

ljianbing
2018/06/26
0
0
Build command failed. Error while executing process 错误

android ndk项目有时编译会报这样的错,但你又不清楚到底哪儿出错了 Build command failed. Error while executing process D:workadt-bundlesdkcmake3.6.4111459bincmake.exe with argumen......

犀牛有脾气
2018/11/14
0
0
用Android Studio进行NDK编程入门实例

版权声明:欢迎关注我的微信公众号:「easyserverdev」,中文名:『高性能服务器开发』。 https://blog.csdn.net/analogous_love/article/details/79979073 参考了网上各种教程,跌跌撞撞最终...

analogous_love
2018/04/17
0
0
Android Studio, gradle and NDK integration

With the recent changes (release 0.7.3 around Dec 27), the new Android Build System starts to be really interesting also if you are using the NDK! Now this is really easy to int......

Jerikc
2015/05/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Java8

package com.shi.lambda;import java.util.Arrays;import java.util.List;import org.junit.Test;import com.shi.model.Employee;/** * 初始化案例 * @author xiaosh......

小小小施爷
11分钟前
0
0
c# 动态编译代码

static void Main() { Stopwatch watch = new Stopwatch(); watch.Start(); //创建一个CSharp语言Provider //CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); CShar......

朝如青丝暮成雪
12分钟前
0
0
好程序员技术分享html5和JavaScript的区别

好程序员技术分享html5和JavaScript的区别,HTML5广义上讲是前端开发学科的代名词,包含HTML5、CSS3及JavaScript三个重要的部分,是运行在浏览器上应用的统称。如PC端网站、管理系统、手机网...

好程序员IT
14分钟前
0
0
tomcat 与 spring boot 设置虚拟路径

tomcat 设置虚拟路径 <Context path="/uploadDir" docBase="/data"/>path是请求访问的路径docBase是服务器存储文件的路径,Linux 根目录下 data spring boot 虚拟路径设置 registry.addRe......

kdy1994
17分钟前
0
0
var ,let ,const 的区别和共同点

一、let和var区别 1.关于变量提升,var能变量提升,let不能 // 关于var 如下所示console.log(a); //输出undefined,此时就是变量提升var a = 2; console.log(a); //2 //相当于下面...

MrBoyce
22分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部