C/C++ >> JNI >> Android (2)
အခုမှ စဖတ်မည့်သူများအတွက် Android VM က ကိုယ့်ရဲ့ application’s source code ထဲမှာ native code နဲ့ implemented လုပ်ထားတဲ့ source code တွေကို JNI ကတဆင့် ခေါ်နိုင်ပါတယ် ဆိုတာ C/C++ >> JNI >> Android (1) မှာသွားရောက်ဖတ်ရှနိုင်ပါတယ်။
ဒီနေ့တော့ C နဲ့ရေးထားတဲ့ code ကို Android NDK သုံး ပြီး Android မှာရေးတဲ့ simple application လေးတစ်ခုရေးကြည့်ရအောင်။ ပထမဆုံးအနေနဲ့ Android developer website ကနေ Android NDK ကိုအရင်ဆုံး download လုပ်လိုက်ပါ။ အခုနောက်ဆုံး ဒီကျူတိုရီရယ်ကို ရေးနေတဲ့ အချိန်မှာ ရှိတဲ့ Version က android-ndk-r4b ပါ။
အောက်မှာပြထားတဲ့ ပုံလေးကတော့ NDK ကိုသုံးပြီး native code တွေဘယ်လိုရေးတယ်ဆိုတဲ့ Overview ပုံလေးပါ။
ဒီတော့ ဒီပုံလေးကိုကြည့်ပြီး ရေးပုံရေးနည်း အဆင့်ဆင့်ကို အကြမ်းဖျဉ်းလေး ဒီလိုမှတ်ထားလိုက်ပါ။
- Native code တွေကို represent လုပ်တဲ့ Native Library Java class ကို create လုပ်ပါ။။
- Native code header file ကို create လုပ်ပါ။
- C code တွေရေးချင်းအားဖြင့် native code ကို implement လုပ်ပါ။
- အားလုံးကို compile လုပ်ပြီး Shared Library (.so) ကို build လုပ်ပါ။
- 5. Android activity ထဲမှာ native code တွေသုံးပါ။
အခု Eclipse ကိုဖွင့်ပြီး Android project တစ်ခုဆောက်လိုက်ကြရအောင်။
၁. Creating Native Library
Native Library ဆိုတာ ကိုယ့်ရဲ့Eclipse project က src directory ထဲမှာရှိတဲ့ java file တစ်ခုပါ။ သူကနောက်ပိုင်းမှာရေးမယ့် native code နဲ့တွဲဆက်ပေးဖို့အတွက် ဆောင်ရွက်ပေးမှာပါ။ အဲ့ဒီ Java class ထဲမှာ native keyword နဲ့ methods တွေ စတာတွေနဲ့ ကြေငြာမှုတွေ လုပ်ရပါမယ် ။
( ဥပမာပြောရမယ်ဆိုရင် native byte[] loadFile(String filePath);) လိုမျိုး native keyword တွေနဲ့ရေးတာကိုဆိုလိုတာပါ ။ အဲ့ဒီ ကြေငြာထားတဲ့ method တွေ မှာ နောက်ပိုင်း implementation ပါတဲ့ native shared library တွေရှိရပါမယ်။ ဒါမှသာ အဲ့ဒီ library တွေကို နောက်ပိုင်း .apk မှာ package လုပ်ပေးပါလိမ့်မယ်။ အဲ့ဒီ library ကိုလည်း standard Unix conversions အဖြစ်နာမည်ပေးရပါမယ်။ ဥပမာ libFileLoader.so ။ ကိုယ့် ရဲ့ application ထဲကနေ အဲ့ဒီ library တွေကို application startup လုပ်နေစဉ်အတွင်းမှာ ခေါ်တင်ချင်တယ်ဆိုရင် တော့ source code မှာ ဒီလိုလေးထည့် ပေးရမှာပါ။
Static
{
System.LoadLibrary(“FileLoader”);
}
ဒါတွေကို အသာထားလို့ အရင်ဆုံး Native Library လေးကို အရင်ဆောက်လိုက်ကြရအောင်။
ဒီတော့ eclipse ထဲမှာ အရင်ဆုံး Native Library ဆောက်ဖို့အတွက် NativeLib.java လေးတစ်ခုကို အခုလိုရေးလိုက်ပါမယ်။ အခုရေးထားတဲ့ header လေးတွေက ရှင်းရှင်လေးတွေပါ။ ကိန်းနှစ်ခုမြှောက်ဖို့ function တစ်ခုအတွက် header ကြေငြာထားတယ်။ နောက်တစ်ခုကတော့ ရိုးရိုး string လေးတစ်ကြောင်း return ပြန်ဖို့ပါဘဲ။
၂. Create C Header File
နောက်တစ်ဆင့်ကတော့ C Header file ကို create လုပ်ရမှာပါ။ ကိုယ့် project ရဲ့ bin directory ထဲမှာ JNI header file ကို create လုပ်ဖို့အတွက် javah ဆိုတဲ့ tool ကိုသုံးပါမယ်။ command prompt ကနေ ကိုယ့် project ရဲ ့ bin အောက်ကိုသွားလိုက်ပါ။ path လမ်းကြောင်းကိုတော့ jdk ကိုညွှန်းရမှာပေါ့။ ပုံမှာပြထားတဲ့အတိုင်း javah ကိုသုံးပြီး header file ထုတ်လိုက်ပါ။ အဲ့ဒီနောက်မှာတော့ ကိုယ့် project directory ထဲမှာ jni directory ကို create လုပ်ပါ။ ပြီးရင် ခုဏက javah နဲ့ ထုတ်ထားတဲ့ JNI header ကို bin အောက်ကနေ အခုဆောက်လိုက်တဲ့ jni directory ထဲကို copy ကူးထည့်လိုက်ပါ။
ဒီတော့ command prompt နဲ့ ထဲကနေပြီး အခုလို javah syntax ကိုသုံးပြီး header file ကို create လုပ်ပါမယ်။
အဲ့ဒီလိုမျိုး ထုတ်ပြီးရင်တော့ ကိုယ့် workspace အောက်က project အောက်က bin folder ထဲကိုသွားကြည့်လိုက်ပါ။ အခု လိုမျိူး ပုံမှာ ၀ုိင်းပြထားတဲ့အတိုင်း Header file လေးတစ်ခုထွက်လာတာကိုတွေ့ရမှာပါ။
အခုထွက်လာတဲ့ header file လေးကို copy ကူးကိုယ့် project folder အောက်မှာ jni ဆိုတဲ့ folder လေးကို create လုပ်ပြီး paste လုပ်လိုက်ပါ။ ဒီတော့ ခြေဆော့လက်ဆော့နဲ့ ဖွင့်ကြည့်လိုက်တော့ အဲ့ဒီ Header file လေးကို ဒီလို signature နဲ့ထုတ်ထားတာကို တွေ့ရပါတယ်
။
၃. Create C Code
အခုချိန်မှာ header file ကိုလည်း jni folder ထဲကို copy ကူးထည့်ပြီးပြီဆိုတော့ သူနဲ့သက်ဆိုင်တဲ့ implementation ဖြစ်တဲ့ ndk_tut.c ဆိုတဲ့ C code လေးကို create လုပ်နိုင်ပါပြီ။ ndk_tut.c ကို ဘယ်လို create လုပ်ရမလဲဆိုရင် ခုဏက header မှာပါလာတဲ့ signature တွေအားလုံးကို copy ကူးထည့် ပြီးတော့ implementation ကို ဒီလိုမျိုးဆက်ရေးပါ။ ဒီ c နဲ့ရေးမယ့် implementation ဖိုင်ကလည်း jni အောက်မှာပါဘဲထားရမှာပါ။
၄. Build the Shared Library
Library ကိုဆောက်ဖို့အတွက် ကိုယ့်ရဲ့ C code ကိုဘယ်လို compile လုပ်ရမလဲဆိုတဲ့ makefile ကို create လုပ်ရမှာပါ။ makefile ဆိုတာ Android.mk ဆိုတဲ့ file ကိုပြောတာပါ။ သူက ဘယ်မှာ ထားရမလဲဆိုရင် ခုဏက ဆောက်ထားတဲ့ jni folder အောက်မှာဘဲဆောက်ပါ။ Android.mk မှာရောဘယ်လို syntax နဲ့ရေးရလဲဆိုတာကို ဒီထက်ပိုပြီးသိချင်တဲ့သူများကတော့ Android NDK package မှာပါလာတဲ့ documentation တွေထဲက Android.mk.txt ဆိုတဲ့ file တွေမှာ ဆက်လက်ပြီးလေ့လာနိုင်ပါတယ်။ ဒီမှာတော့ ဒီ ကျုတိုရီရယ်မှာရေးထားသလောက်ကိုဘဲရှင်း သွားမှာဖြစ်ပါတယ်။
(က) ပထမဆုံး အကြောင်းမှာ ရေးထားတဲ့ LOCAL_PATH := $(call my-dir) ကဘာကိုဆိုလိုသလဲဆိုရင် Android.mk file သည် LOCAL_PATH ဆိုတဲ့ variable နဲ့စရမှာပါ။ development tree ထဲမှာ source file ဘယ်နားမှာရှိလဲဆိုတာကို locate လုပ်ဖို့သုံးတာပါ။ အဲ့ဒီအကြောင်းထဲကဘဲ macro function လေးဖြစ်တဲ့ my-dir ကအခုလက်ရှိ ဘယ်directory လဲဆိုတာကို return ပြန်ပေးပါတယ်။
(ခ) နောက်တစ်ကြောင်းဖြစ်တဲ့ include $ (CLEAR_VARS) ကတော့ ကိုယ့်အတွက် သတ်မှတ်ပေးထားတဲ့ LOCAL_XXX variables တွေဖြစ်တဲ့ (LOCAL_MODULE, LOCAL_SRC_FILES,etc…) စတာတွေကို ရှင်းပေးတဲ့ GNU Makefile လေးကိုညွှန်းချင်တာပါ။
(ဂ) LOCAL_MODULE:=ndk_tut လို့ရေးထားတဲ့ အကြောင်းကတော့ Android.mk မှာဖော်ပြ
ထားတဲ့ module တိုင်းကိုသတ်မှတ်ပေးဖို့ပါ။ အဲ့ဒီ နာမည်က unique (တစ်ခုနဲ့တစ်ခုမတူရဘူး) ဖြစ်ရပါမယ်။ build system က auto prefix နဲ့ suffix တပ်ပေးပါတယ်။ ဥပမာပေးရမယ်ဆိုရင် shared library module name ဖြစ်တဲ့ foo ကို ဘယ်လို generate လုပ်ပေးလဲဆိုရင် libfoo.so လို့ prefix နဲ့ suffix တပ်ပေးပါတယ်။
(ဎ)LOCAL_SRC_FILES:=ndk_tut.c
LOCAL_SRC_FILES ထဲမှာတော့ C and C++ source files တွေကို list လုပ်ပေးထားပြီး module အဖြစ်သို့ assemble လုပ်ပေးပါတယ်။
(င) Include $(BUILD_SHARED_LIBRARY)
နောက်တဆင့်ကတော့ shared library ဘယ်လိုဆောက်မလဲလို့ NDK ကိုပြောရမှာပါ။ ခုချိန်မှာ NDK ကို install လုပ်ပြီးသားလို့ယူဆလိုက်ပြီးဆက်ပြောပါမယ်။ NDK ကို install လုပ်။ ပြီးရင် window 7 စက်ဖြစ်နေတာကြောင့် Linux ရဲ ့ command တွေကို သုံးဖို့ cygwin ကိုပါ install လုပ်ရပါတယ်။ ခုရက်ပိုင်း ဒါကိုသိရဖို့တော်တော်အချိန်ကုန် သွားပါတယ်။ ဒီမှာတော့ cygwin ဘယ်လို install လုပ်လည်း မပြောတော့ပါဘူး။ googling လုပ်ကြည့်နိုင်ကြပါတယ်။ သိချင်ရင်တော့ comment လေးထားခဲ့ပါနော်။ ခုဆက်ပြောမှာကတော့ NDK လည်း install လုပ်ပြီးပြီ cygwin ကိုလည်း install လုပ်ပြီးသား အဆင်သင့် library ထုတ်ရုံဘဲ အခြေနေကိုပြောမှာပါ။
ပထမဆုံး ကိုယ့်ရဲ ့ project ထဲမှာ NDKHOME /apps/ndk_tut ဆိုတဲ့ folder အဆင့်ဆင့်ဆောက်ပြီးရင် သူ့ထဲမှာ Application.mk ကိုဆောက်ရမှာပါ။
BUILD_SHARED_LIBRARY ကတော့ LOCAL_XXX variables မှာ defines လုပ်ထားတဲ့ information တွေကို collect လုပ်ပေးပါတယ်။
နောက်တဆင့်ကတော့ shared library ဘယ်လိုဆောက်မလဲလို့ NDK ကိုပြောရမှာပါ။ ခုချိန်မှာ NDK ကို install လုပ်ပြီးသားလို့ယူဆလိုက်ပြီးဆက်ပြောပါမယ်။ NDK ကို install လုပ်။ ပြီးရင် window 7 စက်ဖြစ်နေတာကြောင့် Linux ရဲ ့ command တွေကို သုံးဖို့ cygwin ကိုပါ install လုပ်ရပါတယ်။ ခုရက်ပိုင်း ဒါကိုသိရဖို့တော်တော်အချိန်ကုန် သွားပါတယ်။ ဒီမှာတော့ cygwin ဘယ်လို install လုပ်လည်း မပြောတော့ပါဘူး။ googling လုပ်ကြည့်နိုင်ကြပါတယ်။ သိချင်ရင်တော့ comment လေးထားခဲ့ပါနော်။ ခုဆက်ပြောမှာကတော့ NDK လည်း install လုပ်ပြီးပြီ cygwin ကိုလည်း install လုပ်ပြီးသား အဆင်သင့် library ထုတ်ရုံဘဲ အခြေနေကိုပြောမှာပါ။
ပထမဆုံး ကိုယ့်ရဲ ့ project ထဲမှာ NDKHOME /apps/ndk_tut ဆိုတဲ့ folder အဆင့်ဆင့်ဆောက်ပြီးရင် သူ့ထဲမှာ Application.mk ကိုဆောက်ရမှာပါ။
အဲ့ဒီနောက်မှာတော့ ကိုယ့်ရဲ ့ NDKHOME ကိုညွှန်းနိုင်ဖို့အတွက် cygwin ရဲ ့ အကူညီနဲ့ symbolic link ထုတ်ပါမယ်။ ဒီတော့ cygwin batch shell ကိုခေါ် ဒီလိုမျိုးလေး symbolic link ထုတ်ပါ။ ပထမတစ်ကြောင်းကတော့ cygwin နဲ့ ကိုယ့် project ရှိတဲ့ နေရာကိုသွားတာပါ။ နောက်တစ်ကြောင်းကတော့ symbolic link ထုတ်တာပါ။
အဲ့ဒီလိုမျိုးထုတ်ပြီးရင်တော့ အခုလိုမျိုး project ဆိုတဲ့ symbolic link လေးညွှန်းထားတဲ့ system file လေး ၀င်လာမှာပါ။ အခုချိန်ကစပြီးတော့ library file ဆိုတဲ့ .so လေးကိုထုတ်နိုင်ပါပြီ။ cygwin ထဲမှာ ndk-build ခေါ်လိုက်ပါ။ အခုလိုမျိုး library file ထုတ်သွားတဲ့ message လေးကို တွေ့နိုင်မှာပါ။
ပြီးရင်တော့ Eclipse project ကို refresh လုပ်ပြီး ကိုယ့်ရဲ့ application project/lib အောက်မှာ libndk_tut.so ဆိုတဲ့ file ရောက်လာတာကိုတွေ့ရမှာပါ။ ၅. Calling Native Code from Java
အခုလက်ရှိ အခြေအနေမှာဆိုရင် native C library ကိုလည်း၊ implemented လုပ်ပြီးပြီ၊ compile လည်းလုပ်ပြီးလို့ သင့်တော်တဲ့နေရာမှာလည်း သက်ဆိုင်ရာ file တွေကိုနေရာချပြီးပြီဆိုတော့ Android application ရဲ ့ Activity ကနေပြန်ခေါ်သုံးဖို့ဘဲကျန်တော့တာပါ။ အဲ့ဒီလိုလုပ်ဖို့ကတော့ လွယ်ပါတယ်။ ကိုယ့်ရဲ့ NativeLib class ကို instantiate လုပ်ပြီး instance တစ်ခုယူလိုက်ရုံပါဘဲ။ ဒီလိုလေးရေးနိုင်ပါတယ်။
UI layout ကတော့ အရင်တိုင်းပါဘဲ မို့မပြောတော့ပါဘူး နော်
run ကြည့်လိုက်တော့ အခုလိုမျိုး ကိန်းနှစ်ခုမြှောက်တာကို C code နဲ့ရေးထာတာကို NDK သုံပြီး Android ရဲ ့ Java ကနေခေါ်နိုင်ပြီပေါ့နော်။
Ref: Using NDK to Call C code from Android Apps by Marko Gargenta
ဒီကျုတိုရီရယ်ကို download လုပ်ချင်တယ်ဆိုရင်တော့ download.zip
၉.၉.၂၀၁၀
Facebook comments:
















[...] ၁၄. C/C++ >> JNI >> Android (2) [...]
thanx for ur sharing……..
Be progress in your job and more share