Android NDK

1、Android NDK

这篇博客写的非常详细
http://bbs.51cto.com/thread-1316339-1-1.html

NDK是一个android开发工具(google在developer官网上也是把它放到tools介绍的),可以实现调用本地的c/c++代码。对于某些应用程序,用java实现不了,或者难以实现。用NDK可以利用现有的代码库(c/c++库)。
这里写图片描述
典型的的NDK的使用的场景,CPU密集型操作无法分配足够的内存,如信号处理、物理模拟等。比如做游戏开发,游戏场景特效,或者是有比较成熟的c/c++库能够很好的利用。
概括来说主要分为以下几种情况:

  1. 代码的保护,由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。
  2. 在NDK中调用第三方C/C++库,因为大部分的开源库都是用C/C++代码编写的。
  3. 便于移植,用C/C++写的库可以方便在其他的嵌入式平台上再次使用。

2、JNI与NDK

JNI表示Java Native Inteface,是Java中定义的一种用于连接Java和C/C++接口的一种实现方式。

NDK表示Native Development Kit,是Google在Android开发中提供的一套用于快速创建native工程的一个工具。使用这个工具可以很方便的编写,调试JNI的代码。

在android早期并没有ndk。如果我们想要调用c/c++库或者代码就得用java的jni去调用c/c++。耍小聪明走后门一样。而ndk的出现就意味着jni调用的这种方法转正了变成官方支持的一样。
可是这样还是没有说到为什么要有ndk啊。是的我只想说的就是如果你要操作底层直接操作内存。操作地址那你不得不去使用c/c++因为java这块想做这些(java与c/c++相对,效率有点低,而且不能操作内存)。那恐怕有点困难。所以ndk是必须需要出现的。

2、Android Sutido下环境搭建

如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK。而在NDKr7开始,Google的Windows版的NDK提供了一个ndk-build.cmd的脚本,这样,就可以直接利用这个脚本编译,而不需要使用Cygwin了。这样极大的简化的环境搭建的配置。

1、下载ndk(android-ndk-r10d下面附上下载地址)
2、as关联ndk: file->project structure->sdk location->选择ndk的路径关系
这里写图片描述

3、NDK需要的配置文件(比较繁琐,需耐心配置,出错的地方比较多,一步一步来)

3.1、新建项目

3.2 、目前的NDK只支持gradle2.5,版本高了或者低了都不行,因此要首先下载gradle2.5的版本,并且把当前的版本改成gradle2.5(下面附上gradle2.5的下载地址)

这里写图片描述
复制代码

#Sun May 29 18:01:10 CST 2016
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

3.3、修改project下的buide.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
}

3.4、修改app下的build.gradle文件(重点,这个地方配置比较多,要看清楚修改的哪个地方)

这里写图片描述
复制代码

apply plugin: 'com.android.model.application'

model {
    android {
        compileSdkVersion = 22
        buildToolsVersion = "22.0.1"
        defaultConfig.with {
            applicationId = "com.example.administrator.myapplication" //这是程序包名
            minSdkVersion.apiLevel = 15
            targetSdkVersion.apiLevel = 22
            versionCode = 1
            versionName = "1.0"
        }
        tasks.withType(JavaCompile) {
            sourceCompatibility = JavaVersion.VERSION_1_7
            targetCompatibility = JavaVersion.VERSION_1_7
        }
    }
    android.ndk {
        moduleName = "lb"
    }
    android.buildTypes {
        release {
            minifyEnabled = true
            proguardFiles.add(file("proguard-rules.pro"))
        }
    }
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.2.1'
    compile 'com.android.support:design:22.2.1'
}

3.5 gradle版本报错解决:点击gradle settins(注意要首先下载gradle2.5版本)

这里写图片描述

这里写图片描述

这样NDK的环境基本就搭建完成

4、完成第一个NDK demo

4.1、 创建jni文件

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

4.2、 创建c++

在jni文件夹上点右键,在弹出菜单中选择“New”、“C/C++ Source File”。
在出现的对话框中,给即将创建的C++文件取名(不要加后缀,软件会自动加上的)。
有一个选项“Create associated header”,不要勾选它,现在不需要创建头文件。
创建my_library后在jni目录下出现一个c++文件

4.3、创建一个Java文件,调用用于调用c++库

这里写图片描述
复制代码

public class Load {

    static { 
        System.loadLibrary("lb");
    }
    public native int addInt(int a, int b);
}

4.4、生成.h头文件,打开Terminal命令框

这里写图片描述
第一步:进入debug模式下

cd app/build/intermediates/classes/debug

第二步:用javah生成头文件(注意自己的包名)

javah -jni com.example.administrator.myapplication.Load

这样,就生成.h头文件了
然后把这个文件右键cut->我们jni目录下最终成这样
这里写图片描述
打开查看代码如下:

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

#ifndef _Included_com_example_administrator_myapplication_Load
#define _Included_com_example_administrator_myapplication_Load
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_administrator_myapplication_Load
 * Method:    addInt
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_example_administrator_myapplication_Load_addInt
  (JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

4.5、编辑源文件

加入我们需要调用的方法在my_library中(在实际开发中,就是我们需要调用的c/c++库)
这里写图片描述
代码如下(一个方法,传入两个int值,返回它们的和):

//
// Created by Administrator on 2016/5/29.
//
#include "com_example_administrator_myapplication_Load.h"


JNIEXPORT jint JNICALL Java_com_example_administrator_myapplication_Load_addInt (JNIEnv *, jobject, jint a, jint b) {
    return a * b;
}

4.6、这样一切都已经完成了,只需要调用一下,去现我们这个方法就可以了

package com.example.administrator.myapplication;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
    private Button btn;
    private TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn= (Button) findViewById(R.id.btn);
        tv= (TextView) findViewById(R.id.tv);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              Load load=new Load();
              int count=load.addInt(10,20);
                tv.setText(""+count);
            }
        });

    }

}

Gradle-2.5下载地址

http://download.csdn.net/detail/androidxiaogang/9534777

示例Demo下载地址

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值