您的位置:首页 > 移动开发 > Android开发

Android Studio 配置以及JNI使用

2016-06-03 00:44 507 查看
从Eclipse时代到Android Studio普及,开发工具越来越好用。早些时候还需要安装Cygwin工具,从Android Studio1.3以后,在Android 环境开发JNI程序搭建开发环境变得相对简单。这里就来介绍一下急于Android Studio如何进行jni开发。

  首先准备基本工具,Android
Studio (>=1.3.x), NDK(ndk-r10-e)。打开Android
Studio 建立一个空工程,关联上NDK,操作步骤方式如下图:

 



 



  设置好NDK之后,开始设置gradle,设置gradle主要需要设置三个地方,设置好之后就可以直接编写和编译JNI代码了,不需要像以前一样编写Makefile,相当方便。但是设置gradle也是需要比较小心的,由于当前NDK还处于Experimental 阶段,更新不断,经常会爆出各种奇怪的错误,因此也要特别留心。好了废话不多说,下面来介绍设置gradle的三个主要步骤。

  首先设置TopLevel gradle,也就是Project gradle,这里比较简单,在dependencies中设置:classpath
'com.android.tools.build:gradle-experimental:0.2.0' ,注意这里要把之前的类似classpath 'com.android.tools.build:gradle:1.3.0' 注释掉。还要多提一句的是,这里设置的是gradle-experimental:0.2.0,后面对应设置gradle wrapper的时候要对应gradle2.5-all 版本,这里先说到这里。

  接着设置 Module gradle,这一步是比较麻烦的。由于我们在创建工程的时候自动生成的这个gradle文件内容比较多,而且如果要使用NDK的话这个gradle变化比较大,这里直接贴出需要使用NDK的gradle,然后来进行说明。

  和自动生成的gradle相比,首先是 apply plugin: 'com.android.application' 变成了 apply plugin: 'com.android.model.application'。下面的配置也需要包装在model{}中。

  这个gradle的配置有几点需要注意的:

  1. 所有值的设置都要写成 xxx = yyyy的形式,比如: applicationId
= "com.zyp.ndktest" (自动生成的gradle 则可能是: applicationId = "com.zyp.ndktest"  ),否则会爆这种错误:Error:Cause: org.gradle.api.internal.ExtensibleDynamicObject, 当出现此类错误,检查是否都用了 “=”的方式。

  2. buildTypes 需要从android{} 中取出来,写成android.buildTypes{}的形式,否则会出现这种错误:Error:Unable
to load class 'org.gradle.nativeplatform.internal.DefaultBuildType_Decorated'.    

   此外,自动生成的buildTypes的形式和上面的也不一样为以下的形式:

  需要改成上面文件中的格式,否则会报这种错误:Error:No signature of method: org.gradle.model.ModelMap.minifyEnabled()
is applicable for argument types: (java.lang.Boolean) values: [false]     

  3. defaultConfig{} 需要写成defaultConfig.with{} 的形式,否则会报这种错误:Error:Cause: com.android.build.gradle.managed.AndroidConfig_Impl

  4. 在defaultConfig.with{} 中 需要写成 
    minSdkVersion.apiLevel  = 19
    targetSdkVersion.apiLevel = 23


    也就是比自动生成的多 .apiLevel ,否则会报这种错误:Unable
to load class com.android.build.gradle.managed.ProductFlavor_Impl

  5. 增加compileOptions.with{} 需要选择JavaVersion.VERSION_1_7,否则会报这种错误:Bad class file
magic or version

  6. 最后一点,在gradleWrapper中使用的是2.5,则android.ndk {} 中类似cppFlags 的添加使用 += 的方式,否则需要使用 .add的方式

  以上可能遇到的问题我这里帮大家罗列出来,具体的请参考Google的文档,只不过这个文档需要FQ。

  最后设置gradle wrapper就好了,将左边的工程视图调整到Project,在gradle->wrapper->grale-wrapper.properties文件的最后设置:distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip,注意这里如果在Project
gradle中设置的是gradle-experimental:0.2.0,则这里选择gradle-2.5-all,如果是gradle-experimental:0.4.0,需要设置gradle-2.8-all。

  gradle设置完成之后就可以创建jni文件夹,然后编写Native代码了,创建好jni后一个工程的基本结构见下图:



1.配置Anroid Studio(这步是关键)

使用[command+,] 打开Preferences,选择External Tools,点击加号框如下图:



Paste_Image.png

点击+号之后,打开Macros 配置宏命令界面,如下图:



Paste_Image.png



setting.png



javah.png



ndk-build.png



ndk-build clean.png

2.配置完成就可以使用javah 、ndk-build、ndk-build clean这三个命令了,那么在哪里使用这些命令,请看下图



tools.png

3.配置完成,我们开始新建工程MyNdk,然后新建jni目录



create jni.png

4.修改app下的build.gradle文件, 如下图

ndk{
moduleName "MyLibrary"
}
sourceSets.main{
jni.srcDirs = []
jniLibs.srcDir "src/main/libs"
}




app build.gradle.png

5.修改MyNdk下的gradle.properties文件(如果没有此文件,自己新建一个),如下图

android.useDeprecatedNdk=true




MyNdk gradle.properties.png

6.新建MyNdk.java

public class MyNdk {
static {
System.loadLibrary("MyLibrary");
}
public native String getString();
}




MyNdk.java.png

7.这步开始创建头文件,操作如下图(注意在MyNdk.java文件上点击右键)



create com_zhangyp_higo_myndk_MyNdk.h file.png

8.执行完成后jni目录下就创建了com_zhangyp_higo_myndk_MyNdk.h文件,然后我们在jni目录下编写 MyLibrary.cpp、Android.mk、Application.mk这三个文件,代码如下:



jni files.png

com_zhangyp_higo_myndk_MyNdk.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_zhangyp_higo_myndk_MyNdk */

#ifndef _Included_com_zhangyp_higo_myndk_MyNdk
#define _Included_com_zhangyp_higo_myndk_MyNdk
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     com_zhangyp_higo_myndk_MyNdk
* Method:    getString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_zhangyp_higo_myndk_MyNdk_getString
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif


MyLibrary.cpp

#include "com_zhangyp_higo_myndk_MyNdk.h"

JNIEXPORT jstring JNICALL Java_com_zhangyp_higo_myndk_MyNdk_getString
(JNIEnv * env, jobject obj){
return (*env).NewStringUTF("This is mylibrary !!!");
}


Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := MyLibrary
LOCAL_SRC_FILES =: MyLibrary.cpp
include $(BUILD_SHARED_LIBRARY)


Application.mk

APP_MODULES := MyLibrary
APP_ABI := all

9.如何执行ndk-build,请看下图:(注意在jni目录上点击右键)



make ndk-build .png

10.得到so文件,如下图



so file.png

12.在MainActivity中调用,代码如下

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.tv);

tv.setText(new MyNdk().getString());

}
}

12.大功告成,可以运行了,oh yet!



MyLibrary.png

13.如果需要使用Android Studio调试c/c++请看这篇文章:Android Studio NDk调试(基于gradle-experimental插件与LLDB)

1.Android端使用retrofit上传多张图片,后端使用Php接收图片(包含前后端代码)

2.Android Studio NDk调试(基于gradle-experimental插件与LLDB)

3.让Android开发者相见恨晚的软件及插件

4.GitHub上一些超炫的Android开源项目推荐

文/zzyyppqq(简书作者)

原文链接:http://www.jianshu.com/p/e689d0196a17

著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: