導航:首頁 > 操作系統 > androidjni流程

androidjni流程

發布時間:2022-12-25 10:06:34

㈠ 如何在android下使用JNI

第一步:

使用java編寫HelloWorld 的Android應用程序:

復制代碼
package com.lucyfyr;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class HelloWorld extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.v("fresne", printJNI("I am HelloWorld Activity"));
}
static
{
//載入庫文件
System.loadLibrary("HelloWorldJni");
}
//聲明原生函數 參數為String類型 返回類型為String
private native String printJNI(String inputStr);
}
復制代碼


這一步我們可以使用eclipse來生成一個App;

因為eclipse會自動為我們編譯此Java文件,後面要是用到。

第二步:

生成共享庫的頭文件:

進入到eclipse生成的Android Project中 :/HelloWorld/bin/classes/com/lucyfyr/ 下:

可以看到裡面後很多後綴為.class的文件,就是eclipse為我們自動編譯好了的java文件,其中就有:

HelloWorld.class文件。

退回到classes一級目錄:/HelloWorld/bin/classes/

執行如下命令

javah com.lucyfyr.HelloWorld

生成文件:com_lucyfyr_HelloWorld.h復制代碼
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_lucyfyr_HelloWorld */
#ifndef _Included_com_lucyfyr_HelloWorld
#define _Included_com_lucyfyr_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_lucyfyr_HelloWorld
* Method: printJNI
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
復制代碼


可以看到自動生成對應的函數:Java_com_lucyfyr_HelloWorld_printJNI

Java_ + 包名(com.lucyfyr) + 類名(HelloWorld) + 介面名(printJNI):必須要按此JNI規范來操作;

java虛擬機就可以在com.simon.HelloWorld類調用printJNI介面的時候自動找到這個C實現的Native函數調用。

當然函數名太長,可以在.c文件中通過函數名映射表來實現簡化。

第三步:

實現JNI原生函數源文件:

新建com_lucyfyr_HelloWorld.c文件:復制代碼
#include <jni.h>
#define LOG_TAG "HelloWorld"
#include <utils/Log.h>
/* Native interface, it will be call in java code */
JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI(JNIEnv *env, jobject obj,jstring inputStr)
{
LOGI("fresne Hello World From libhelloworld.so!");
// 從 instring 字元串取得指向字元串 UTF 編碼的指針
const char *str =
(const char *)(*env)->GetStringUTFChars( env,inputStr, JNI_FALSE );
LOGI("fresne--->%s",(const char *)str);
// 通知虛擬機本地代碼不再需要通過 str 訪問 Java 字元串。
(*env)->ReleaseStringUTFChars(env, inputStr, (const char *)str );
return (*env)->NewStringUTF(env, "Hello World! I am Native interface");
}

/* This function will be call when the library first be load.
* You can do some init in the libray. return which version jni it support.
*/
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
void *venv;
LOGI("fresne----->JNI_OnLoad!");
if ((*vm)->GetEnv(vm, (void**)&venv, JNI_VERSION_1_4) != JNI_OK) {
LOGE("fresne--->ERROR: GetEnv failed");
return -1;
}
return JNI_VERSION_1_4;
}
復制代碼


OnLoadJava_com_lucyfyr_HelloWorld_printJNI

函數裡面做一些log輸出 注意JNI中的log輸出的不同。

JNI_OnLoad函數JNI規范定義的,當共享庫第一次被載入的時候會被回調,

這個函數裡面可以進行一些初始化工作,比如注冊函數映射表,緩存一些變數等,

最後返回當前環境所支持的JNI環境。本例只是簡單的返回當前JNI環境。第四步:

編譯生成so庫

編譯com_lucyfyr_HelloWorld.c成so庫可以和app一起編譯,也可以都單獨編譯。

在當前目錄下建立jni文件夾:HelloWorld/jni/

下建立Android.mk ,並將com_lucyfyr_HelloWorld.c和 com_lucyfyr_HelloWorld.h 拷貝到進去

編寫編譯生成so庫的Android.mk文件:復制代碼
LOCAL_PATH:= $(call my-dir)
# 一個完整模塊編譯
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=com_lucyfyr_HelloWorld.c
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_MODULE := libHelloWorldJni
LOCAL_SHARED_LIBRARIES := libutils
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE_TAGS :=optional
include $(BUILD_SHARED_LIBRARY)
復制代碼


系統變數解析:

LOCAL_PATH - 編譯時的目錄
$(call 目錄,目錄….) 目錄引入操作符
如該目錄下有個文件夾名稱 src,則可以這樣寫 $(call src),那麼就會得到 src 目錄的完整路徑

include $(CLEAR_VARS) -清除之前的一些系統變數
LOCAL_MODULE - 編譯生成的目標對象
LOCAL_SRC_FILES - 編譯的源文件
LOCAL_C_INCLUDES - 需要包含的頭文件目錄
LOCAL_SHARED_LIBRARIES - 鏈接時需要的外部庫
LOCAL_PRELINK_MODULE - 是否需要prelink處理
include$(BUILD_SHARED_LIBRARY) - 指明要編譯成動態庫

㈡ android 怎麼調用jni裡面的方法

調用jni裡面的方法,過程如下:
第一步:
使用Java編寫HelloWorld 的Android應用程序:

package com.lucyfyr;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class HelloWorld extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.v("fresne", printJNI("I am HelloWorld Activity"));
}
static
{
//載入庫文件
System.loadLibrary("HelloWorldJni");
}
//聲明原生函數 參數為String類型 返回類型為String
private native String printJNI(String inputStr);
}

這一步我們可以使用eclipse來生成一個App;
因為eclipse會自動為我們編譯此Java文件,後面要是用到。

第二步:
生成共享庫的頭文件:
進入到eclipse生成的Android Project中 :/HelloWorld/bin/classes/com/lucyfyr/ 下:
可以看到裡面後很多後綴為.class的文件,就是eclipse為我們自動編譯好了的java文件,其中就有:
HelloWorld.class文件。
退回到classes一級目錄:/HelloWorld/bin/classes/
執行如下命令:
javah com.lucyfyr.HelloWorld
生成文件:com_lucyfyr_HelloWorld.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_lucyfyr_HelloWorld */
#ifndef _Included_com_lucyfyr_HelloWorld
#define _Included_com_lucyfyr_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_lucyfyr_HelloWorld
* Method: printJNI
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif

可以看到自動生成對應的函數:Java_com_lucyfyr_HelloWorld_printJNI
Java_ + 包名(com.lucyfyr) + 類名(HelloWorld) + 介面名(printJNI):必須要按此JNI規范來操作;
java虛擬機就可以在com.simon.HelloWorld類調用printJNI介面的時候自動找到這個C實現的Native函數調用。
當然函數名太長,可以在.c文件中通過函數名映射表來實現簡化。

第三步:
實現JNI原生函數源文件:
新建com_lucyfyr_HelloWorld.c文件:

㈢ 如何在Android下使用JNI

第一步:

使用Java編寫HelloWorld 的Android應用程序:

復制代碼
package com.lucyfyr;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class HelloWorld extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.v("fresne", printJNI("I am HelloWorld Activity"));
}
static
{

㈣ Android之對外開放的api關聯jni載入流程梳理

前言

zygote啟動

app_process可執行文件的啟動

關注AndroidRuntime.start執行的業務

關注AndroidRuntime.gRegJNI的初始化

以register_android_os_SystemClock注冊為例

總結

㈤ 如何在Android下使用JNI

第一步: 使用Java編寫HelloWorld 的Android應用程序: 復制代碼 package com.lucyfyr; import android.app.Activity; import android.os.Bundle; import android.util.Log; public class HelloWorld extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.v("fresne", printJNI("I am HelloWorld Activity")); } static { //載入庫文件 System.loadLibrary("HelloWorldJni"); } //聲明原生函數 參數為String類型 返回類型為String private native String printJNI(String inputStr); } 復制代碼 這一步我們可以使用eclipse來生成一個App; 因為eclipse會自動為我們編譯此Java文件,後面要是用到。 第二步: 生成共享庫的頭文件: 進入到eclipse生成的Android Project中 :/HelloWorld/bin/classes/com/lucyfyr/ 下: 可以看到裡面後很多後綴為.class的文件,就是eclipse為我們自動編譯好了的java文件,其中就有: HelloWorld.class文件。 退回到classes一級目錄:/HelloWorld/bin/classes/ 執行如下命令: javah com.lucyfyr.HelloWorld 生成文件:com_lucyfyr_HelloWorld.h 復制代碼 /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_lucyfyr_HelloWorld */ #ifndef _Included_com_lucyfyr_HelloWorld #define _Included_com_lucyfyr_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: com_lucyfyr_HelloWorld * Method: printJNI * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif 復制代碼 可以看到自動生成對應的函數:Java_com_lucyfyr_HelloWorld_printJNI Java_ + 包名(com.lucyfyr) + 類名(HelloWorld) + 介面名(printJNI):必須要按此JNI規范來操作; java虛擬機就可以在com.simon.HelloWorld類調用printJNI介面的時候自動找到這個C實現的Native函數調用。 當然函數名太長,可以在.c文件中通過函數名映射表來實現簡化。 第三步: 實現JNI原生函數源文件: 新建com_lucyfyr_HelloWorld.c文件: 復制代碼 #include <jni.h> #define LOG_TAG "HelloWorld" #include <utils/Log.h> /* Native interface, it will be call in java code */ JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI(JNIEnv *env, jobject obj,jstring inputStr) { LOGI("fresne Hello World From libhelloworld.so!"); // 從 instring 字元串取得指向字元串 UTF 編碼的指針 const char *str = (const char *)(*env)->GetStringUTFChars( env,inputStr, JNI_FALSE ); LOGI("fresne--->%s",(const char *)str); // 通知虛擬機本地代碼不再需要通過 str 訪問 Java 字元串。 (*env)->ReleaseStringUTFChars(env, inputStr, (const char *)str ); return (*env)->NewStringUTF(env, "Hello World! I am Native interface"); } /* This function will be call when the library first be load. * You can do some init in the libray. return which version jni it support. */ jint JNI_OnLoad(JavaVM* vm, void* reserved) { void *venv; LOGI("fresne----->JNI_OnLoad!"); if ((*vm)->GetEnv(vm, (void**)&venv, JNI_VERSION_1_4) != JNI_OK) { LOGE("fresne--->ERROR: GetEnv failed"); return -1; } return JNI_VERSION_1_4; } 復制代碼 OnLoadJava_com_lucyfyr_HelloWorld_printJNI 函數裡面做一些log輸出 注意JNI中的log輸出的不同。 JNI_OnLoad函數JNI規范定義的,當共享庫第一次被載入的時候會被回調, 這個函數裡面可以進行一些初始化工作,比如注冊函數映射表,緩存一些變數等, 最後返回當前環境所支持的JNI環境。本例只是簡單的返回當前JNI環境。 第四步: 編譯生成so庫 編譯com_lucyfyr_HelloWorld.c成so庫可以和app一起編譯,也可以都單獨編譯。 在當前目錄下建立jni文件夾:HelloWorld/jni/ 下建立Android.mk ,並將com_lucyfyr_HelloWorld.c和 com_lucyfyr_HelloWorld.h 拷貝到進去 編寫編譯生成so庫的Android.mk文件: 復制代碼 LOCAL_PATH:= $(call my-dir) # 一個完整模塊編譯 include $(CLEAR_VARS) LOCAL_SRC_FILES:=com_lucyfyr_HelloWorld.c LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) LOCAL_MODULE := libHelloWorldJni LOCAL_SHARED_LIBRARIES := libutils LOCAL_PRELINK_MODULE := false LOCAL_MODULE_TAGS :=optional include $(BUILD_SHARED_LIBRARY) 復制代碼 系統變數解析: LOCAL_PATH - 編譯時的目錄 $(call 目錄,目錄….) 目錄引入操作符 如該目錄下有個文件夾名稱 src,則可以這樣寫 $(call src),那麼就會得到 src 目錄的完整路徑 include $(CLEAR_VARS) -清除之前的一些系統變數 LOCAL_MODULE - 編譯生成的目標對象 LOCAL_SRC_FILES - 編譯的源文件 LOCAL_C_INCLUDES - 需要包含的頭文件目錄 LOCAL_SHARED_LIBRARIES - 鏈接時需要的外部庫 LOCAL_PRELINK_MODULE - 是否需要prelink處理 include$(BUILD_SHARED_LIBRARY) - 指明要編譯成動態庫

㈥ android jni怎麼使用

  1. 安裝NDK,在eclipse里設置關聯

  2. 首先你在類裡面寫native方法,如native String printHello();

  3. 設置靜態方法塊調用so文件,如static {System.loadLibrary("jnitest");}

  4. 右鍵工程-android tools-add native support

  5. 編寫C/C++文件,對應.c/.cpp,如

    JNIEXPORT jstring JNICALL Java_com_example_jnit_MainActivity_printHello
    (JNIEnv *env, jobject obj){
    return env->NewStringUTF("Hello world !");
    }

  6. 編譯運行

㈦ 如何在Android下使用JNI

關於如何在Android使用JNI調用C/C++代碼庫,網上已經有很多優秀的文章了,這里說一個大概過程吧:

首先需要懂C,其次要明白JNI的開發流程,然後還要知道NDK如何使用

1、在java代碼中聲明了一個native本地方法

Public native String helloFromc();

2、在項目目錄中創建JNI文件夾

3、在JNI文件夾裡面創建C文件,按照規范寫代碼

Jstring
Java_com_cheng_jnitest_MainActivity_helloFromc(JNIEnv* env,jobject obj)

4、用ndk-build指令編譯
編譯前需要配置Android.mk文件
//指定編譯的文件夾,指定當前的目錄
LOCAL_PATH := $(call my-dir)

//編譯器在編譯的時候會產生很多臨時變數,中間變數最好在編譯前清空所有的臨時變數

include $(CLEAR_VARS)

//編譯完成後的模塊名
LOCAL_MOUDLE := hello
//編譯的源文件

LOCAL_SRC_FILES:=hello.c

//編譯一個動態庫

//動態庫.so 只包含運行的函數,不包含依賴,所以體積小,運行的時候回去系統尋找依賴

//靜態庫.a 包含所有的函數和運行的依賴,所以體積大,包含所有的api

include $(BUILD_SHARED_LIBRARY)

5、生成了一個so動態庫,放到了libs裡面

6、項目中引入依賴庫

Static{

System.loadLibrary("hello");

}
-

㈧ 如何在Android下使用JNI

1.引言
我們知道,Android系統的底層庫由c/c++編寫,上層Android應用程序通過Java虛擬機調用底層介面,銜接底層c/c++庫與Java應用程序間的介面正是JNI(JavaNative Interface)。本文描述了如何在ubuntu下配置AndroidJNI的開發環境,以及如何編寫一個簡單的c函數庫和JNI介面,並通過編寫Java程序調用這些介面,最終運行在模擬器上的過程。

2.環境配置

2.1.安裝jdk1.6
(1)從jdk官方網站下載jdk-6u29-linux-i586.bin文件。
(2)執行jdk安裝文件
[html] view plainprint?
01.$chmod a+x jdk-6u29-linux-i586.bin
02.$jdk-6u29-linux-i586.bin
$chmod a+x jdk-6u29-linux-i586.bin
$jdk-6u29-linux-i586.bin
(3)配置jdk環境變數

[html] view plainprint?
01.$sudo vim /etc/profile
02.#JAVAEVIRENMENT
03.exportJAVA_HOME=/usr/lib/java/jdk1.6.0_29
04.exportJRE_HOME=$JAVA_HOME/jre
05.exportCLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
06.exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
$sudo vim /etc/profile
#JAVAEVIRENMENT
exportJAVA_HOME=/usr/lib/java/jdk1.6.0_29
exportJRE_HOME=$JAVA_HOME/jre
exportCLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
保存後退出編輯,並重啟系統。

(4)驗證安裝

[html] view plainprint?
01.$java -version
02.javaversion "1.6.0_29"
03.Java(TM)SE Runtime Environment (build 1.6.0_29-b11)
04.JavaHotSpot(TM) Server VM (build 20.4-b02, mixed mode)
05.$javah
06.用法:javah[選項]<類>
07.其中[選項]包括:
08.-help輸出此幫助消息並退出
09.-classpath<路徑>用於裝入類的路徑
10.-bootclasspath<路徑>用於裝入引導類的路徑
11.-d<目錄>輸出目錄
12.-o<文件>輸出文件(只能使用-d或-o中的一個)
13.-jni生成JNI樣式的頭文件(默認)
14.-version輸出版本信息
15.-verbose啟用詳細輸出
16.-force始終寫入輸出文件
17.使用全限定名稱指定<類>(例
18.如,java.lang.Object)。
$java -version
javaversion "1.6.0_29"
Java(TM)SE Runtime Environment (build 1.6.0_29-b11)
JavaHotSpot(TM) Server VM (build 20.4-b02, mixed mode)
$javah
用法:javah[選項]<類>
其中[選項]包括:
-help輸出此幫助消息並退出
-classpath<路徑>用於裝入類的路徑
-bootclasspath<路徑>用於裝入引導類的路徑
-d<目錄>輸出目錄
-o<文件>輸出文件(只能使用-d或-o中的一個)
-jni生成JNI樣式的頭文件(默認)
-version輸出版本信息
-verbose啟用詳細輸出
-force始終寫入輸出文件
使用全限定名稱指定<類>(例
如,java.lang.Object)。2.2.安裝android應用程序開發環境
ubuntu下安裝android應用程序開發環境與windows類似,依次安裝好以下軟體即可:
(1)Eclipse
(2)ADT
(3)AndroidSDK
與windows下安裝唯一不同的一點是,下載這些軟體的時候要下載Linux版本的安裝包。
安裝好以上android應用程序的開發環境後,還可以選擇是否需要配置emulator和adb工具的環境變數,以方便在進行JNI開發的時候使用。配置步驟如下:
把emulator所在目錄android-sdk-linux/tools以及adb所在目錄android-sdk-linux/platform-tools添加到環境變數中,android-sdk-linux指androidsdk安裝包android-sdk_rxx-linux的解壓目錄。
[plain] view plainprint?
01.$sudo vim /etc/profile
02.exportPATH=~/software/android/android-sdk-linux/tools:$PATH
03. exportPATH=~/software/android/android-sdk-linux/platform-tools:$PATH
$sudo vim /etc/profile
exportPATH=~/software/android/android-sdk-linux/tools:$PATH
exportPATH=~/software/android/android-sdk-linux/platform-tools:$PATH
編輯完畢後退出,並重啟生效。

2.3.安裝NDK
NDK是由android提供的編譯android本地代碼的一個工具。
(1)從androidndk官網http://developer.android.com/sdk/ndk/index.html下載ndk,目前最新版本為android-ndk-r6b-linux-x86.tar.bz2.
(2)解壓ndk到工作目錄:
[plain] view plainprint?
01.$tar -xvf android-ndk-r6b-linux-x86.tar.bz2
02.$sudo mv android-ndk-r6b /usr/local/ndk
$tar -xvf android-ndk-r6b-linux-x86.tar.bz2
$sudo mv android-ndk-r6b /usr/local/ndk
(3)設置ndk環境變數

[plain] view plainprint?
01.$sudo vim /etc/profile
02.exportPATH=/usr/local/ndk:$PATH
$sudo vim /etc/profile
exportPATH=/usr/local/ndk:$PATH

編輯完畢後保存退出,並重啟生效

(4)驗證安裝

[plain] view plainprint?
01.$ cd/usr/local/ndk/samples/hello-jni/
02.$ ndk-build
03.Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
04.Gdbsetup : libs/armeabi/gdb.setup
05.Install : libhello-jni.so => libs/armeabi/libhello-jni.so
$ cd/usr/local/ndk/samples/hello-jni/
$ ndk-build
Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
Gdbsetup : libs/armeabi/gdb.setup
Install : libhello-jni.so => libs/armeabi/libhello-jni.so

3.JNI實現
我們需要定義一個符合JNI介面規范的c/c++介面,這個介面不用太復雜,例如輸出一個字元串。接下來,則需要把c/c++介面的代碼文件編譯成共享庫(動態庫).so文件,並放到模擬器的相關目錄下。最後,啟動Java應用程序,就可以看到最終效果了。

3.1.編寫Java應用程序代碼
(1)啟動Eclipse,新建android工程

Project:JNITest

Package:org.tonny.jni

Activity:JNITest

(2)編輯資源文件

編輯res/values/strings.xml文件如下:編輯res/layout/main.xml文件
我們在主界面上添加了一個EditText控制項和一個Button控制項。

(3)編輯JNITest.java文件


static表示在系統第一次載入類的時候,先執行這一段代碼,在這里表示載入動態庫libJNITest.so文件。

再看這一段:

[java] view plainprint?
01.privatenativeString GetReply();
privatenativeString GetReply();
native表示這個方法由本地代碼定義,需要通過jni介面調用本地c/c++代碼。

[java] view plainprint?
01.publicvoidonClick(View arg0) {
02.edtName.setText(reply);
03.}
publicvoidonClick(View arg0) {
edtName.setText(reply);
}

這段代碼表示點擊按鈕後,把native方法的返回的字元串顯示到EditText控制項。

(4)編譯工程,生成.class文件。

3.2.用javah工具生成符合JNI規范的c語言頭文件

在終端中,進入android工程所在的bin目錄

[plain] view plainprint?
01.$cd ~/project/Android/JNITest/bin
$cd ~/project/Android/JNITest/bin
我們用ls命令查看,可以看到bin目錄下有個classes目錄,其目錄結構為classes/org/tonny/jni,即classes的子目錄結構是android工程的包名org.tonny.jni。請注意,下面我們准備執行javah命令的時候,必須進入到org/tonny/jni的上級目錄,即classes目錄,否則javah會提示找不到相關的java類。

下面繼續:

[plain] view plainprint?
01.$cd classes
02.$javah org.tonny.jni.JNITest
03.$ls
04.org org_tonny_jni_JNITest.h
$cd classes
$javah org.tonny.jni.JNITest
$ls
org org_tonny_jni_JNITest.h

執行javahorg.tonny.jni.JNITest命令,在classes目錄下會生成org_tonny_jni_JNITest.h頭文件。如果不進入到classes目錄下的話,也可以這樣:

[plain] view plainprint?
01.$javah -classpath ~/project/Android/JNITest/bin/classesorg.tonny.jni.JNITest
$javah -classpath ~/project/Android/JNITest/bin/classesorg.tonny.jni.JNITest
-classpath 參數表示裝載類的目錄。

3.3.編寫c/c++代碼
生成org_tonny_jni_JNITest.h頭文件後,我們就可以編寫相應的函數代碼了。下面在android工程目錄下新建jni目錄,即~/project/Android/JNITest/jni,把org_tonny_jni_JNITest.h頭文件拷貝到jni目錄下,並在jni目錄下新建org_tonny_jni_JNITest.c文件,編輯代碼如下:

[cpp] view plainprint?
01.#include<jni.h>
02.#include<string.h>
03.#include"org_tonny_jni_JNITest.h"
04.
05.
06.JNIEXPORTjstring JNICALLJava_org_tonny_jni_JNITest_GetReply
07.(JNIEnv *env, jobject obj){
08.return(*env)->NewStringUTF(env,(char*)"Hello,JNITest");
09.}
#include<jni.h>
#include<string.h>
#include"org_tonny_jni_JNITest.h"

JNIEXPORTjstring JNICALLJava_org_tonny_jni_JNITest_GetReply
(JNIEnv *env, jobject obj){
return(*env)->NewStringUTF(env,(char*)"Hello,JNITest");
}

我們可以看到,該函數的實現相當簡單,返回一個字元串為:"Hello,JNITest"

3.4.編寫Android.mk文件
在~/project/Android/JNITest/jni目錄下新建Android.mk文件,android可以根據這個文件的編譯參數編譯模塊。編輯Android.mk文件如下:

[plain] view plainprint?
01.LOCAL_PATH:= $(call my-dir)
02.include$(CLEAR_VARS)
03.LOCAL_MODULE := libJNITest
04.LOCAL_SRC_FILES:= org_tonny_jni_JNITest.c
05.include$(BUILD_SHARED_LIBRARY)
LOCAL_PATH:= $(call my-dir)
include$(CLEAR_VARS)
LOCAL_MODULE := libJNITest
LOCAL_SRC_FILES:= org_tonny_jni_JNITest.c
include$(BUILD_SHARED_LIBRARY)

LOCAL_MODULE表示編譯的動態庫名稱

LOCAL_SRC_FILES 表示源代碼文件

3.5.用ndk工具編譯並生成.so文件
進入到JNITest的工程目錄,執行ndk-build命令即可生成libJNITest.so文件。

[plain] view plainprint?
01.$cd ~/project/Android/JNITest/
02.$ndk-build
03.Invalidattribute name:
04.package
05.Install : libJNITest.so => libs/armeabi/libJNITest.so
$cd ~/project/Android/JNITest/
$ndk-build
Invalidattribute name:
package
Install : libJNITest.so => libs/armeabi/libJNITest.so
可以看到,在工程目錄的libs/armeabi目錄下生成了libJNITest.so文件。

3.6.在模擬器上運行
(1)首先,我們把android模擬器啟動起來。進入到emulator所在目錄,執行emulator命令:

[plain] view plainprint?
01.$cd ~/software/android/android-sdk-linux/tools
02.$./emulator @AVD-2.3.3-V10 -partition-size 512
$cd ~/software/android/android-sdk-linux/tools
$./emulator @AVD-2.3.3-V10 -partition-size 512
AVD-2.3.3-V10表示你的模擬器名稱,與在Eclipse->AVDManager下的AVDName對應,-partition-size表示模擬器的存儲設備容量。

(2)接下來,我們需要把libJNITest.so文件拷貝到模擬器的/system/lib目錄下,執行以下命令:

[plain] view plainprint?
01.$cd ~/project/Android/JNITest/libs/armeabi/
02.$adb remount
03.$adb push libJNITest.so /system/lib
04.80 KB/s (10084 bytes in 0.121s)
$cd ~/project/Android/JNITest/libs/armeabi/
$adb remount
$adb push libJNITest.so /system/lib
80 KB/s (10084 bytes in 0.121s)

當在終端上看到有80 KB/s (10084 bytes in 0.121s)傳輸速度等信息的時候,說明拷貝成功。

(3)在終端上執行JNITest程序,這個我們可以在Eclipse下,右鍵點擊JNITest工程,RunAs->Android Application,即可在模擬器上啟動程序

㈨  android中,請簡述jni的調用過程

1)安裝和下載Cygwin,下載 Android NDK
2)在ndk項目中JNI介面的設計
3)使用C/C++實現本地方法
4)JNI生成動態鏈接庫.so文件
5)將動態鏈接庫復制到java工程,在java工程中調用,運行java工程即可

閱讀全文

與androidjni流程相關的資料

熱點內容
javatomcat圖片 瀏覽:415
程序員生產智能創意 瀏覽:65
匯和銀行app怎麼登錄 瀏覽:381
騰訊伺服器如何上傳源碼 瀏覽:739
單片機的原理概述 瀏覽:508
火控pdf 瀏覽:267
如何復制雲伺服器centos環境 瀏覽:984
債權pdf 瀏覽:301
紅色番字的app怎麼下載 瀏覽:876
雲伺服器流程教課 瀏覽:702
中國農業銀行app怎麼沒有網 瀏覽:997
幾率表演算法 瀏覽:902
程序員理工科 瀏覽:708
企業郵箱登錄收件伺服器地址 瀏覽:558
計算機思維與演算法設計的重要性 瀏覽:664
linux刷新磁碟命令 瀏覽:76
我的世界如何查看伺服器種子pc 瀏覽:284
linuxlamp編譯安裝 瀏覽:609
枚舉演算法ppt 瀏覽:184
cmd查看進程命令 瀏覽:956