NDK:Android NDK 是在SDK前面又加上了“原生”二字,即Native Development Kit,因此又被Google稱為“NDK”。
成都創(chuàng)新互聯(lián)專注于廣南企業(yè)網(wǎng)站建設,響應式網(wǎng)站,商城網(wǎng)站建設。廣南網(wǎng)站建設公司,為廣南等地區(qū)提供建站服務。全流程定制網(wǎng)站開發(fā),專業(yè)設計,全程項目跟蹤,成都創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務
NDK全稱:Native Development Kit。
NDK是一系列工具的集合。
* NDK提供了一系列的工具,幫助開發(fā)者快速開發(fā)C(或C++)的動態(tài)庫,并能自動將so和java應用一起打包成apk。這些工具對開發(fā)者的幫助是巨大的。
* NDK集成了交叉編譯器,并提供了相應的mk文件隔離CPU、平臺、ABI等差異,開發(fā)人員只需要簡單修改mk文件(指出“哪些文件需要編譯”、“編譯特性要求”等),就可以創(chuàng)建出so。
* NDK可以自動地將so和Java應用一起打包,極大地減輕了開發(fā)人員的打包工作。
其實:
NDK就是能夠方便快捷開發(fā).so文件的工具。JNI的過程比較復雜,生成.so需要大量操作,而NDK就是簡化了這個過程。
Android SDK:
SDK (software development kit)軟件開發(fā)工具包。被軟件開發(fā)工程師用于為特定的軟件包、軟件框架、硬件平臺、操作系統(tǒng)等建立應用軟件的開發(fā)工具的集合。因此!Android SDk 指的既是Android專屬的軟件開發(fā)工具包
JNI:
Java Native Interface (JNI)標準是java平臺的一部分,它允許Java代碼和其他語言寫的代碼進行交互。JNI 是本地編程接口,它使得在 Java 虛擬機 (VM) 內(nèi)部運行的 Java 代碼能夠與用其它編程語言(如 C、C++ 和匯編語言)編寫的應用程序和庫進行交互操作
當然一般需要進行如下操作流程:
1) 編寫java程序:這里以HelloWorld為例。為了實現(xiàn)在 java代碼中調(diào)用c函數(shù)printf。
代碼1:
class HelloWorld {
public native void testHelloWorld();
static {
System.loadLibrary("hello");
}
public static void main(String[] args) {
new HelloWorld().testHelloWorld();
}
}
聲明native方法:如果你想將一個方法做為一個本地方法的話,那么你就必須聲明改方法為native的,并且不能實現(xiàn)。
Load動態(tài)庫:System.loadLibrary("hello");
這里一般是以static塊進行加載的。同時需要注意的是System.loadLibrary()的參數(shù)“hello”是動態(tài)庫的名字。
2) 編譯
javac HelloWorld.java
3) 生成擴展名為h的頭文件 javah ?
JNIEXPORT void JNICALL Java_HelloWorld_testHelloWorld (JNIEnv *, jobject);
這個h文件相當于我們在java里面的接口,這里聲明了一個 Java_HelloWorld_testHelloWorld (JNIEnv *, jobject)方法,然后在我們 的本地方法里面實現(xiàn)這個方法,也就是說我們在編寫C/C++程序的時候所使用的方法名必須和這里的一致)。
4) 編寫本地方法實現(xiàn)和由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) 生成動態(tài)庫
這里以在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參數(shù)加上,因為在第四步里面編寫本地方法的時候引入了jni.h文件。
1. 自己寫.c文件,然后生成so庫
2. 引用別人的靜態(tài)庫,或者動態(tài)庫來生成新的jni調(diào)用庫。
我們先來看最簡單的編寫一個jni調(diào)用的so庫,包含一個獲取字符串的方法,通過這個列子,我們主要是了解怎么在android的工程中調(diào)用jni的庫,以及要注意的問題。
第一步:首先我們來看下我們的工程的目錄
jni目錄是我們生成庫的文件,里面包含了一個.mk編譯文件以及一系列的.c文件
libs目錄是我們編譯jni目錄下的mk文件動態(tài)生成的。
當我們寫好了jni下面的庫文件以后,在當前目錄下執(zhí)行ndk-build則會自動生成我們需要調(diào)用的.so庫文件。
第二步: java里面怎么調(diào)用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文件中要做到調(diào)用jni文件生成的so庫,需要做到2步
PC機
C程序移植
ANDROID
NDK效率更高
些(編程效率)
目前
用純C
實現(xiàn)安卓編程
linux
程序
移植更
便
windows
程序
更改
要
些
NDK相關
資料比較少
調(diào)試起
比較麻煩
現(xiàn)問題
搜索起
比較費事
工程
建議用java做
工程(幾十
CPP文件)
建議用NDK
Android.mk文件:
LOCAL_SRC_FILES參數(shù)用空格隔開
[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方法調(diào)用Java類的函數(shù)。
[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開發(fā)教程
分享路徑:http://jinyejixie.com/article30/dosgepo.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設計、小程序開發(fā)、微信小程序、靜態(tài)網(wǎng)站、網(wǎng)站排名、App開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)