標籤:沒有 而且 jnienv har ati 好的 method java api main
android的ndk學習(1) 之前學了一段時間ndk,總認為要總結一下。ndk使得很方便地實現java和C與C++代碼的相互溝通。合理地掌握使用ndk能夠提高應用程式的運行效率。所以對於學習anndroid開發的人來說,ndk是必須掌握的工具。剛剛開始學習的時候是有點興奮。有點害怕的,興奮是由於之前學過C++語言。能將學過的東西結合在一起,感覺能夠做出更好的東西,害怕的是之前聽身邊的大神說ndk在android開發中是很難的內容之中的一個。可是無論怎麼說我還是找了本書,看了視頻,找了一些電子資料,而且開始了學習ndk之路!
一,第一個程式Hello world 相對來說,使用ndk實現大量的原生方法並讓他們與Java類同步非常easy成為一個繁瑣的任務。
首先須要建立一個android項目。然後在主函數那裡聲明一個native方法,代碼例如以下
public class MainActivity extends Activity {public static native String test(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }
然後使用命令列,開始-cmd,切換到項目的src檔案夾下再運行命令例如以下:
javah -d ../jni 包名.MainActivity
這時候重新整理項目就會發現多了一個jni目錄,裡面有個.h的檔案,開啟就是一個c標頭檔
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_example_exercise_MainActivity */#ifndef _Included_com_example_exercise_MainActivity#define _Included_com_example_exercise_MainActivity#ifdef __cplusplusextern "C" {#endif#undef com_example_exercise_MainActivity_MODE_PRIVATE#define com_example_exercise_MainActivity_MODE_PRIVATE 0L#undef com_example_exercise_MainActivity_MODE_WORLD_READABLE#define com_example_exercise_MainActivity_MODE_WORLD_READABLE 1L#undef com_example_exercise_MainActivity_MODE_WORLD_WRITEABLE#define com_example_exercise_MainActivity_MODE_WORLD_WRITEABLE 2L#undef com_example_exercise_MainActivity_MODE_APPEND#define com_example_exercise_MainActivity_MODE_APPEND 32768L#undef com_example_exercise_MainActivity_MODE_MULTI_PROCESS#define com_example_exercise_MainActivity_MODE_MULTI_PROCESS 4L#undef com_example_exercise_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING#define com_example_exercise_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L#undef com_example_exercise_MainActivity_BIND_AUTO_CREATE#define com_example_exercise_MainActivity_BIND_AUTO_CREATE 1L#undef com_example_exercise_MainActivity_BIND_DEBUG_UNBIND#define com_example_exercise_MainActivity_BIND_DEBUG_UNBIND 2L#undef com_example_exercise_MainActivity_BIND_NOT_FOREGROUND#define com_example_exercise_MainActivity_BIND_NOT_FOREGROUND 4L#undef com_example_exercise_MainActivity_BIND_ABOVE_CLIENT#define com_example_exercise_MainActivity_BIND_ABOVE_CLIENT 8L#undef com_example_exercise_MainActivity_BIND_ALLOW_OOM_MANAGEMENT#define com_example_exercise_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L#undef com_example_exercise_MainActivity_BIND_WAIVE_PRIORITY#define com_example_exercise_MainActivity_BIND_WAIVE_PRIORITY 32L#undef com_example_exercise_MainActivity_BIND_IMPORTANT#define com_example_exercise_MainActivity_BIND_IMPORTANT 64L#undef com_example_exercise_MainActivity_BIND_ADJUST_WITH_ACTIVITY#define com_example_exercise_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L#undef com_example_exercise_MainActivity_CONTEXT_INCLUDE_CODE#define com_example_exercise_MainActivity_CONTEXT_INCLUDE_CODE 1L#undef com_example_exercise_MainActivity_CONTEXT_IGNORE_SECURITY#define com_example_exercise_MainActivity_CONTEXT_IGNORE_SECURITY 2L#undef com_example_exercise_MainActivity_CONTEXT_RESTRICTED#define com_example_exercise_MainActivity_CONTEXT_RESTRICTED 4L#undef com_example_exercise_MainActivity_RESULT_CANCELED#define com_example_exercise_MainActivity_RESULT_CANCELED 0L#undef com_example_exercise_MainActivity_RESULT_OK#define com_example_exercise_MainActivity_RESULT_OK -1L#undef com_example_exercise_MainActivity_RESULT_FIRST_USER#define com_example_exercise_MainActivity_RESULT_FIRST_USER 1L#undef com_example_exercise_MainActivity_DEFAULT_KEYS_DISABLE#define com_example_exercise_MainActivity_DEFAULT_KEYS_DISABLE 0L#undef com_example_exercise_MainActivity_DEFAULT_KEYS_DIALER#define com_example_exercise_MainActivity_DEFAULT_KEYS_DIALER 1L#undef com_example_exercise_MainActivity_DEFAULT_KEYS_SHORTCUT#define com_example_exercise_MainActivity_DEFAULT_KEYS_SHORTCUT 2L#undef com_example_exercise_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL#define com_example_exercise_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L#undef com_example_exercise_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL#define com_example_exercise_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L/* * Class: com_example_exercise_MainActivity * Method: test * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_example_exercise_MainActivity_test (JNIEnv *, jclass);/* * Class: com_example_exercise_MainActivity * Method: updateFile * Signature: (Ljava/lang/String;)V */<pre name="code" class="java">JNICALL Java_com_example_exercise_MainActivity_updateFile (JNIEnv *, jclass, jstring)#ifdef __cplusplus}#endif#endif
代碼非常長。可是我們臨時僅僅要看
JNICALL Java_com_example_exercise_MainActivity_updateFile (JNIEnv *, jclass, jstring)
這就是依據我們一開始在mainactivity定義的那個native方法產生的一個方法。
有了標頭檔,我們就能夠開始寫.c檔案了。即實現檔案,建立一個檔案main.c。然後輸入代碼例如以下
#include<stdio.h>#include<stdlib.h>JNIEXPORT jstring JNICALL Java_com_example_exercise_MainActivity_test(JNIEnv * env, jobject obj){return (*env)->NewStringUTF(env, "Hello world !");}
返回一個字串,這就是java與c互動的代碼。
可是如今還不能直接執行,還要建立一個android.mk檔案對項目進行配置,代碼例如以下:
LOCAL_PATH :=$(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := mainLOCAL_SRC_FILES := main.cinclude $(BUILD_SHARED_LIBRARY)
好了,然後就是在mainactivity中用法了。代碼例如以下
public class MainActivity extends Activity {public static native String test(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView t = (TextView)findViewById(R.id.jnitextview); t.setText(test()); } static {System.loadLibrary("main");} }
匯入庫是使用的
static {System.loadLibrary("main");}main是我們在android.mk中配置的一個名字,如今萬事俱備,僅僅差編譯產生so檔案了。我們開啟cmd而且切換到項目的檔案夾下,執行ndk-build。中間是減號,不是底線,重新整理項目就能夠看到libs中多了個檔案夾和裡面的一個libmain.so檔案,這時候就能夠執行項目了!
假設沒有意外就會出現helloworld在手機頻幕上。
二。列印log列印log是必須掌握的僅僅是。所以這裡介紹一下怎麼配置,首先是配置android.mk檔案。加入一行代碼LOCAL_LDLIBS += -llog
完整的android.mk代碼例如以下
LOCAL_PATH :=$(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := mainLOCAL_SRC_FILES := main.cLOCAL_LDLIBS += -lloginclude $(BUILD_SHARED_LIBRARY)
然後在實現檔案裡加入標頭檔#include<android/log.h>而且宏定義要列印log的類型#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__))
在代碼中使用LOGI()或者LOGW。執行程式,然後就能夠列印log了!更加具體的能夠去看java api文檔中的ndk篇。
三,總結剛開始學jni,要配置這個要配置那個的很麻煩,可是寫了一個helloworld以後感覺配置也就那樣,萬事開頭難啊!相信後面的學習會越來越難。可是也會越來越有意思,希望繼續加油!
android的ndk學習(1)