靠谱 的软件外包伙伴

您的位置:首页 > 新闻动态 > Android NDK app开发——环境配置

Android NDK app开发——环境配置

2016-08-26 16:08:13

以前的NDK开发,需要使用cygwin模拟Linux环境,用ndk-build进行编译,虽然可以配置环境变量大大缩减编译复杂度,但是每次在eclipse改完代码,再用cygwin编译总是怪怪的。而且每次有新工程使用JNI时还要手动新建jni文件夹和Android.mk这些步骤,显得特别繁琐。

而现在,android NDK r7及以上的版本已经集成了Cygwin编译环境,也就是说,我们完全可以抛弃庞大的Cygwin了。使用NDK开发包可以自动为我们准备一切JNI的前奏,下面我们看看在eclipse下如何进行NDK开发。

安装NDK包

由于包太大,只能放在网盘:ndk-r10d-windows-32&64,提取码:93a1。

解压后,在eclipse –> window –> perference –> Android –> NDK标签中指定NDK所在的目录(只需要执行一次)

这里写图片描述

给工程添加JNI支持

在工程上右键 –> Android Tools –> Add Native Support

这里写图片描述

在弹出的对话框中,添加so库的名字

这里写图片描述

如此,eclipse便会自动生成jni文件夹,Android.mk文件和cpp文件。

这里写图片描述

值得一提的是,eclipse为我们自动生成的是C++文件,如果需要C文件,直接改后缀即可,然后注意c和c++指针调用时候的区别,下面会提到。

链接源码

在没有链接源码之前,在eclipse中打开c或者c++文件,会发现很多黄色下划线。

这里写图片描述

而且Ctrl点击还不能看到源码,强迫症患者表示很难接受,下面我们来给强迫症患者治病。

在工程点击右键 –> properties –> C/C++ General –> Paths and Symbols右侧点击add按钮 –> 点击File System –> 选择android-ndk-r9b\platforms\android-19\arch-arm\usr\include, 然后点击OK即可。

这里写图片描述

再回头看看该死的小黄线不见了,ctrl点击还能看见源码了。

编写Java层调用代码

环境配置相当简单,上面已经是全部了,下面我们以HelloJNI项目,示范下NDK开发步骤。第一步肯定是要编写java调用代码了。

package com.example.hellojni;

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

public class MainActivity extends Activity {
    //1、声明Native方法
    public native String javaFromJNI();  
    //2、使用前要装载so库
    static {  
        System.loadLibrary("HelloJNI");  
    }  

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button1).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, javaFromJNI(), Toast.LENGTH_LONG).show();
            }
        });
    }
}
  • 		1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

生成头文件

在C++文件中定义native方法,方法签名规则是:返回值类型 Java_包名_类名_native方法名(JNIEnv* env, jobject obj)

其中这两个参数是必备的,其他参数应该依次排在后面。可以看出规则生成的方法签名比较长,很容易出错,所以我们可

以使用javah命令帮我们生成头文件。

这里写图片描述

这里我们要先进入项目的src目录,例如我的目录是:D:\eclipseworkspace\LYGworkspace\HelloJNI_gk\src

使用-encoding utf-8是为了指定编码,因为编译器自动根据windows默认的编码(GBK)编译,如果不加这个,可能会报这个错:

这里写图片描述

如果javah命令不能使用,请先配置JDK环境。

经过上面的javah编译,src目录下就会生成一个h头文件。

这里写图片描述

然后就可以把它粘贴到项目的jni文件夹下,打开看看:

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

#ifndef _Included_com_example_hellojni_MainActivity
#define _Included_com_example_hellojni_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_hellojni_MainActivity
 * Method:    javaFromJNI
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_hellojni_MainActivity_javaFromJNI
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
  • 		1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

可以看到我们在MainActivity中声明的javaFromJNI方法已经被自动生成了,我们只需要引用这个头文件即可。而且这样做,无论是c文件还是c++文件都是通用的,不会出现兼容问题。

编写本地代码

接下来就是整体了,这部分的代码由c或者c++语言编写,可能很多搞android的看着都比较头疼,不过一般这部分都有专人写,我们能看懂就可以了。我们看下helloJNI的这部分代码,还是很简单的:

#include<stdio.h>
#include <jni.h>
#include "com_example_hellojni_MainActivity.h"

jstring Java_com_example_hellojni_MainActivity_javaFromJNI(JNIEnv* env, jobject obj){
    return env->NewStringUTF( "Hello JNI, GK!");
}
  • 		1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面是c++写法,如果是c文件,只要稍微改一下语法即可:

return env->NewStringUTF( "Hello JNI, GK!");
  • 		1

改成

return (*env)->NewStringUTF(env, "Hello JNI, GK!");
  • 		1

我们使用NDK开发包时,编写这部分代码时依然可以使用Alt+/进行代码提示:

这里写图片描述

修改Android.mk文件

一个Android.mk 文件用来向编译系统描述你的源代码,是交叉编译器在编译C/C++代码所依赖的配置文件。接下来,我们要修改eclipse为我们自动生成的Android.mk文件。


LOCAL_PATH := $(call my-dir)//mk文件所在路径 

include $(CLEAR_VARS)//变量的初始化操作 特点:不会重新初始化LOCAL_PATH的变量  

LOCAL_MODULE    := HelloJNI//指定编译后生成的.so文件名

LOCAL_SRC_FILES := hello_jni.cpp//指定native代码文件,如果使用了c++库,需要把所有c和h文件都列出来

include $(BUILD_SHARED_LIBRARY)//指定native代码编译成动态库.so或者指定编译成静态库.a  
  • 		1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

编译

直接Build Project,控制台出现以下提示,编译成功,至此,我们就完成了一次NDK开发之旅。


**** Build of configuration Default for project HelloJNI_gk ****

D:\NDK\android-ndk-r10d\ndk-build.cmd all 
[armeabi] Compile++ thumb: HelloJNI <= hello_jni.cpp
[armeabi] SharedLibrary  : libHelloJNI.so
[armeabi] Install        : libHelloJNI.so => libs/armeabi/libHelloJNI.so

**** Build Finished ****

关于:中科研拓
深圳市中科研拓科技有限公司专注提供软件外包、app开发、智能硬件开发、O2O电商平台、手机应用程序、大数据系统、物联网项目等开发外包服务,十年研发经验,上百成功案例,中科院软件外包合作企业。通过IT技术实现创造客户和社会的价值,致力于为用户提供最佳的软件解决方案。联系电话400-0316-532,邮箱sales@zhongkerd.com,网址www.zhongkerd.com


  上一篇   [返回首页] [打印] [返回上页]   下一篇