標籤:android des style blog class code java tar ext color width
在某些情況下,比如原來與很多c/c++的代碼, 可能希望採用c/c++編寫android應用程式.在這種情況下,一般使用NDK.但是由於android直提供了java介面,因此不能夠直接調用android中的各種對象或者組件. 如何直接使用c/c++開發android應用? 可以使用cle和wrapandroid項目作為中介軟體. CLE項目提供了多種語言的通用介面,其中就包含對c/c++的支援.
本文簡單介紹了如何使用CLE和wrapandroid編寫GUI應用程式。CLE可以作為多種語言的通用平台,支援java, python,c/c++,lua, 等,且可以擴充至其它多種語言,也可以自訂語言。在CLE中,對象作為1個基本的操作元素。對象對外提供了統一的介面,可以通過這些介面,調用對象的函數,重載對象的函數,捕獲對象的事件.
Wrapandroid將android類封裝成為CLE對象,從而可以使程式員在c/c++中使用android的類。一般有以下幾個步驟:1. 使用CLE介面函數MallocObjectL建立android類的執行個體對象2. 使用ScriptCall介面函數調用對象的方法3. 使用CreateOvlFunction重載對象的函數4. 使用RegEventFunction註冊對象的事件處理函數
步驟1: 準備環境a: CLE可以在應用啟動的時候自動安裝,只需要在工程中包含starcore_android_r6.jar,該檔案在starcore_devfiles_r6.zip壓縮包中, 可以從連結:http://code.google.com/p/cle-for-android 下載。
b: Wrapandroid是一個jar庫,可以從http:/code.google.com/p/wrapandroid-for-multilaguage/download/wrapandroid_devfiles_0_8_5.rar下載。
步驟2 : 開始編程
開發工具使用eclipse和NDK. 這兩個如何安裝和使用,請參閱相關的文檔.
a. 開啟eclipse, 建立一個新工程,名字為“introduction”
b. cle可以在應用啟動的時候從網路下載,此時需要在工程中增加以下許可:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
c. 將java庫檔案starcore_android_r6.jar和wrapandroid.jar拷貝到工程目錄,並加入到工程中:
d. 編輯IntroductionActivity.java,如下修改,裝載共用庫
import com.srplab.wrapandroid.*;
public class IntroductionActivity extends WrapAndroidActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); StarActivity._Call("DoFile","","/data/data/"+getPackageName()+"/lib/libCode.so"); }}
e cle也可以打包到工程中,此時需要將CLE的共用庫檔案放到工程目錄中,如下:
同時,將下載標誌設定為false
public class IntroductionActivity extends WrapAndroidActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { DownloadFromNetFlag = false; super.onCreate(savedInstanceState); setContentView(R.layout.main); StarActivity._Call("DoFile","","/data/data/"+getPackageName()+"/lib/libCode.so"); }}
f. 編輯布局檔案:main.xml.
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/widget73" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" >
<TextView android:id="@+id/widget45" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:id="@+id/widget74" android:layout_width="220dp" android:layout_height="48dp" android:text="thank for your use" android:typeface="serif" android:textStyle="bold" android:textColor="#ffff0000" android:layout_x="284dp" android:layout_y="220dp" android:textSize="16dp" /> </LinearLayout>
g. 在工程目錄下,建立jni目錄, 將wrap android和cle標頭檔拷貝到該目錄下. 建立新檔案code.cpp. and Android.mk, 編輯Android.mk:
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)
# Here we give our module name and sourcefile(s)LOCAL_CFLAGS += -Wno-write-strings -DENV_ANDROIDLOCAL_CPPFLAGS += -Wno-write-strings -fexceptions -DENV_ANDROIDLOCAL_LDFLAGS += -Wno-write-strings -DENV_ANDROID
LOCAL_C_INCLUDES += cle_files/include
#--------source fileMODULE_CXXSRCS := Code.cpp SRPWrapAndroidEngine_UUIDDef.cpp
LOCAL_SRC_FILES := ${MODULE_CXXSRCS}LOCAL_LDLIBS := cle_files/libs/armeabi/libstarlib.a
LOCAL_MODULE := Code
include $(BUILD_SHARED_LIBRARY)
#------------------------include $(CLEAR_VARS)
LOCAL_SRC_FILES := cle_files/so/armeabi/libstarcore.soLOCAL_MODULE := starcore
include $(PREBUILT_SHARED_LIBRARY)
#------------------------include $(CLEAR_VARS)
LOCAL_SRC_FILES := cle_files/so/armeabi/libstar_java.soLOCAL_MODULE := star_java
include $(PREBUILT_SHARED_LIBRARY)
步驟3. Code.cpp採用原生代碼編寫android應用,需要將其編譯成為共用庫。共用庫輸出兩個介面函數:VS_BOOL StarCoreService_Init(class ClassOfStarCore *starcore)void StarCoreService_Term(class ClassOfStarCore *starcore)
第一個函數在共用庫裝載的時候調用,可以進行一些初始化工作;第二個函數在共用庫卸載的時候調用
代碼如下: //--wrap android標頭檔#include "SRPWrapAndroidEngine_VSClass.h"
//--服務介面,其它所有函數都通過該介面調用.static class ClassOfSRPInterface *SRPInterface; //--android Activity對象,由java代碼建立.static void *StarActivity;
//--按鈕的事件函數。 事件函數的處理原型都相同.static VS_INT32 MyButton_onClick(VS_ULONG FunctionChoice,void *EventPara){ //--當事件被觸發時,顯示一些資訊. //--建立toast對象。 void *toast = SRPInterface->MallocObjectL(&VSOBJID_ToastClass,0,NULL); //--調用toast的函數“makeText”, (si) 為輸入參數的類型,詳細解釋需要參閱CLE文檔. SRPInterface -> ScriptCall(toast,NULL,"makeText","(si)","Button is click", 0); //--調用toast的函數“show” SRPInterface -> ScriptCall(toast,NULL,"show","()"); return 0;}
static VS_INT32 MyButton1_onClick(VS_ULONG FunctionChoice,void *EventPara){ void *toast = SRPInterface->MallocObjectL(&VSOBJID_ToastClass,0,NULL); SRPInterface -> ScriptCall(toast,NULL,"makeText","(si)","Button is click", 0); SRPInterface -> ScriptCall(toast,NULL,"show","()"); return 0;}
//--共用庫的初始化函數VS_BOOL StarCoreService_Init(class ClassOfStarCore *starcore){ class ClassOfBasicSRPInterface *BasicSRPInterface; //--擷取基本服務介面 BasicSRPInterface = starcore ->GetBasicInterface(); //---擷取當前的服務介面,服務由java代碼建立 SRPInterface = BasicSRPInterface ->GetSRPInterface(BasicSRPInterface->QueryActiveService(NULL),"",""); void *ActivityClass; //---擷取被封裝的acvitity類 ActivityClass = SRPInterface -> GetObjectEx(NULL,"ActivityClass"); //--調用getCurrent function擷取當前的activity, 由java代碼建立. ()O 表示傳回值為一個cle對象 StarActivity = (void *)SRPInterface -> ScriptCall(ActivityClass,NULL,"getCurrent","()O"); //--列印一些資訊,列印的資訊會顯示到logcat中. SRPInterface -> Print("Get Main Activity = %s", SRPInterface -> GetName(StarActivity)); //--調用activity的函數getResource擷取布局中定義的資源的ID. 輸入參數為字串,輸出為整數,使用標記為(s)I.int widget45 = SRPInterface -> ScriptCall(StarActivity,NULL,"getResource","(s)i","id/widget45"); //--調用findViewById函數擷取textview. 該函數與android的函數原型略為不同,輸入參數中增加的類的名稱。 void *MyText = (void *)SRPInterface -> ScriptCall(StarActivity,NULL,"findViewById","(si)o","TextViewClass",widget45); //--調用textview的函數setText。 SRPInterface -> ScriptCall(MyText,NULL,"setText","(s)","TextViewClass","from layout");
int widget74 = SRPInterface -> ScriptCall(StarActivity,NULL,"getResource","(s)i","id/widget74"); //--調用findViewById擷取按鈕對象 void *MyButton = (void *)SRPInterface -> ScriptCall(StarActivity,NULL,"findViewById","(si)o","ButtonClass",widget74); //--調用按鈕對象的setText. SRPInterface -> ScriptCall(MyButton,NULL,"setText","(s)","click me"); //--調用按鈕對象的函數setOnClickListener. SRPInterface -> ScriptCall(MyButton,NULL,"setOnClickListener","()"); //--註冊事件的處理函數 SRPInterface -> RegEventFunction(MyButton,&VSOUTEVENTID_ViewClass_onClick,MyButton,(void *)MyButton_onClick,0); int widget73 = SRPInterface -> ScriptCall(StarActivity,NULL,"getResource","(s)i","id/widget73"); //--調用findViewById擷取LinearLayout. void *MyLinearLayout = (void *)SRPInterface -> ScriptCall(StarActivity,NULL,"findViewById","(si)o","LinearLayoutClass",widget73); //--動態建立按鈕對象,是linearlayout的子物件 void *MyDynaButton = SRPInterface->MallocObject(MyLinearLayout,VSATTRINDEX_VIEWGROUPCLASS_VIEWQUEUE,&VSOBJID_ButtonClass,0,NULL); SRPInterface -> ScriptCall(MyDynaButton,NULL,"setText","(s)","created dynamically"); SRPInterface -> ScriptCall(MyDynaButton,NULL,"setOnClickListener","()"); SRPInterface -> RegEventFunction(MyDynaButton,&VSOUTEVENTID_ViewClass_onClick,MyDynaButton,(void *)MyButton1_onClick,0); //--設定布局參數 SRPInterface -> ScriptCall(MyDynaButton,NULL,"setLinearLayoutParams","(ii)",100,50);
return VS_TRUE;}
void StarCoreService_Term(class ClassOfStarCore *starcore){ SRPInterface -> Release(); return;}
Step 4. 使用ndk編譯成為共用庫
運行結果
例子下載:
http://wrapandroid-for-multilanguage.googlecode.com/svn/wiki/examples/c_introduction.zip