RELATEED CONSULTING
相关咨询
选择下列产品马上在线沟通
服务时间:8:30-17:00
你可能遇到了下面的问题
关闭右侧工具栏

新闻中心

这里有您想知道的互联网营销解决方案
ndk使用java代码 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文件。

ndk生成的so怎么在java调用

1. 自己写.c文件,然后生成so库

2. 引用别人的静态库,或者动态库来生成新的jni调用库。

我们先来看最简单的编写一个jni调用的so库,包含一个获取字符串的方法,通过这个列子,我们主要是了解怎么在android的工程中调用jni的库,以及要注意的问题。

第一步:首先我们来看下我们的工程的目录

jni目录是我们生成库的文件,里面包含了一个.mk编译文件以及一系列的.c文件

libs目录是我们编译jni目录下的mk文件动态生成的。

当我们写好了jni下面的库文件以后,在当前目录下执行ndk-build则会自动生成我们需要调用的.so库文件。

第二步: java里面怎么调用jni的库文件,我们先看代码

public class MainActivity extends Activity {

/* A native method that is implemented by the

* 'hello-jni' native library, which is packaged

* with this application.

*/

public native String stringFromJNI();

/* 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("hello-jni");

}

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

String str = stringFromJNI();

System.out.println("*****str:" + str);

}

}

在java文件中要做到调用jni文件生成的so库,需要做到2步

NDK和直接用JAVA编写代码哪个效率更高

PC机

C程序移植

ANDROID

NDK效率更高

些(编程效率)

目前

用纯C

实现安卓编程

linux

程序

移植更

便

windows

程序

更改

NDK相关

资料比较少

调试起

比较麻烦

现问题

搜索起

比较费事

工程

建议用java做

工程(几十

CPP文件)

建议用NDK

android ndk 开发,C++ 调用Java的方法

Android.mk文件:

LOCAL_SRC_FILES参数用空格隔开

[c-sharp] view plaincopyprint?

LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE:=native

LOCAL_SRC_FILES:=geolo.cpp my_jni.h

include $(BUILD_SHARED_LIBRARY)

2. geolo.cpp

先用FindClass方法找到java类,有点类似java的反射用LoadClass

再用CallObjectMethod方法调用Java类的函数。

[c-sharp] view plaincopyprint?

#include "my_jni.h"

jobject getInstance(JNIEnv* env, jclass obj_class){

jmethodID construction_id = env-GetMethodID(obj_class, "init", "()V");

jobject obj = env-NewObject(obj_class, construction_id);

return obj;

}

JNIEXPORT jstring JNICALL Java_com_easepal_geolo_CActivityMain_stringFromJNI(JNIEnv* env, jobject thiz){

jstring str;

jclass java_class = env-FindClass("com/easepal/geolo/CForCall");

if (java_class == 0){

return env-NewStringUTF("not find class!");

}

jobject java_obj = getInstance(env, java_class);

if (java_obj == 0){

return env-NewStringUTF("not find java OBJ!");

}

jmethodID java_method = env-GetMethodID(java_class, "GetJavaString", "()Ljava/lang/String;");

if(java_method == 0){

return env-NewStringUTF("not find java method!");

}

str = (jstring)env-CallObjectMethod(java_obj, java_method);

return str;

}

3. my_jni.h

[c-sharp] view plaincopyprint?

/* DO NOT EDIT THIS FILE - it is machine generated */

#include jni.h

/* Header for class com_easepal_geolo_CActivityMain */

#ifndef _Included_com_easepal_geolo_CActivityMain

#define _Included_com_easepal_geolo_CActivityMain

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class:     com_easepal_geolo_CActivityMain

* Method:    stringFromJNI

* Signature: ()Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_com_easepal_geolo_CActivityMain_stringFromJNI(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

4. CActivityMain.java

[c-sharp] view plaincopyprint?

package com.easepal.geolo;

import android.app.Activity;

import android.os.Bundle;

import android.widget.TextView;

public class CActivityMain extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

TextView tv = new TextView(this);

tv.setText( stringFromJNI("hello") );

setContentView(tv);

}

static {

System.loadLibrary("native");

}

public native String stringFromJNI(String str);

}

5. CForCall.java

[c-sharp] view plaincopyprint?

package com.easepal.geolo;

public class CForCall{

public CForCall(){};

//public ~CForCall(){};

public String GetJavaString(){

String str;

str = "123456";

return str;

}

}


名称栏目:ndk使用java代码 ndk开发教程
本文地址:http://lswzjz.com/article/dosgepo.html