① 关于android NDK 开发方面的书籍有哪些推荐
推荐网上的两篇tutorial,英文的,但是讲的比较全面。
Mastering Android NDK Build System- Part 1: Techniques with ndk-build
Mastering Android NDK Build System- Part 2: Standalone toolchain
这两篇介绍了怎样编译native程序。
然后再找一个介绍JNI的文章看一下,基本就能掌握NDK的运用了。
② Android NDK开发简介 NDK和SDK以及JNI有什么关系
NDK:Android NDK 是在SDK前面又加上了“原生”二字,即Native Development Kit,因此又被Google称为“NDK”。
NDK全称:Native Development Kit。
NDK是一系列工具的集合。
* NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。
* NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。
* NDK可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。
其实:
NDK就是能够方便快捷开发.so文件的工具。JNI的过程比较复杂,生成.so需要大量操作,而NDK就是简化了这个过程。
Android SDK:
SDK (software development kit)软件开发工具包。被软件开发工程师用于为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件的开发工具的集合。因此!Android SDk 指的既是Android专属的软件开发工具包
JNI:
Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C++ 和汇编语言)编写的应用程序和库进行交互操作
当然一般需要进行如下操作流程:
1) 编写java程序:这里以HelloWorld为例。为了实现在 java代码中调用c函数printf。
代码1:
class HelloWorld {
public native void testHelloWorld();
static {
System.loadLibrary("hello");
}
public static void main(String[] args) {
new HelloWorld().testHelloWorld();
}
}
声明native方法:如果你想将一个方法做为一个本地方法的话,那么你就必须声明改方法为native的,并且不能实现。
Load动态库:System.loadLibrary("hello");
这里一般是以static块进行加载的。同时需要注意的是System.loadLibrary()的参数“hello”是动态库的名字。
2) 编译
javac HelloWorld.java
3) 生成扩展名为h的头文件 javah ?
JNIEXPORT void JNICALL Java_HelloWorld_testHelloWorld (JNIEnv *, jobject);
这个h文件相当于我们在java里面的接口,这里声明了一个 Java_HelloWorld_testHelloWorld (JNIEnv *, jobject)方法,然后在我们 的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致)。
4) 编写本地方法实现和由javah命令生成的头文件里面声明的方法名相同的方法
代码2:
#include "jni.h"
#include "HelloWorld.h"
#include other headers
JNIEXPORT void JNICALL Java_HelloWorld_testHelloWorld(JNIEnv *env, jobject obj)
{
printf("Hello world!/n");
return;
}
注意代码2中的第1行,需要将jni.h(该文件可以在%JAVA_HOME%/include文件夹下面找到)文件引入,因为在程序中的JNIEnv、 jobject等类型都是在该头文件中定义的;另外在第2行需要将HelloWorld.h头文件引入。然后保存为 HelloWorldImpl.c就ok了。
5) 生成动态库
这里以在Windows中为例,需要生成dll文件。在保存HelloWorldImpl.c文件夹下面,使用VC的编译器cl成。 cl -I%java_home%/include -I%java_home%/include/win32 -LD HelloWorldImp.c -Fehello.dll 注意:生成的dll文件名在选项-Fe后面配置,这里是hello,因为在HelloWorld.java文件中我们loadLibary的时候使用的名字是hello。
另外需要将-I%java_home%/include -I%java_home%/include/win32参数加上,因为在第四步里面编写本地方法的时候引入了jni.h文件。
③ 如何使用android的ndk建立native的开发环境
从网上看了一篇使用andriod的toolchain在cygwin上来建立android的开发环境,但是在vista上编译始终失败,在xp上能够成功。但是编译的时间比较长,而且对于新手来说也比较麻烦,难道就没有简单的方法吗?google已经把andriod的ndk已经放出来了,所以我就想着打它的主意了,把它配置一下,就能来开发c的程序了。旁边小伙肯定笑了,“搞啥?,有病啊,ndk就是一个开发native code的环境。”大哥,我当然知道了,虽然使用ndk来开发native code相对容易,但是它的.mk文件我看的是云里雾里,我本来想调用自己写的另外一个so库,都不知道在.mk文件里如何写,我现在也懒的去看ndk里面的mk文件,等哪天(哪天?天晓得是哪一天)有空了好好研究一下。好了,闲话少说,开练吧。首先安装cygwin,这个网上的教程多的是,就不说了,接着下载android ndk,这个在andriod的官网上就有了,然后下载一个从android模拟器里取system lib的工具busybox,然后调用命令
$adb push busybox /dev/sample/busybox
$adb shell chmod 777 /dev/sample/busybox
$adb shell ./dev/sample/busybox tar -cf /dev/sample/libs.tar /system/lib
$adb pull /dev/sample/libs.tar libs.tar
这样就将模拟器下的 /system/lib 目录的所有库(so)文件打包并下载下来了,解压libs.tar就得到了我们所需要的所有库文件。
接着将所有的文件 到 $(NDK)/build/prebuilt/windows/arm-eabi-4.2.1/lib/gcc/arm-eabi/4.2.1,好了,这个时候基本的配置工作就结束了,怎么样简单多了吧。
接着编写一个简单的c文件 tutorial01.c
#include <stdio.h>
int getinformation()
{
return 0;
}
然后编写一个Makefile文件
CC = /cygdrive/f/software/android/android-ndk-1.5_r1/build/prebuilt/windows/arm-eabi-4.2.1/bin/arm-eabi-gcc
CFLAGS = -g -O2 -fPIC -DANDROID -I ./ -I ../ -I F:/software/android/android-ndk-1.5_r1/build/platforms/android-1.5/arch-arm/usr/include
SDFLAGS = -nostdlib -Wl,-T,armelf.xsc -Wl,-soname,$@ -Wl,-shared,-Bsymbolic -lc
CRT_OBJS= -lz -lm
all: libtutorial01.so
libtutorial01.so: tutorial01.o
$(CC) $(SDFLAGS) -o $@ tutorial01.o $(CRT_OBJS)
tutorial01.o: tutorial01.c
然后make,这个时候会报错 can't find "armelf.xsc", 在ndk的目录里搜索一下,搜到之后 到$(NDK)/build/prebuilt/windows/arm-eabi-4.2.1/lib/gcc/arm-eabi/4.2.1,然后make,成功。这样一个简单的so文件就生成了,这个时候如果想在android的虚拟机上运行,我们还需要给它包装一下。再编写一个文件test01.c,在这里是使用dl动态加载so文件,静态加载始终有问题,搞不清楚android是如何搜索目录,而且现在只能用绝对路径,这个问题还得仔细研究研究。
#include <string.h>
#include <jni.h>
jint
Java_com_example_testffmpeg_testffmpeg_getinformation( JNIEnv* env,
jobject thiz )
{
void* filehandle = dlopen("/data/data/com.example.test/lib/libtutorial.so", RTLD_LAZY );
int ll = -1;
if(filehandle)
{
int( * getinformation ) ();
getinformation = dlsym(filehandle, "getinformation");
if( getinformation )
{
ll = getinformation();
}
else
{
ll = -3;
}
dlclose(filehandle);
filehandle=0;
}
else
{
ll = -2;
}
return ll;
}
同样再来一个Makefile文件
CC = /cygdrive/f/software/android/android-ndk-1.5_r1/build/prebuilt/windows/arm-eabi-4.2.1/bin/arm-eabi-gcc
CFLAGS = -g -O2 -fPIC -DANDROID -I ./ -I ../ -I F:/software/android/android-ndk-1.5_r1/build/platforms/android-1.5/arch-arm/usr/include
SDFLAGS = -nostdlib -Wl,-T,armelf.xsc -Wl,-shared,-Bsymbolic -Wl,-soname,$@ -lc -L ../tutorial
CRT_OBJS= -lz -lm -ldl
all: libtest01.so
libtest01.so: test01.o
$(CC) $(SDFLAGS) -o $@ test01.o $(CRT_OBJS)
ok, make一下成功。好了,接下来使用andriod的sdk写一个简单的activity, testapp来测试其运行情况,以下是test01.java的代码。
package com.example.test;
import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;
public class test01 extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
/* Create a TextView and set its content.
* the text is retrieved by calling a native
* function.
*/
TextView tv = new TextView(this);
// tv.setText( stringFromJNI() );
Integer ll = getinformation();
String lls = ll.toString();
tv.setText(lls);
setContentView(tv);
}
/* A native method that is implemented by the
* 'hello-jni' native library, which is packaged
* with this application.
*/
public native int getinformation();
/* this is used to load the 'hello-jni' library on application
* startup. The library has already been unpacked into
* /data/data/com.example.HelloJni/lib/libhello-jni.so at
* installation time by the package manager.
*/
static {System.loadLibrary("test");
}
}
在eclipse中运行,在模拟器上显示0,就表示成功了。
转载
④ android ndk开发需要哪些
Android NDK是一个工具集,可以将本地代码嵌入到你的Android 应用中。 Android 应用是在dalvik虚拟机中运行的。NDK可以让你使用本地代码语言来开发应用,比如说C/C++,这种方法对某些类型的应用的是有好处的,可以充分利用本地代码和在某些情况下加速代码的执行。 什么时候用NDK? 对于绝大多数的应用来说,使用NDK并不是一个明智的选择,作为一个开发者,我们需要衡量它所带来的好处和缺点。使用本地代码并不一定可以使性能得到优化,但是通常使得应用代码变得复杂。一般来说,我们将应用中关键部分的代码用C/C++写,而不能由于我们习惯于用C/C++开发而把所有的代码都用C/C++来实现。 有下面这些特点的应用可以考虑使用NDK: 1 独立的,不和其他应用有关系的 2 频繁占用CPU但是申请的内存空间不是很大的操作,像信号的处理,物体的模拟等等 简单的用C/C++重写我们的代码是不会带来很大的性能提升的。 在考虑是否采用本地代码开发的时候,要结合应用的实际需求并且看看Android 的framework层是否提供了我们需要的API,但是用NDK可以充分利用本地已经有的代码。 Android framework提供下面两种方法来使用本地代码: 1 在Android framework的框架下面开发应用,使用JNI的方法来使用NDK本地方法提供的API。这样的好处就是我们可以很好的利用的Android的framework提供的框架,但是需要编写本地具体实现的代码。这样的APK可以在Android 1.5及其之后的版本上面运行。 2 写一个本地的Activity,在本地代码中实现生命回调函数,AndroidSDk提供了 NativeActivity类,这个类可以方便的让你在你的本地代码中实现回调函数(OnCreate,OnPause),从而当这些事件发生的时候处理。用本地类实现的应用可以在Android 2.3及其之后的版本上面运行。
⑤ 安卓NDK可以代替SDK吗可以只用NDK开发吗
让我先来说说android sdk (Android Software Development Kit, 即Android软件开发工具包)可以说只要你使用java去开发Android这个东西就必须用到。他包含了SDK Manager 和 AVD Manage
对于android系统的一些开发版本的管理以及模拟器管理。
而ndk (Native Development Kit)跟sdk差不多的是他也是一个开发工具包。用他开发c/c++是很方便的。他有一个强大的编译集合。
其实名词的解释我也不想多说。这点你只需要网络分别输入sdk 和 ndk 网络里就有你想要的。
区别是什么我只想说是他们基本上是应该没什么相同的。
至于哪个更有前途。
这个不好说。
我来说说android他为什么会有一个ndk把。
很早以前android是只有sdk的。并没有ndk。这就意味着一旦android的开发者要使用c/c++的三方库或者需要用到c/c++就必须使用非官方的法子。用java的jni去调用c/c++。耍小聪明走后门一样。而ndk的出现就意味着jni调用的这种方法转正了变成官方了以后你不需要再走后面大路正面随你走。
可是这样还是没有说到为什么要有ndk啊。是的我只想说的就是如果你要操作底层直接操作内存。操作地址那你不得不去使用c/c++因为java这块想做这些。那恐怕有点困难。所以ndk是必须需要出现的。
而这个sdk和ndk并不是完全不相溶的2门语言。对于android来说是同种语言的2种不同时期的必须品。
最后想说如果你做android开发想要做得更好你就必须要ndk的
⑥ android studio 怎么开发ndk
建立项目,并设置activity.xml布局文件,这一点与普通编程没有不同。通过一个简单的文本展示实验。
在MainActivity中添加native接口,并加载.so库
生成项目的.class文件。首先选中项目后,在菜单栏选择Build-->Make Project。
Make之后,将生成.class文件,生成的.class文件位于app_path/build/intermediates/classes/debug/包名
利用javah生成C头文件:点击"View->Tool Windows->Terminal",即在Studio中进行终端命令行工具。在控制台中通过命令“cd app\src\main\java”,进入到java目录下。操作指令:javah -d ../jni vrlab.ndkdemoforandroidstudio.MainActivity。此时在main目录下生成一个jni文件夹,其中在jni文件夹中有生成的.h头文件。
编辑C文件,在jni文件夹下新建文件命名为main.c。并在该文件中导入需要的头文件,实现上一步生成的头文件中的方法。
配置NDK路径,在local.properties中指明sdk和ndk路径:
设置ndk参数,名字、发布平台等。在应用目录下的build.gradle中defaultConfig中设置
生成.so文件,此时再次选择Build-->Build Project就可以生成so文件了。出现不支持NDK的错误提示,不过跟着错误提示修改:在项目空间下的gradle.properties中添加android.useDeprecatedNdk=true。
针对三种不同的CPU生成了三种不同的.so文件。生成的.so文件位于app_path/build/intermediates/ndk/debug/lib.
安装运行~~去吧,皮卡丘
⑦ android ndk 可以开发什么
第一步:在Eclipse中新建Android项目,我的第一个NDK项目就叫FirstNdk。
第二步:开始之前先介绍cmd环境下的javah命令,
接下来我们进入cmd窗口,进行到项目所在目录。
执行javah -classpath bin/classes -d 项目包名+类名。
维埃里报错,提示找不到类文件,怎么办?
通常有两种解决方案:
1,找到我们电脑中SDK文件目录中的platforms下任意一个版本android.jar包,添加到环境变量中。
2,在上图的cmd命令中把android.jar的目录也写进去。如图:
可以看到运行成功了。
第三步:此时我们刷新项目,可以发现,项目中自动添加了jni文件目录,在此目录中新建first.c文件。接下来就开始代码之旅啦。
第四步:编写first.c文件代码,从未接触过C,视频学习+网络写的:
[cpp] view plain
#include <stdio.h>
#include <stdlib.h>
#include <com_ldm_firstndk_MainActivity.h>
JNIEXPORT jstring JNICALL Java_com_ldm_firstndk_MainActivity_getStringFromC(JNIEnv *env, jobject obj)
{
return (*env)->NewStringUTF(env,"My First JNI PROJECT!");
}
第五步:从NDK工具包中的示例项目比如Hello-jni项目的jni目录下,把Android.mk文件和Application.mk文件复制到我们项目的jni目录下,做适当修改。我的Android.mk文件:
[plain] view plain
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := first
LOCAL_SRC_FILES := first.c #指定c文件
include $(BUILD_SHARED_LIBRARY)
⑧ 安卓的NDK和SDK是什么
可以用NDK开发,但不会替代SDK,因为NDK开发难度非常发,NDK有个巨大的麻烦就是现在有x86芯片的android手机的,用NDK就会需要提供两套APK,比较麻烦。Android平台的第三方应用程序均是依靠基于Java的Dalvik特制虚拟机进行开发的。原生SDK(NDK)的可以让开发者更加直接的接触Android系统资源,并使用传统的C或C++语言编写程序,并在程序封包文件(.apks)中直接嵌入原生库文件。NDK主要用于一些具有大量逻辑计算和高性能的图像渲染的工作,比如我们要开发款大型的3D游戏,那么如果使用AndroidSDK通过Java来开发,速度和性能上很难满足我们的要求,这是就可以使用NDK通过C\C++来开发原生的程序来处理这些渲染,可以极大的提高我们游戏的性能。所以我们很有必要对NDK进行学习。
⑨ 开发android用 ndk做啥
为什么使用NDK
1.代码的保护。由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。
2.可以方便地使用现存的开源库。大部分现存的开源库都是用C/C++代码编写的。
3.提高程序的执行效率。将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率。
4.便于移植。用C/C++写得库可以方便在其他的嵌入式平台上再次使用。
⑩ 我不懂c++,可以直接学习Android ndk开发吗
可以,语言逻辑大都是互通的,只是实现语法和表述方法不一样