現在Android發展的如火如荼,但是它的一些程式還是需要調用到C的代碼,這期間的銜接(JAVA與C之間)就叫做JNI。 不熟悉JNI的可以先百度一下,另外,還需要NDK的一個開發環境,我用的是NDK5。 話不多說,開始: 建立一個Android工程,之後,在裡面建立一個類,裡面只需要包含一個native方法即可,例: package com.****.testjnilog; public class TJLog {
public native void ShowJNILog();
}
Eclipse會自動對.java檔案進行編譯, 下面需要產生相對應的.h檔案,(用javah命令) 由於用javah命令產生h檔案需要知道相應的類檔案,所以這裡會有一些需要注意的。 在cygwin下:進入到工程目錄,這時候的類檔案,都是放在bin/com/****/testjnilog下的, 我們所做的就是:進入到bin目錄,然後用如下命令: javah -jni com.****.testjnilog.TJLog 這個執行完成以後,在bin目錄裡面就產生好相應的.h檔案了。 /* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_****_testjnilog_TJLog */ #ifndef _Included_com_****_testjnilog_TJLog
#define _Included_com_****_testjnilog_TJLog
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_****_testjnilog_TJLog
* Method: ShowJNILog
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_****_testjnilog_TJLog_ShowJNILog
(JNIEnv *, jobject); #ifdef __cplusplus
}
#endif
#endif
建立一個.c檔案,包含相應的.h檔案,並將其中的函數進行實現。 #include "com_****_testjnilog_TJLog.h" #include <android/log.h> // 這個是輸出LOG所用到的函數所在的路徑 #define LOG_TAG "JNILOG" // 這個是自訂的LOG的標識 #undef LOG // 取消預設的LOG #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) // 定義LOG類型 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) // 定義LOG類型 #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) // 定義LOG類型 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) // 定義LOG類型 #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__) // 定義LOG類型 JNIEXPORT void JNICALL Java_com_****_testjnilog_TJLog_ShowJNILog
(JNIEnv *env, jobject obj) // 注意一定要寫上兩個變數,否則NDK編譯的時候是編譯不過去的。
{
LOGD("Hello JNILog");
}
好了,代碼都寫完了,剩下的就是編譯so庫了。 按照NDK中的例子,在工程目錄下建立一個jni的檔案夾,將兩個檔案拷貝到目錄裡面,並將一個Android.mk拷貝進來, 修改方法如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) LOCAL_MODULE := testjnilog
LOCAL_SRC_FILES := com_aemm_testjnilog_TJLog.c LOCAL_LDLIBS := -llog # 如果不包含這一句的話,會提示:__android_log_print 未定義 include $(BUILD_SHARED_LIBRARY)
接上面:從bin目錄,返回到工程目錄。按照NDK開發環境配置的路徑進行編譯,我的是ANDK $ANDK/ndk-build 如果成功以後,就會提示產生了.so檔案。(如果不成功,可以給我留言。) 在Android工程中引用.so檔案。 public class testjnilog extends Activity { static { System.loadLibrary("testjnilog") ; // 注意,只是庫名稱,沒有前面的 lib 與後面的 .so }
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TJLog jlog = new TJLog();
jlog.ShowJNILog();
}
} 運行工程,就會在LOGCAT裡面看到自己輸出的LOG了。 |