Android3.0环境配置sdk,Android Studio 3.0 利用cmake搭建jni环境(很详细哦)

我用的Android Studio是3.0的版本,然后想搭建一下jni的环境。这里把自己遇到的问题和注意点都记录下。

首先是需要在android studio里面安装最基本的环境。

打开Default Preference里面查看SDK Tool选项。

CMake、LLDB、NDK这三个勾选上去,然后安装。

安装好了以后,在File-》Project Structure的SDK Location里面应该可以看到Android NDK Location的地址。

如下图所示。

新建一个Android Studio项目,注意到我这里新建项目的时候并没有什么include C++ 的勾选项目,as也不会在项目生成后帮忙生成cmakelist.txt, 我以为这个as版本的问题,后面也能够顺利搭建就行了。

首先新建一个JNITest类,代码如下:

package jnifive.preqel.com.jnifive;

public class JNITest {

static {

System.loadLibrary("jnilib");

}

public native String getString();

}

这里的jnilib代表的就是你的jni库名。这时候编译器会提示有错误,不用管。

然后根据javah工具来生成c语言头文件。

首先配置好你的jdk环境变量,即在termianla终端里面可以正常使用javac和javah。

到JNITest同级目录下面用javac 生成class文件。

具体操作:用终端进入到JNITest.java所在目录,执行 javac JNITest.java

然后在终端里面用命令行退到java文件目录下面,用javah生成c++头文件。

终端输入:javah -jni jni.example.com.testjni6.JNITest

注意:请用cd命令退到工程文件目录的java同级目录下面执行,否则会提示找不到文件

成功后会生成

然后

右击app目录,新建Folder-》Jni Folder 建立jni目录

点击下一步后看见android studio在工程下面帮我们生成了一个cpp的文件夹,并没有看到所谓的jni文件夹。晕了?没关系,其实是一样的,把Android studio的视图转化为Project,找到app目录,然后在main下面找到jni目录。如图所示

然后把刚才的jni_example_com_testjni6_JNITest.h文件拷贝进来。

在这个jni目录下面创建一个新的c/c++ source file。

名字就叫main.cpp好了。里面代码如下:

#include "jni_example_com_testjni6_JNITest.h"

#include

extern "C"

JNIEXPORT jstring JNICALL

JNICALL Java_jni_example_com_testjni6_JNITest_getString(

JNIEnv* env,

jobject /* this */) {

std::string hello = "Hello from C++";

return env->NewStringUTF(hello.c_str());

}

注意这里的包名都要对应上。

这时候build一下工程你会发现

这时候不用配什么android.useDeprecatedNdk=true ,这个东西在3.0以后好像是被取消了,配了只会走错路。(表示折腾了很久。。。)

正确的做法是直接用cmakelist.txt配置环境。在工程app/java/目录(并非一定要这个地方,但是最后在build.gradle里面应正确关联)下面直接新建一个CMakeLists.txt,里面的内容如下:

# For more information about using CMake with Android Studio, read the

# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC

# or SHARED, and provides the relative paths to its source code.

# You can define multiple libraries, and CMake builds them for you.

# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.

jnilib

# Sets the library as a shared library.

SHARED

# Provides a relative path to your source file(s).

../jni/native-lib.cpp )

# Searches for a specified prebuilt library and stores the path as a

# variable. Because CMake includes system libraries in the search path by

# default, you only need to specify the name of the public NDK library

# you want to add. CMake verifies that the library exists before

# completing its build.

find_library( # Sets the name of the path variable.

log-lib

# Specifies the name of the NDK library that

# you want CMake to locate.

log )

# Specifies libraries CMake should link to your target library. You

# can link multiple libraries, such as libraries you define in this

# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.

jnilib

# Links the target library to the log library

# included in the NDK.

${log-lib} )

带#号全是注释,所以这里有几个重要的属性要配的。

add_library 下面首先指明库的名称,这里是jnilib,Provides a relative path to your source file(s),这里要用相对路径指到cpp文件所在的路径。cmakelist的配置,这个配置一定要配对,否则会抱什么

CMake Error: CMake can not determine linker language for target: 的错误。

然后在app的build.gradle下面新增一些语句。

在defaultConfig下面新增

ndk {

abiFilters 'armeabi', 'armeabi-v7a','x86'

}

externalNativeBuild {

cmake {

cppFlags ""

//生成多个版本的so文件

abiFilters 'arm64-v8a','armeabi-v7a','x86','x86_64'

}

}

这里表示支持的abi版本,如果设备的abi版本不在这个列表中是安装不了apk的。

然后在同一文件的android下面加入下面的代码

externalNativeBuild {

cmake {

path "src/main/java/CMakeLists.txt"  // 设置所要编写的c源码位置,以及编译后so文件的名字

}

}

path 就是CMakeLists.txt的相对路径。

好了。

最后在MainActivity里面调用一下这个JNITest的getString()函数就行了,关键代码如下:

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

TextView tv = (TextView) findViewById(R.id.textview);

JNITest ndkTest = new JNITest();

try {

tv.setText(ndkTest.getString());

}catch (Exception e){

e.printStackTrace();

}

}

如有需要,请点击下面链接:

项目github源码地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值