在eclipse上新建jni工程能夠參考:http://www.cnblogs.com/ashitaka/p/5953708.htmlhtml
要在java層打印c的log必須引入這個頭文件的宏定義:java
#ifndef __LOG #define __LOG #ifdef __cplusplus extern "C" { #endif #include <android/log.h> // 宏定義相似java 層的定義,不一樣級別的Log LOGI, LOGD, LOGW, LOGE, LOGF。 對就Java中的 Log.i log.d #define LOG_TAG "HelloJni" // 這個是自定義的LOG的標識 //#undef LOG // 取消默認的LOG #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG, __VA_ARGS__) #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, __VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG, __VA_ARGS__) #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG, __VA_ARGS__) #ifdef __cplusplus } #endif #endif
分析一下:這裏調用了系統的log文件 #include <android/log.h>android
#ifndef _ANDROID_LOG_H #define _ANDROID_LOG_H #include <stdarg.h> #ifdef __cplusplus extern "C" { #endif /* * Android log priority values, in ascending priority order. */ typedef enum android_LogPriority { ANDROID_LOG_UNKNOWN = 0, ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */ ANDROID_LOG_VERBOSE, ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL, ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */ } android_LogPriority; /* * Send a simple string to the log. */ int __android_log_write(int prio, const char *tag, const char *text); /* * Send a formatted string to the log, used like printf(fmt,...) */ int __android_log_print(int prio, const char *tag, const char *fmt, ...) #if defined(__GNUC__) #ifdef __USE_MINGW_ANSI_STDIO #if __USE_MINGW_ANSI_STDIO __attribute__ ((format(gnu_printf, 3, 4))) #else __attribute__ ((format(printf, 3, 4))) #endif #else __attribute__ ((format(printf, 3, 4))) #endif #endif ; /* * A variant of __android_log_print() that takes a va_list to list * additional parameters. */ int __android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap); /* * Log an assertion failure and abort the process to have a chance * to inspect it if a debugger is attached. This uses the FATAL priority. */ void __android_log_assert(const char *cond, const char *tag, const char *fmt, ...) #if defined(__GNUC__) __attribute__ ((noreturn)) #ifdef __USE_MINGW_ANSI_STDIO #if __USE_MINGW_ANSI_STDIO __attribute__ ((format(gnu_printf, 3, 4))) #else __attribute__ ((format(printf, 3, 4))) #endif #else __attribute__ ((format(printf, 3, 4))) #endif #endif ; #ifdef __cplusplus } #endif #endif /* _ANDROID_LOG_H */
這裏面定義了log的優先級,而且log最終調用的都是__android_log_print(...)函數:eclipse
int __android_log_print(int prio, const char *tag, const char *fmt, ...) { va_list ap; char buf[LOG_BUF_SIZE]; va_start(ap, fmt); vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); va_end(ap); return __android_log_write(prio, tag, buf); }
因此本身定義一個頭文件,而且定義宏指令指向__android_log_print(...)。就能夠調用了。ide
另外在 system/core/include/cutils/log.h 也有定義,可是有些沒有,並且在#include <cutils/log.h>提示找不到。估計是版本變動了。可是原理是同樣的。函數
下面是測試函數:測試
JNIEXPORT jint JNICALL Java_com_example_hellojni_MainActivity_test (JNIEnv *env, jclass clazz){ LOGD("log.d Java_Log_test()"); LOGI("Log.i Java_Log_test()"); return 0; }
安卓測試程序:spa
public class MainActivity extends Activity { static{ System.loadLibrary("HelloJava"); } private Button btn_getString; private TextView tv_content; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initUI(); setEvent(); } private void setEvent() { // TODO Auto-generated method stub btn_getString.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub tv_content.setText(getString()); test(); } }); } private void initUI() { // TODO Auto-generated method stub btn_getString = (Button) findViewById(R.id.btn_getString); tv_content = (TextView) findViewById(R.id.tv_content); } public static native String getString(); public static native int test(); }
測試結果:.net
參考博客:http://blog.csdn.net/thl789/article/details/6638494debug