Android For JNI(六)——交叉编译,NDK概述以及文件结构,编写自己的第一个JNI工程
Android For JNI(六)——交叉编译,NDK概述以及文件结构,编写自己的第一个JNI工程
终于回到我们的 android了,我们先要配置这个NDK的环境,但是之前,我们还要了解一下基本的术语
一.交叉编译
- 在一个平台下编译出另一个平台可以执行的二进制程序
- CPU平台:ARM X86 MIPS(指令集)
- 系统平台:windows linux mac
- 原理:模拟另一个平台的特性去编译程序
- 源代码——>预编译——>编译——>链接——>可执行程序
- 工具链:一个工具使用自动调用下一个
二.JNI常用工具
- NDK : Native Developer Kits
- CDT : C/C++ Developer Tools(插件/高亮显示C关键字)
- Cygwin:Windows下的linux模拟器(ROM系列有讲)
三.NDK配置
NDK下载地址:下载地址:http://wear.techbrood.com/tools/sdk/ndk/
1.NDK产生的背景
Android平台从诞生起,就已经支持C、C++开发。众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第三方应用都必须使用Java语言。但这并不等同于“第三方应用只能使用Java”。在Android SDK首次发布时,Google就宣称其虚拟机Dalvik支持JNI编程方式,也就是第三方应用完全可以通过JNI调用自己的C动态库,即在Android平台上,“Java+C”的编程方式是一直都可以实现的。
不过,Google也表示,使用原生SDK编程相比Dalvik虚拟机也有一些劣势,Android SDK文档里,找不到任何JNI方面的帮助。即使第三方应用开发者使用JNI完成了自己的C动态链接库(so)开发,但是so如何和应用程序一起打包成apk并发布?这里面也存在技术障碍。比如程序更加复杂,兼容性难以保障,无法访问Framework API,Debug难度更大等。开发者需要自行斟酌使用。
于是NDK就应运而生了。NDK全称是Native Development Kit。
NDK的发布,使“Java+C”的开发方式终于转正,成为官方支持的开发方式。NDK将是Android平台支持C开发的开端。
2.为什么使用NDK
1.代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。
2.可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。
3.提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。
4.便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。
3.NDK简介
- 1.NDK是一系列工具的集合
NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。
NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。
NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。
- 2.NDK提供了一份稳定、功能有限的API头文件声明
Google明确声明该API是稳定的,在后续所有版本中都稳定支持当前发布的API。从该版本的NDK中看出,这些API支持的功能非常有限,包含有:C标准库(libc)、标准数学库(libm)、压缩库(libz)、Log库(liblog)。
我们先下载安装NDK吧!
4.NDK目录结构
我们下载好之后就直接解压
我们来分析一下
- docs:帮助文档
- build/tools:Linux批处理文件
- platforms:存放JNI用到的h头文件和so类库
- prebuilt:预编译使用的工具
- samples:小例子
- sources:NDK的部分源码
toolchains:工具链
ndk-build.cmd:编译打包C代码
其实跟SDK还是类似的,我们就不细说了
四.HelloJNI
我们来创建自己的第一个jni工程,我们在eclipse中新建一个工程——HelloJNI,额,问我为什么不用android studio,这个…..还不是很熟练,因为工作需要,一直用的是eclipse,看NDK的文件夹下的例子我们知道,首先,我们要创建一个jni的目录,我们新建
我们新建一个C类,再次之前,我们先看一下api里的哪个hello-jni的例子中c程序是怎么写的
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <string.h>
#include <jni.h>
/* This is a trivial JNI example where we use a native method
* to return a new VM String. See the corresponding Java source
* file located at:
*
* apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java
*/
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
#if defined(__ARM_NEON__)
#if defined(__ARM_PCS_VFP)
#define ABI "armeabi-v7a/NEON (hard-float)"
#else
#define ABI "armeabi-v7a/NEON"
#endif
#else
#if defined(__ARM_PCS_VFP)
#define ABI "armeabi-v7a (hard-float)"
#else
#define ABI "armeabi-v7a"
#endif
#endif
#else
#define ABI "armeabi"
#endif
#elif defined(__i386__)
#define ABI "x86"
#elif defined(__x86_64__)
#define ABI "x86_64"
#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */
#define ABI "mips64"
#elif defined(__mips__)
#define ABI "mips"
#elif defined(__aarch64__)
#define ABI "arm64-v8a"
#else
#define ABI "unknown"
#endif
return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");
}
这里,前面是注释,不用管,我们看最后的return,我们在jni的目录下写一个c文件
#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
/**
* 计算相加
* 定义一个本地函数
* env:结构体二级指针,该结构体封装了大量的函数指针,方便我们开发某些功能
* thiz:本地方法调用者的对象,这里值MainActvity的对象
*/
jstring Java_com_lgl_hellojni_MainActivity_HelloJNI(JNIEnv* env, jobject thiz) {
char* cstr = "hello jni";
//把C字符串转换成java字符串
/**
* 官方文档:return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");
*/
jstring jstr = (*env)->NewStringUTF(env,cstr);
return jstr;
}
写完之后,我们运行是没用的,我们这里是需要手动编译的
我们进入我们的源文件目录下,打开cmd,输入ndk-build.cmd去编译,他会报一个错误,原因是路径,我们缺少了一个mk文件,要创建这个文件,我们需要查看一下android-mk.html的文档,我们在jni目录下新建一个Android.mk文件,把这段话复制进去
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello_jni //生成的文件名
LOCAL_SRC_FILES := hello_jni.c //要编译的文件
include $(BUILD_SHARED_LIBRARY)
现在,我们可以编译了,编译完成之后,libs目录下会有一个动态的链接库
我们执行的就是这个库
当然,我们现在还需要去加载动态链接库,我们回到MainActivity
static{
//模块名字
System.loadLibrary("hello-jni");
}
然后我们可以使用了
Toast.makeText(this, HelloJNI(), Toast.LENGTH_LONG).show();
但是这里运行的话需要arm平台的,你在X86平台上是没用的,文章前面也说了,如果大家编译晕倒困难,那就是相关配置没配好,这里推荐
Demo下载:http://download.csdn.net/detail/qq_26787115/9501088
Android For JNI(六)——交叉编译,NDK概述以及文件结构,编写自己的第一个JNI工程的更多相关文章
- 史上最易懂的Android jni开发资料--NDK环境搭建
谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK.而在NDKr7开始,Google的Windows版的NDK提供 ...
- Android jni开发资料--NDK环境搭建
谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK.而在NDKr7开始,Google的Windows版的NDK ...
- 【Android】Eclipse自动编译NDK/JNI的三种方法
[Android]Eclipse自动编译NDK/JNI的三种方法 SkySeraph Sep. 18th 2014 Email:skyseraph00@163.com 更多精彩请直接访问SkySer ...
- android 串口开发第一篇:搭建ndk开发环境以及第一个jni调用程序
一:ndk环境搭建 1:开发环境 我使用的是android studio 2.3.3版本,搭建ndk开发环境比较简单,打开File----Settings----Appearance&Beha ...
- 使用Android Studio自带的NDK编译JNI
/********************************************************************************** * 使用Android Stud ...
- Android For JNI(一)——JNI的概念以及C语言开发工具dev-c++,编写你的第一个C语言程序,使用C启动JAVA程序
Android For JNI(一)--JNI的概念以及C语言开发工具dev-c++,编写你的第一个C语言程序 当你的Android之旅一步步的深入的时候,你其实会发现,很多东西都必须去和framew ...
- Android SDK +Eclipse+ADT+CDT+NDK 开发环境在windows 7下的搭建
Android SDK+Eclipse+ADT+CDT+NDK 开发环境在windows 7下的搭建 这几天一直在研究 Android SDK C/C++平台的搭建,尽管以前有成功在Windows ...
- Android学习笔记—Windows下NDK开发简单示例
该示例假设Android开发环境已经搭建完成,NDK也配置成功: 1.在Eclipse上新建Android工程,名称为ndkdemo.修改res\layout\activity_main.xml &l ...
- Android群英传笔记——摘要,概述,新的出发点,温故而知新,可以为师矣!
Android群英传笔记--摘要,概述,新的出发点,温故而知新,可以为师矣! 当工作的越久,就越感到力不从心了,基础和理解才是最重要的,所以买了两本书,医生的<Android群英传>和主席 ...
随机推荐
- Unity发布至IOS的流程(踩坑记录)
这篇文章主要用于记录本人亲身经历过的Unity发布到IOS平台所遇到的所有坑(其实也就是一些自己并不明白的强制设定),以便于后续再有类似需求时少走些弯路. 我的环境: Unity 5.2.2 个人版( ...
- 带有进度条的WebView
带有进度条的WebView 本篇继于WebView的使用 效果图 自定义一个带有进度条的WebView package com.kongqw.kbox.view; import android.con ...
- DB 查询分析器7.01 新增的保存执行结果到多个文件功能
1 引言 中国本土程序员马根峰(CSDN专访马根峰:海量数据处理与分析大师的中国本土程序员)推出的个人作品----万能数据库查询分析器,中文版本DB 查询分析器.英文版本< ...
- Gradle 1.12用户指南翻译——第五十二章. Maven 插件
本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见:http://blog.csdn.net/column/details/gradle-translation.html翻译项目请关注Github上 ...
- Android Multimedia框架总结(二十二)MediaCodec中C++中创建到start过程及状态变换
上一章介绍MediaCodec中创建到start过程(到jni部分),从今天开始,将深入源码中看看其c++过程,看下Agenda如下: mediacodec.h CreateByType initMe ...
- Unity角色残影特效
残影特效在网上有很多例子,比如这个,我参考着自己整合了一下,算是整合了一个比较完整且特别简单易用的出来,只需要一个脚本挂上去无需任何设定就能用. 这里只针对SkinnedMeshRenderer的网格 ...
- WmS简介(三)之Activity窗口是如何创建的?基于Android7.0源码
OK,在前面两篇博客中我们分别介绍了WmS中的token,同时也向小伙伴们区分了Window和窗口的区别,并且按照type值的不同将Android系统中的窗口分为了三大类,那么本篇博客我们就来看看应用 ...
- android 图片网络下载github开源框架之Universal-Image-Loader
最近在做妙趣剪纸项目,剪纸应用项目链接.发扬传统文化,大家多多关注. 需要自己搭建服务器,我用的是新浪sae,简直秒杀京东云几条街,把图片放在网上下载,但是图片经常下载要遇到很多问题,包括oom等.所 ...
- Linux for sougou ping yin (http://pinyin.sogou.com/linux/help.php)
安装指南 Ubuntu / Ubuntu Kylin 14.04 LTS 版本 只需双击下载的 deb 软件包,即可直接安装搜狗输入法. Ubuntu 12.04 LTS 版本 由于 Ubuntu 1 ...
- Android全屏截图的方法,返回Bitmap并且保存在SD卡上
Android全屏截图的方法,返回Bitmap并且保存在SD卡上 今天做分享,需求是截图分享,做了也是一个运动类的产品,那好,我们就直接开始做,考虑了一下,因为是全屏的分享,所有很自然而然的想到了Vi ...