Android Studio NDK开发入门

摘要:
//对buildTypes//添加任务进行一些修改。在android中键入{…}{}//添加android。模型{}中的ndk{…}//删除依赖关系{…}//中的testCompile'junit:junit:4.12'。最后,请注意等号应该是一对一的对应关系,不要忽略模型{android{compileSdkVersion=23buildToolsVersion=“23.0.3”defaultConfig.with{applicationId=“com.ndkexample”minSdkVersion.apiLevel=14targetSdkVersion.apiLevel=23versionCode=1versionName=“1.0”}任务。withType{//指定JDK版本sourceCompatibility=JavaVersion.version_1_7targetCompatibility=JavaVersion.VVERSION_1_7}android。ndk{moduleName=“ndkexample”//这是将来将生成的so文件的名称。您可以随意获取ldLibs++“log”。//打印日志信息的包已导入。//支持armeabi、armeabi-v7a,x86 abiFilters++“armeabi”abiFilters+=“armeabiv7a”abiFilters+=“x86”}android三个平台。buildTypes{release{minifyEnabledfalseprogredFiles+=file}}依赖项{compilefileTree/*testCompile'junit:junit:4.12'*//删除compile'com.android.support:appcompat-v7:23.4.0'行}您可以在此处编译它以查看是否有任何错误。如果有错误,请仔细检查字符是否错误或包名是否未更改为您自己的名称。

从Android Studio 1.3 Beta1开始,就支持了NDK,我目前使用的版本是1.5.首先强调几点。

1.必须安装NDK并配置好环境变量(和配置JDK环境变量如出一辙:新建NDK_HOME我的变量值为D:android-sdk-windows dk-bundle

在Path变量最后加上;%NDK_HOME%)

2.目前的NDK只支持gradle2.5,版本高了或低了都不行(后面还会说到)

接下来我通过实际建立一个工程赖演示NDK在Android Studio中的用法。我会一步一步的来,方便大家学习。

我们首先向平时一样建立一个空的项目模板,修改设置,设置Gradle版本为2.5

Android Studio NDK开发入门第1张

接下来我们需要将根目录下的gradle修改为实验性的gradle如下所示:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle-experimental:0.2.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

因为需要gradle2.5的支持,我们需要需要将gradle/gradle-wrapper.properties中的版本修改为2.5,如下所示:

#Wed Oct 21 11:34:03 PDT 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https://services.gradle.org/distributions/gradle-2.5-all.zip
然后到了最容易出错的地方:修改原来的app/build.gradle,如下所示:

apply plugin: 'com.android.model.application'//这里加上.model
//在android{......}外面加上一层model{},
// 将android{......}中的buildTypes移动到android{}外面,但在model{}里面。
//对buildTypes做一些修改
//在android{}里面添加一个task.withType(JavaCompile){......}
//在model{}里面添加一个android.ndk{......}
//删除dependencies{......}中的testCompile 'junit:junit:4.12'
//最后要注意等于号要一一对应,不要漏写
model {
    android {
        compileSdkVersion = 23
        buildToolsVersion = "23.0.3"

        defaultConfig.with {
            applicationId = "com.ndkexample"
            minSdkVersion.apiLevel = 14
            targetSdkVersion.apiLevel = 23
            versionCode = 1
            versionName = "1.0"
        }
        task.withType(JavaCompile) {
            //指定编译JDK版本
            sourceCompatibility = JavaVersion.VERSION_1_7
            targetCompatibility = JavaVersion.VERSION_1_7
        }
    }
    android.ndk {
        moduleName = "ndkexample"//这个是将来生成的so文件的名称,可任意取
        ldLibs += "log"//引入打印日志信息的包
        //支持armeabi,armeabi-v7a,x86三个平台
        abiFilters += "armeabi"
        abiFilters += "armeabi-v7a"
        abiFilters += "x86"
    }
    android.buildTypes {
        release {
            minifyEnabled false
            proguardFiles += file('proguard-rules.pro')
        }
    }
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    /*testCompile 'junit:junit:4.12'*///这一行删去
    compile 'com.android.support:appcompat-v7:23.4.0'
}

此处可以编译一下,看看是否出错,如果出错请仔细核对是否字符错误或包名没有改成你自己的。

据Google官网上说在官网上说,因为NDK还是实验版,不得已才让用户自己改代码,他们会逐渐让这些东西自动化。

在app/src/main文件夹上点右键,在弹出菜单中选择“New”、“Folder”、“JNI Folder”,按提示进行。
有一个“Change Folder Location”选项,不需要勾选,因为jni文件夹采用默认的位置(在main文件夹中)就行。然后main目录下会出现jni文件夹。


新建一个MyExample的类(与MainActivity在同一目录下),加载jni库,声明native方法

package com.ndkexample;

public class MyExample {
    static {
        System.loadLibrary("ndkexample");
    }
    public native void myLog();//打印日志信息的函数
}
此时你的myLog方法还是红色的,在上面按alt+enter生成c层的方法。
添加一个打印日志的方法_android_log_write(......);

#include <jni.h>
#include "android/log.h"
JNIEXPORT void JNICALL
Java_com_ndkexample_MyExample_myLog(JNIEnv *env, jobject instance) {
    // TODO
    __android_log_write(ANDROID_LOG_ERROR,"MainActivity","This is my first ndkexample!");

}
尤其不要忘记引入头文件log.h

之后clean project会在jni目录生成对应的头文件


然后在java层进行调用

package com.ndkexample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyExample myExample=new MyExample();
        myExample.myLog();
    }
}

编译运行可以看到日志信息被打印出来

06-22 20:36:25.984 31550-31550/? I/art: Late-enabling -Xcheck:jni
06-22 20:36:26.029 31550-31558/? I/art: Debugger is no longer active
06-22 20:36:26.057 31550-31550/? I/HwCust: Constructor found for class android.app.HwCustHwWallpaperManagerImpl
06-22 20:36:26.104 31550-31550/? I/HwCust: Constructor found for class android.widget.HwCustTextViewImpl
06-22 20:36:26.109 31550-31550/? I/HwCust: Constructor found for class android.widget.HwCustTextViewImpl
06-22 20:36:26.114 31550-31550/? E/MainActivity: This is my first ndkexample!
06-22 20:36:26.175 31550-31630/? I/OpenGLRenderer: Initialized EGL, version 1.4

至此成功。
如果遇到问题无法解决可以咨询我的QQ:1925554595



免责声明:文章转载自《Android Studio NDK开发入门》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇个人亲历运维面试myBatis 切换数据源(spring事务)理解下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

文件签名&amp;lt;魔塔50层&amp;gt;android反编译破解

发一下牢骚和主题无关: 缘由:该游戏作者有点可爱,原来就是拿别人的游戏,还在游戏中参加积分的轨制,打到20层后,需要积分。看不惯,就把它破解了,打到20层后,直接跳过要积分进程。 本文不提供破解后的安装包! 进程: 首先下载目标apk,我是从这里下载的:http://www.wandoujia.com/apps/com.ss.magicTower 然后下载...

android 调试 native 程序的方法

一、背景 首先说需求,这个需求非常常见,就是android上需要的一个功能,linux已经有开源代码而且非常稳定,希望能直接porting过去使用,这个程序是pure c 的代码,也就是说,跟android framework, java 没关系,也跟jni没有关系,我们希望的就是能编译成一个可执行工具,push到android后能直接跑起来使用。 既然是...

老李分享:Android -自动化埋点 3

又一个问题,代码中的writeLog方法到底要记录哪些数据作为log信息呢?log信息中最重要的是能让开发者看出来哪个界面被打开或者哪个控件被点 击。对于界面,可以记录其类名;对于控件,一般没有确定的名称,那么可以记录下来这个控件在界面中的路径。比如上文中介绍Android UI布局的实例,如果要定位记录那个Button,则可以记录它所在界面的类名和But...

[JAR包] android引入JAR包,打包成JAR包,打包成Library项目,导入Library项目

(1)项目导入JAR包:1、在项目目录里建立一个libs目录,将外部jar包拷贝在里面。2、右键点击项目,Bulid Path->Configure Build Path3、在设置Libraies项,选择刚才的位置添加jar包。3、在Order and Export项里,将外部jar包选中。4、clean项目后,重新编译,这时的apk包里应该是包含外...

Android JNI开发高级篇有关Android JNI开发中比较强大和有用的功能就是从JNI层创建、构造Java的类或执行Java层的方法获取属性等操作。 一、类的相关操作 1. jclass FindClass(JNIEnv *env, const char *name);

有关Android JNI开发中比较强大和有用的功能就是从JNI层创建、构造Java的类或执行Java层的方法获取属性等操作。 一、类的相关操作 1.jclass FindClass(JNIEnv *env, const char *name);查找类 该函数可能做过Java开发的不会陌生,这个是JNI层的实现,需要注意的是第二个参数为const char...

Android系统编程入门系列之广播接收者BroadcastReceiver实现进程间通信

在前边几篇关于Android系统两个重要组件的介绍中,界面Activity负责应用程序与用户的交互,服务Service负责应用程序内部线程间的交互或两个应用程序进程之间的数据交互。看上去这两大组件就能满足日常应用程序的开发需求了,可是应用程序之间的交互,如果都使用服务Service中的AIDL规范,那每个应用程序本身岂不是要声明其他应用程序中的一些接口?这...