基于Android本地代碼生成器詳解
更新時(shí)間:2013年05月23日 09:14:07 作者:
本篇文章是對(duì)Android本地代碼生成器的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
在使用AndroidNDK開發(fā)的時(shí)候有個(gè)事情是很煩人的,那就是創(chuàng)建本地代碼文件夾,生成本地代碼文件和創(chuàng)建本地代碼的編譯文件。特別是實(shí)現(xiàn)本地方法的時(shí)候,也是比較煩人的,因?yàn)楸镜胤椒ǖ拿謱?shí)在是太長(zhǎng)了。它的命名規(guī)范是:Java_package-name_class-name_method-name(arguments),稍一不留神就會(huì)有拼寫錯(cuò)誤,而導(dǎo)致長(zhǎng)時(shí)間的調(diào)試。由于不勘忍受這樣的折磨,也為了不重復(fù)同樣的事情(DRY-Don't Repeat Yourself),于是就寫了一個(gè)Java程序來做這件事。
這個(gè)小工具可以逐個(gè)檢查Java文件,并創(chuàng)建含有本地方法文件,也即本地代碼文件,生成Android.mk編譯文件并更新Java文件,添加System.loadLibrary。
具體的原則是這樣:
•每個(gè)含有本地代碼的Java文件,生成一個(gè)本地文件,其內(nèi)含有該文件中的所有本地方法
•所生成的本地方法是符合標(biāo)準(zhǔn)的JNI,具體的形式是:
return-type Java_package-name_class-name_method-name(arguments){
}
也就是說,所需要做的只是實(shí)現(xiàn)這個(gè)方法。
•默認(rèn)本地代碼共享庫的名字是Android項(xiàng)目的名字
有了這個(gè)小工具,就可以只在Java中聲明本地方法,運(yùn)行下這個(gè)工具,然后實(shí)現(xiàn)本地方法,再編譯就可以了。
可以從<這里下載>這個(gè)小工具。解壓后有三個(gè)文件一個(gè)是Java源碼,一個(gè)是Jar包(genjni.jar),一個(gè)是Shell腳本(genjni.sh)。放上源碼的原因是,如果有興趣的朋友可以進(jìn)行改進(jìn),但是改進(jìn)后請(qǐng)
發(fā)我一份。下載后,最好修改下Shell腳本,把Jar文件的路徑改成具體的存放路徑,否則會(huì)報(bào)出找不到Jar文件的錯(cuò)誤。最后把genjni.sh放到~/bin下面,為了使用時(shí)方便。使用的時(shí)候要在Android項(xiàng)目的根目錄下面運(yùn)行g(shù)enjni.sh就可以了。
下面以一個(gè)實(shí)例方式演示下這個(gè)小工具的使用方法:
創(chuàng)建一個(gè)項(xiàng)目叫HelloJni,并創(chuàng)建一個(gè)HelloJniActivity,在其內(nèi)聲明一個(gè)本地方法getStringFromJni();并用有一個(gè)TextView用來顯示getStringFromJni()返回的信息。另一個(gè)本地方法getStatusFromJni(int)是為了顯示用的,沒有使用。這是Java代碼:
package com.hilton.hellojni;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloJniActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView text = (TextView) findViewById(R.id.text);
text.setText(getStringFromJni());
}
private native String getStringFromJni();
private native int getStatusFromJni(int type);
}
寫好Java代碼后,從終端進(jìn)入到項(xiàng)目的根目錄下
$cd HelloJni
$ls
AndroidManifest.xml assets bin default.properties gen proguard.cfg res src
$genjni.sh
appplication HelloJni
package name: com.hilton.hellojni
class name: HelloJniActivity
$ls
AndroidManifest.xml assets bin default.properties gen jni proguard.cfg res src
$ls jni
Android.mk HelloJniActivity.c
打開查看Android.mk和HelloJniActivity.c
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := HelloJni
LOCAL_SRC_FILES := HelloJniActivity.c
include $(BUILD_SHARED_LIBRARY)
#include <jni.h>
jstring Java_com_hilton_hellojni_HelloJniActivity_getStringFromJni(JNIEnv* env, jobject thiz) {
}
jint Java_com_hilton_hellojni_HelloJniActivity_getStatusFromJni(JNIEnv* env, jobject thiz, jint type) {
}
再查看HelloJniActivity.java也被更新了,里面多了加載共享庫的語句:
package com.hilton.hellojni;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloJniActivity extends Activity {
static {
System.loadLibrary("HelloJni");
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView text = (TextView) findViewById(R.id.text);
text.setText(getStringFromJni());
}
private native String getStringFromJni();
private native int getStatusFromJni(int type);
}
剩下的工作就是實(shí)現(xiàn)本地方法了。
當(dāng)然這個(gè)工具還是有很多問題,歡迎各位反饋,或給出改進(jìn)意見。
另外,這個(gè)工具是用Java寫的,更好的選擇應(yīng)該是用腳本來寫,如Perl或Python。還有就是,如果能把這個(gè)工具集成到ADT中,或是創(chuàng)造一個(gè)完全用于NDK開發(fā)的集成工具ANDT,能夠像產(chǎn)生R.java那樣的自動(dòng)生成本地文件。比如做一個(gè)ANDT工具,集成到Eclipse中,能夠自動(dòng)當(dāng)Java中有本地方法聲明后就自動(dòng)生成本地文件和編譯文件。這將是多么美好的事情啊,將對(duì)NDK的開發(fā)有重大的幫助。我想,Google應(yīng)該會(huì)做一專門用于NDK開發(fā)的Eclipse插件,或是在ADT中加入對(duì)NDK的支持,因?yàn)镹DK開放的接口越來越多,使用NDK開發(fā)者也將越來越多,基于NDK開發(fā)的應(yīng)用也將越來越多(2.3及以后的版本,完全可以只用NDK開發(fā)出一個(gè)Apk,也就是說用純C/C++來開發(fā)應(yīng)用)。希望這一天早些到來。
這個(gè)小工具可以逐個(gè)檢查Java文件,并創(chuàng)建含有本地方法文件,也即本地代碼文件,生成Android.mk編譯文件并更新Java文件,添加System.loadLibrary。
具體的原則是這樣:
•每個(gè)含有本地代碼的Java文件,生成一個(gè)本地文件,其內(nèi)含有該文件中的所有本地方法
•所生成的本地方法是符合標(biāo)準(zhǔn)的JNI,具體的形式是:
復(fù)制代碼 代碼如下:
return-type Java_package-name_class-name_method-name(arguments){
}
也就是說,所需要做的只是實(shí)現(xiàn)這個(gè)方法。
•默認(rèn)本地代碼共享庫的名字是Android項(xiàng)目的名字
有了這個(gè)小工具,就可以只在Java中聲明本地方法,運(yùn)行下這個(gè)工具,然后實(shí)現(xiàn)本地方法,再編譯就可以了。
可以從<這里下載>這個(gè)小工具。解壓后有三個(gè)文件一個(gè)是Java源碼,一個(gè)是Jar包(genjni.jar),一個(gè)是Shell腳本(genjni.sh)。放上源碼的原因是,如果有興趣的朋友可以進(jìn)行改進(jìn),但是改進(jìn)后請(qǐng)
發(fā)我一份。下載后,最好修改下Shell腳本,把Jar文件的路徑改成具體的存放路徑,否則會(huì)報(bào)出找不到Jar文件的錯(cuò)誤。最后把genjni.sh放到~/bin下面,為了使用時(shí)方便。使用的時(shí)候要在Android項(xiàng)目的根目錄下面運(yùn)行g(shù)enjni.sh就可以了。
下面以一個(gè)實(shí)例方式演示下這個(gè)小工具的使用方法:
創(chuàng)建一個(gè)項(xiàng)目叫HelloJni,并創(chuàng)建一個(gè)HelloJniActivity,在其內(nèi)聲明一個(gè)本地方法getStringFromJni();并用有一個(gè)TextView用來顯示getStringFromJni()返回的信息。另一個(gè)本地方法getStatusFromJni(int)是為了顯示用的,沒有使用。這是Java代碼:
復(fù)制代碼 代碼如下:
package com.hilton.hellojni;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloJniActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView text = (TextView) findViewById(R.id.text);
text.setText(getStringFromJni());
}
private native String getStringFromJni();
private native int getStatusFromJni(int type);
}
寫好Java代碼后,從終端進(jìn)入到項(xiàng)目的根目錄下
復(fù)制代碼 代碼如下:
$cd HelloJni
$ls
AndroidManifest.xml assets bin default.properties gen proguard.cfg res src
$genjni.sh
appplication HelloJni
package name: com.hilton.hellojni
class name: HelloJniActivity
$ls
AndroidManifest.xml assets bin default.properties gen jni proguard.cfg res src
$ls jni
Android.mk HelloJniActivity.c
打開查看Android.mk和HelloJniActivity.c
復(fù)制代碼 代碼如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := HelloJni
LOCAL_SRC_FILES := HelloJniActivity.c
include $(BUILD_SHARED_LIBRARY)
復(fù)制代碼 代碼如下:
#include <jni.h>
jstring Java_com_hilton_hellojni_HelloJniActivity_getStringFromJni(JNIEnv* env, jobject thiz) {
}
jint Java_com_hilton_hellojni_HelloJniActivity_getStatusFromJni(JNIEnv* env, jobject thiz, jint type) {
}
再查看HelloJniActivity.java也被更新了,里面多了加載共享庫的語句:
復(fù)制代碼 代碼如下:
package com.hilton.hellojni;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloJniActivity extends Activity {
static {
System.loadLibrary("HelloJni");
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView text = (TextView) findViewById(R.id.text);
text.setText(getStringFromJni());
}
private native String getStringFromJni();
private native int getStatusFromJni(int type);
}
剩下的工作就是實(shí)現(xiàn)本地方法了。
當(dāng)然這個(gè)工具還是有很多問題,歡迎各位反饋,或給出改進(jìn)意見。
另外,這個(gè)工具是用Java寫的,更好的選擇應(yīng)該是用腳本來寫,如Perl或Python。還有就是,如果能把這個(gè)工具集成到ADT中,或是創(chuàng)造一個(gè)完全用于NDK開發(fā)的集成工具ANDT,能夠像產(chǎn)生R.java那樣的自動(dòng)生成本地文件。比如做一個(gè)ANDT工具,集成到Eclipse中,能夠自動(dòng)當(dāng)Java中有本地方法聲明后就自動(dòng)生成本地文件和編譯文件。這將是多么美好的事情啊,將對(duì)NDK的開發(fā)有重大的幫助。我想,Google應(yīng)該會(huì)做一專門用于NDK開發(fā)的Eclipse插件,或是在ADT中加入對(duì)NDK的支持,因?yàn)镹DK開放的接口越來越多,使用NDK開發(fā)者也將越來越多,基于NDK開發(fā)的應(yīng)用也將越來越多(2.3及以后的版本,完全可以只用NDK開發(fā)出一個(gè)Apk,也就是說用純C/C++來開發(fā)應(yīng)用)。希望這一天早些到來。
您可能感興趣的文章:
相關(guān)文章
Android如何在App中啟動(dòng)系統(tǒng)鬧鐘
這篇文章主要為大家詳細(xì)介紹了Android如何在App中啟動(dòng)系統(tǒng)鬧鐘,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
Android輸入法彈出時(shí)覆蓋輸入框問題的解決方法
這篇文章主要介紹了Android輸入法彈出時(shí)覆蓋輸入框問題的解決方法的相關(guān)資料,需要的朋友可以參考下2016-04-04
android仿華為手機(jī)懸浮窗設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了android仿華為手機(jī)懸浮窗設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
Kotlin 協(xié)程 supervisorScope {} 運(yùn)行崩潰解決方法
看過很多?supervisorScope {}?文檔的使用,我照抄一摸一樣的代碼,運(yùn)行就崩潰,最后找到了解決方法,應(yīng)該是kotlin版本更新做過改動(dòng),當(dāng)前我使用的是?androidx.core:core-ktx:1.9.0,本文給大家介紹Kotlin 協(xié)程 supervisorScope {} 運(yùn)行崩潰解決方法,感興趣的朋友一起看看吧2024-01-01
Android?14新功能HighLights快速實(shí)現(xiàn)文本高亮
這篇文章主要為大家介紹了Android?14新功能HighLights快速實(shí)現(xiàn)文本高亮示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
Android中FloatingActionButton實(shí)現(xiàn)懸浮按鈕實(shí)例
這篇文章主要介紹了Android中FloatingActionButton實(shí)現(xiàn)懸浮按鈕實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04
Pagerslidingtabstrip菜單標(biāo)題欄制作方法
這篇文章主要為大家詳細(xì)介紹了Pagerslidingtabstrip菜單標(biāo)題欄的制作方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
Android7.0版本影響開發(fā)的改進(jìn)分析
這篇文章主要介紹了Android7.0版本影響開發(fā)的改進(jìn),總結(jié)分析了Android7.0版本中比較常見的開發(fā)注意事項(xiàng)與操作技巧,需要的朋友可以參考下2017-11-11

