AS下NDK开发(一)

捣鼓了一天的NDK,总结下。

Eclipse下开发ndk好像挺麻烦的样子,看书上要下载Cygwin,eclipse还要下载插件CDT。。而在AS上就方便多啦。下载android ndk。安装,配置环境,即可。

NDK(android native develop kits ):android 本地开发工具集 ,这些工具帮助开发者快速开发C或C++动态库,并自动将so和java文件打包成apk,可以把c/c++ ->编译成一个 linux下可以执行的二进制文件 java代码里面就可以通过jni 调用执行二进制的文件.

JNI :java本地开发接口,JNI是一个协议这个协议用来沟通java代码和外部的本地代码(c/c++).通过这个协议,java代码就可以调用外部的c/c++,代码外部的c/c++代码也可以调用java代码。

JNI开发用途:Native code效率高,数学运算,实时渲染的游戏上,音视频处理(极品飞车,opengl,ffmpeg等。

一、配置NDK环境

下载NDK,网上有很多,下载好之后,解压即可。然后在AS中配置,依次点击:File ->ProjectStructure:如图:

配置好之后,会在项目下的local.properties文件里自动添加:ndk.dir=D\:\\android-ndk-r10d   如果没有就自己加上,我的是自动的。

二、建立app项目

1.建立一个普通的android project

2.声明原生方法,必须加上native,告诉程序这是一个原生方法。在具体java代码调用时,和调用java的其他方法一样,直接调用就可以了。activity代码:

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

public class NDK extends Activity {

    static {
        System.loadLibrary("MyJni");//导入生成的链接库文件
    }

    public native String getStringFromNative();//本地方法
    public native String getString_From_c();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ndk);
    }

    public void onClick(View view) {
        System.out.println(getString_From_c());
        Toast.makeText(this, getStringFromNative(), Toast.LENGTH_LONG).show();
    }
}

System.loadLibrary("MyJni");加载库,需要注意的是加载的库名即编译生成的库名,去掉前缀lib和后缀so。

然后make project一下,目的就是编译成对应的class文件。然后根据生成的class文件,利用javah生成对应的 .h头文件。

三、生成.h头文件

1.AS中点击view ->ToolsWindows->Terminal,cd app\src\main,进入src\main\目录下:2.执行:
javah -d jni -classpath F:\android\sdk\platforms\android-23\android.jar;..\..\build\intermediates\classes\debug example.user.ndkdemo2.NDK这个命令很长,分开慢慢来,javah是生成头文件需要的工具,-d jni 在工程下生成jni目录,到时会在这个目录下建JNI开始的C/C++源文件的。
-classpath F:\android\sdk\platforms\android-23\android.jar 这个就是你SDK文件下android.jar所在的文件位置,找到后复制即可。
..\..\build\intermediates\classes\debug 这个路径如图所示:

example.user.ndkdemo2.NDK就是NDKclass的路径名。

执行完这个命令后,会在main文件夹下自动生成jni目录和.h头文件。

可以打头文件看看:

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

#ifndef _Included_example_user_ndkdemo2_NDK
#define _Included_example_user_ndkdemo2_NDK
#ifdef __cplusplus
extern "C" {
#endif
#undef example_user_ndkdemo2_NDK_BIND_ABOVE_CLIENT
#define example_user_ndkdemo2_NDK_BIND_ABOVE_CLIENT 8L
#undef example_user_ndkdemo2_NDK_BIND_ADJUST_WITH_ACTIVITY
#define example_user_ndkdemo2_NDK_BIND_ADJUST_WITH_ACTIVITY 128L
#undef example_user_ndkdemo2_NDK_BIND_ALLOW_OOM_MANAGEMENT
#define example_user_ndkdemo2_NDK_BIND_ALLOW_OOM_MANAGEMENT 16L
#undef example_user_ndkdemo2_NDK_BIND_AUTO_CREATE
#define example_user_ndkdemo2_NDK_BIND_AUTO_CREATE 1L
#undef example_user_ndkdemo2_NDK_BIND_DEBUG_UNBIND
#define example_user_ndkdemo2_NDK_BIND_DEBUG_UNBIND 2L
#undef example_user_ndkdemo2_NDK_BIND_IMPORTANT
#define example_user_ndkdemo2_NDK_BIND_IMPORTANT 64L
#undef example_user_ndkdemo2_NDK_BIND_NOT_FOREGROUND
#define example_user_ndkdemo2_NDK_BIND_NOT_FOREGROUND 4L
#undef example_user_ndkdemo2_NDK_BIND_WAIVE_PRIORITY
#define example_user_ndkdemo2_NDK_BIND_WAIVE_PRIORITY 32L
#undef example_user_ndkdemo2_NDK_CONTEXT_IGNORE_SECURITY
#define example_user_ndkdemo2_NDK_CONTEXT_IGNORE_SECURITY 2L
#undef example_user_ndkdemo2_NDK_CONTEXT_INCLUDE_CODE
#define example_user_ndkdemo2_NDK_CONTEXT_INCLUDE_CODE 1L
#undef example_user_ndkdemo2_NDK_CONTEXT_RESTRICTED
#define example_user_ndkdemo2_NDK_CONTEXT_RESTRICTED 4L
#undef example_user_ndkdemo2_NDK_MODE_APPEND
#define example_user_ndkdemo2_NDK_MODE_APPEND 32768L
#undef example_user_ndkdemo2_NDK_MODE_ENABLE_WRITE_AHEAD_LOGGING
#define example_user_ndkdemo2_NDK_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
#undef example_user_ndkdemo2_NDK_MODE_MULTI_PROCESS
#define example_user_ndkdemo2_NDK_MODE_MULTI_PROCESS 4L
#undef example_user_ndkdemo2_NDK_MODE_PRIVATE
#define example_user_ndkdemo2_NDK_MODE_PRIVATE 0L
#undef example_user_ndkdemo2_NDK_MODE_WORLD_READABLE
#define example_user_ndkdemo2_NDK_MODE_WORLD_READABLE 1L
#undef example_user_ndkdemo2_NDK_MODE_WORLD_WRITEABLE
#define example_user_ndkdemo2_NDK_MODE_WORLD_WRITEABLE 2L
#undef example_user_ndkdemo2_NDK_DEFAULT_KEYS_DIALER
#define example_user_ndkdemo2_NDK_DEFAULT_KEYS_DIALER 1L
#undef example_user_ndkdemo2_NDK_DEFAULT_KEYS_DISABLE
#define example_user_ndkdemo2_NDK_DEFAULT_KEYS_DISABLE 0L
#undef example_user_ndkdemo2_NDK_DEFAULT_KEYS_SEARCH_GLOBAL
#define example_user_ndkdemo2_NDK_DEFAULT_KEYS_SEARCH_GLOBAL 4L
#undef example_user_ndkdemo2_NDK_DEFAULT_KEYS_SEARCH_LOCAL
#define example_user_ndkdemo2_NDK_DEFAULT_KEYS_SEARCH_LOCAL 3L
#undef example_user_ndkdemo2_NDK_DEFAULT_KEYS_SHORTCUT
#define example_user_ndkdemo2_NDK_DEFAULT_KEYS_SHORTCUT 2L
#undef example_user_ndkdemo2_NDK_RESULT_CANCELED
#define example_user_ndkdemo2_NDK_RESULT_CANCELED 0L
#undef example_user_ndkdemo2_NDK_RESULT_FIRST_USER
#define example_user_ndkdemo2_NDK_RESULT_FIRST_USER 1L
#undef example_user_ndkdemo2_NDK_RESULT_OK
#define example_user_ndkdemo2_NDK_RESULT_OK -1L
#undef example_user_ndkdemo2_NDK_MAX_NUM_PENDING_FRAGMENT_ACTIVITY_RESULTS
#define example_user_ndkdemo2_NDK_MAX_NUM_PENDING_FRAGMENT_ACTIVITY_RESULTS 65534L
#undef example_user_ndkdemo2_NDK_HONEYCOMB
#define example_user_ndkdemo2_NDK_HONEYCOMB 11L
#undef example_user_ndkdemo2_NDK_MSG_REALLY_STOPPED
#define example_user_ndkdemo2_NDK_MSG_REALLY_STOPPED 1L
#undef example_user_ndkdemo2_NDK_MSG_RESUME_PENDING
#define example_user_ndkdemo2_NDK_MSG_RESUME_PENDING 2L
/*
 * Class:     example_user_ndkdemo2_NDK
 * Method:    getStringFromNative
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_example_user_ndkdemo2_NDK_getStringFromNative
  (JNIEnv *, jobject);

/*
 * Class:     example_user_ndkdemo2_NDK
 * Method:    getString_From_c
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_example_user_ndkdemo2_NDK_getString_1From_1c
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

这个文件中:JNIEXPORT jstring JNICALL Java_example_user_ndkdemo2_NDK_getStringFromNative(JNIEnv *, jobject);这是函数定义,Java_<packege_path>_<class_name>_<method_name>(JNIEnv *, jobject,<parameter_list>);

函数定义中这两个参数:JNIEnv *, jobject是必须的,之后才是需要在函数调用时需要传递的参数,如:

Java_<packege_path>_<class_name>_<method_name>(JNIEnv *, jint value1,jint value2);//jint是什么意思,在后边说明。jint就是代表的Java里的int类型。

四,创建C文件,实现native方法

在jni目录下建立c文件:util.c是一个空文件,这是因为NDK在windows系统上的一个bug,没有会出错,你也可以不建,如果出错再建也没事。

c文件:

#include "example_user_ndkdemo2_NDK.h"
//#include <android/log.h>
//#define  LOG_TAG  "System.out"
//#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG,  __VA_ARGS__)
//#define LOGINFO(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG,  __VA_ARGS__)

JNIEXPORT jstring JNICALL Java_example_user_ndkdemo2_NDK_getStringFromNative
        (JNIEnv * env, jobject jobject){
   // LOGINFO("LOGINFO");
    return (*env)->NewStringUTF(env,"NDK 测试成功");
}

JNIEXPORT jstring JNICALL Java_example_user_ndkdemo2_NDK_getString_1From_1c
        (JNIEnv * env, jobject jobject){

    return  (*(*env)).NewStringUTF(env,"NDK 来自于C文件");

}
//
// Created by user on 2016/4/13.
//

最后还有配置一个地方:build.gradle文件的defaultConfig中加ndk

android.mk文件位置:

五、jni.h文件

在jni.h文件中,定义了本地的数据类型和对象的引用类型,编写c代码时要注意必须使用这些定义的数据类型和对象的引用类型

对象数据:

				
时间: 2024-12-25 00:49:14

AS下NDK开发(一)的相关文章

AndroidStudio环境下ndk开发

AndroidStudio环境下ndk开发的基本步骤是,写本地方法生成头文件,用c/c++实现本地方法,配置android.mk文件生成so文件.具体步骤如下 1.创建android工程:MyJni. 2.写本地方法,并编译成class文件,在\app\build\intermediates\classes\debug中找. public class MainActivity extends AppCompatActivity { static { System.loadLibrary("Jni

android下NDK开发环境搭建及TestJNI入门实例完整过程

1.先搭建好基本的ndk的开发环境 在windows下安装下面两个软件 1. Android NDK 安装 2. 安装Cygwin与使用NDK编译 本文建立在已经完成Android开发环境搭建的基础上.其基础环境至少需要包含以下内容: 1. JDK 2. Eclipse 3. Android SDK and ADT 一.Android NDK 安装与配置 下载Android NDK.下载地址:http://developer.android.com/tools/sdk/ndk/index.htm

【转】Android NDK学习(2)Windows下NDK开发环境配置

一.配置好Android开发环境 现在android SDK的版本已经到了4.4了,几乎不用配置,下载下来解压,SDK跟Android开发专用Eclipse都有了.喜欢. 二.下载安装安卓NDK 下载最新版,解压即可. 2013年6月7日: 目前版本已经到了r8e. 三.下载安装cygwin   由于NDK编译代码时必须要用到make和gcc,所以你必须先搭建一个linux环境, cygwin是一个在windows平台上运行的unix模拟环境,它对于学习unix/linux操作环境,或者从uni

Android学习笔记—Windows下NDK开发简单示例

该示例假设Android开发环境已经搭建完成,NDK也配置成功: 1.在Eclipse上新建Android工程,名称为ndkdemo.修改res\layout\activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layo

Windows下NDK开发环境搭建

Cygwin 介绍 cygwin是windwos下的linux环境模拟器.   为什么需要cygwin?  因为NDK只能在Linux环境下运行. 安装流程 1.打开cygwin的可执行文件,执行扩展库安装地址. 我这里选择Install from Local Directory,因为扩展库我已经下载到本地了. 2.选择安装目录,目录名不能有空格或者中文 3.因为选择的是本地安装,所以需要指定插件包 4.选择需要安装的插件,Devel(编译),Shells(执行脚本) 5.安装完成后在点击桌面的

NDK在windows下的开发环境搭建及开发过程

在Android应用的开发project中.无论是游戏还是普通应用.都时常会用到.so即动态链接库,关于.so是什么玩意儿,有什么优点.这个大家能够在网上查一下,本人不做过多解释. .so本是linux下的文件类型,所以编译.so必需要在linux环境下,那么怎样在win下进行编译呢?随便在网上搜下,教程也是五花八门,不清不楚,没有一定功底,即便看着教程到最后预计还是功败垂成,更别说刚開始学习的人,看了保证头晕眼花,本人也是依据网上的一些样例.总结了一个个人觉得还算比較简单的一个.so的编译方法

C++开发安卓、windows下搭建Android NDK开发环境

1. NDK(Native Development Kit) 1.1 NDK简介 Android NDK是一套允许开发人员使用本地代码(如C/C++)进行Android APP功能开发的工具,通过这个工具,我们可以把用C/C++代码编译成可以直接运行在Android平台上的本地代码,这些本地代码以动态链接库( *.so )的形式存在,也正因为这样,我们可以通过复用这些动态链接库从而复用本地代码. 那么,通过NDK这个开发工具包,那么我们是否可以将一个APK完全使用C/C++来编写呢? 答案是不可

Eclipse下Android的NDK开发环境配置

摸索了一周,走了很多弯路,磕磕绊绊,总算是弄好了NDK的开发环境,在这里总结一下吧. 一.Android NDK开发环境 首先下载安装JRE.JDK,不必多说.然后下载NDK包,建议下载r10版本后的,自带C/C++的编译器,不需要使用外部编译器的麻烦了.下载完NDK包后,解压缩即可,需要之后关联到Eclipse.然后下载ADT Bundle,即安卓开发工具套装,里面集成好的Eclipse的安卓开发环境,但是,里面的版本可能较低而且没有集成NDK功能,可以通过SDK Manager进行更新SDK

Windows下Android+NDK开发环境搭建(JDK[8u45]+Eclipse+Android SDK[r24.1.2]+ADT+NDK[r10d])

一.Android开发环境搭建 1.安装JDK. (1)简介:JDK,即Java Development Kit,是Java语言的软件开发工具包.JRE,即Java Runtime Environment,是Java的运行环境,是面向Java的使用者而非开发者. (2)下载:点击打开链接(Oracle官网),选择对应系统的版本,我下载的是jdk-8u45-windows-i586.exe. (3)安装:双击进行安装,程序刚安装时设置的安装目录为JDK的安装目录,中途需要设置JRE的安装目录.为进