65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 C++ 编写 Android GUI: 第 4 部分 - Activity

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.76/5 (24投票s)

2012年7月1日

CPOL

3分钟阅读

viewsIcon

104395

downloadIcon

2662

本文给出的例子与之前的文章类似,只不过是用 C++ 编写的。

引言

在之前的文章中,我们看到了一个使用 Python 创建和启动子 Activity 的例子。在本文中,该示例用 C++ 重新编写。 使用 C++ 创建子 Activity 时,每个 Activity 都应构建为共享库,并使用 CLE 的接口函数 DoFile 加载。

本文给出的例子与之前的文章类似,只不过是用 C++ 编写的。 该示例包含两个 Activity,根 Activity 和子 Activity。 根 Activity 包含一个编辑小部件,用于从用户那里获取输入,以及一个按钮小部件。 当用户按下按钮时,将使用输入作为参数创建一个子 Activity。 子 Activity 在文本小部件中显示参数,并显示一个编辑小部件供用户输入父 Activity 的结果。 最后,子 Activity 返回的文本将显示在父 Activity 中。

根 Activity

布局 XML 文件

我们使用 XML 文件布局。 XML 文件包含文本视图、按钮和编辑视图,如下所示。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/widget30"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<LinearLayout
android:id="@+id/widget34"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:layout_gravity="center_vertical"
>
<TextView
android:id="@+id/widget35"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="input text :"
>
</TextView>
<EditText
android:id="@+id/widget38"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="hello"
android:textSize="18sp"
>
</EditText>
</LinearLayout>
<Button
android:id="@+id/widget39"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="send to child"
>
</Button>
<LinearLayout
android:id="@+id/widget40"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
android:layout_gravity="center_vertical"
>
<TextView
android:id="@+id/widget41"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="result from child :"
>
</TextView>
<TextView
android:id="@+id/widget42"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""
android:textSize="18sp"
>
</TextView>
</LinearLayout>
</LinearLayout>

Activity 的代码

Activity 的启动代码是用 Java 编写的,很简单。 它的功能是加载 C++ 共享库。

public class ActivityActivity 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");
    }
} 

code.cpp

Code.cpp” 是根 Activity 的主要代码。

步骤 1

C++ 代码的第一步是获取 Java 代码创建的服务组对象和 Activity 对象。

class ClassOfBasicSRPInterface *BasicSRPInterface;
//--init star core
BasicSRPInterface = starcore ->GetBasicInterface();    
SRPInterface = BasicSRPInterface ->GetSRPInterface(BasicSRPInterface->QueryActiveService(NULL),"","");
        
void *ActivityClass;
ActivityClass = SRPInterface -> GetObjectEx(NULL,"ActivityClass");
StarActivity = (void *)SRPInterface -> ScriptCall(ActivityClass,NULL,"getCurrent","()O");
SRPInterface -> Print("Get Main Activity = %s", SRPInterface -> GetName(StarActivity)); 
第二步

第 2 步获取在布局文件中定义的控件,并设置按钮的 onClick 事件监听器。 当事件触发时,我们构建一个 Intent 并创建一个子 Activity。 子 Activity 的名称为 ChildActivity。 必须在 AndroidManifest.xml 中声明它。 否则,调用将失败。

AndroidManifest.xml
<application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
    <activity
        android:label="@string/app_name"
        android:name=".ActivityActivity" >
        <intent-filter >
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".ChildActivity" android:label="@string/app_name"/>
</application>

获取在布局文件中定义的按钮并设置 onClick 监听器

static VS_INT32 MyButton_onClick(VS_ULONG FunctionChoice,void *EventPara)
{
    void *MyIntent = SRPInterface->MallocObjectL(&VSOBJID_IntentClass,0,NULL);
    SRPInterface -> ScriptCall(MyIntent,NULL,"setClassName","(s)","ChildActivity");
    VS_CHAR *Text = (VS_CHAR *)SRPInterface -> ScriptCall(myEdit,NULL,"getText","()s");
    SRPInterface -> ScriptCall(MyIntent,NULL,"putStringExtra","(ss)","value",Text);
    SRPInterface -> ScriptCall(StarActivity,NULL,"startActivityForResult","(oi)",MyIntent,1);
    SRPInterface->FreeObject(MyIntent);
    return 0;
}
    VS_INT32 widget39 = SRPInterface -> ScriptCall(StarActivity,NULL,"getResource","(s)i","id/widget39");
    void *myButton = (void *)SRPInterface -> ScriptCall(StarActivity,NULL,"findViewById","(si)O","ButtonClass",widget39);
    SRPInterface -> RegEventFunction(myButton,&VSOUTEVENTID_ViewClass_onClick,myButton,(void *)MyButton_onClick,0);
    SRPInterface -> ScriptCall(myButton,NULL,"setOnClickListener","()"); 
步骤 3

当子 Activity 返回时,我们可以从子 Activity 中获取结果并将其显示在文本视图中。 为了接收结果,我们应该重写 Activity 的函数 onActivityResult

static void StarActivity_onActivityResult(void *Object,int requestCode, int resultCode, void *data)  
{
    if( requestCode == 1 && data != NULL ){
        VS_CHAR *Text = (VS_CHAR *)SRPInterface -> ScriptCall(data,NULL,"getStringExtra","(s)s","value");
        SRPInterface -> ScriptCall(myText,NULL,"setText","(s)",Text);
    }
}
SRPInterface -> CreateOVLFunction(StarActivity,
  &VSFUNCID_ActivityClass_onActivityResult,(void *)StarActivity_onActivityResult,NULL); 

子 Activity

布局 XML 文件

XML 文件还包含一个文本视图、按钮和编辑视图,如下所示。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/widget30"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<LinearLayout
android:id="@+id/widget31"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/widget32"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="from parent :"
>
</TextView>
<TextView
android:id="@+id/widget33"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
>
</TextView>
</LinearLayout>
<LinearLayout
android:id="@+id/widget34"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/widget35"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="input text : "
>
</TextView>
<EditText
android:id="@+id/widget36"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="EditText"
android:textSize="18sp"
>
</EditText>
</LinearLayout>
<Button
android:id="@+id/widget37"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="return to parent"
>
</Button>
</LinearLayout> 

子 Activity 的代码

子 Activity 的启动代码与父 Activity 相同。

code.cpp

步骤 1

C++ 代码的第一步是获取 Java 代码创建的服务组对象和 Activity 对象,这与父 Activity 相同。

第二步

首先,我们获取父 Activity 设置的启动 Intent。 然后,获取在布局文件中定义的文本视图,并在文本视图中显示 Intent 的字符串。 现在获取按钮控件并设置其 onClick 事件监听器。 当事件触发时,我们为父 Activity 构建结果 Intent,并调用 finish 函数来结束子 Activity。

void *child_intent = (void *)SRPInterface -> ScriptCall(StarActivity,NULL,"getIntent","()o");
VS_INT32 widget33 = SRPInterface -> ScriptCall(StarActivity,NULL,"getResource","(s)i","id/widget33");
void *ChildText = (void *)SRPInterface -> ScriptCall(StarActivity,NULL,"findViewById","(si)O","TextViewClass",widget33);
VS_CHAR *Text = (VS_CHAR *)SRPInterface -> ScriptCall(child_intent,NULL,"getStringExtra","(s)s","value");
SRPInterface -> ScriptCall(ChildText,NULL,"setText","(s)",Text);
SRPInterface -> ScriptCall(ChildText,NULL,"setTextColor","(i)",0xFFFF0000); 

获取定义的布局按钮并设置 onClick 监听器。

static VS_INT32 MyButton_onClick(VS_ULONG FunctionChoice,void *EventPara)
{
    void *MyIntent = SRPInterface->MallocObjectL(&VSOBJID_IntentClass,0,NULL);
    VS_CHAR *Text = (VS_CHAR *)SRPInterface -> ScriptCall(myEdit,NULL,"getText","()s");
    SRPInterface -> ScriptCall(MyIntent,NULL,"putStringExtra","(ss)","value",Text);
    SRPInterface -> ScriptCall(StarActivity,NULL,"setResult1","(io)",0,MyIntent);
    SRPInterface->FreeObject(MyIntent);
    SRPInterface -> ScriptCall(StarActivity,NULL,"finish","()");
    return 0;
}

VS_INT32 widget37 = SRPInterface -> ScriptCall(StarActivity,NULL,"getResource","(s)i","id/widget37");
void *myButton = (void *)SRPInterface -> ScriptCall(StarActivity,NULL,"findViewById","(si)O","ButtonClass",widget37);
SRPInterface -> RegEventFunction(myButton,&VSOUTEVENTID_ViewClass_onClick,myButton,(void *)MyButton_onClick,0);
SRPInterface -> ScriptCall(myButton,NULL,"setOnClickListener","()");

我们还应该捕获“BACK”键事件。 当按下该键时,我们也会结束 Activity。

static VS_BOOL StarActivity_onKeyDown(void *Object,int keyCode, void *event)  
{
    if( keyCode == KEYCODE_BACKId ){
        void *MyIntent = SRPInterface->MallocObjectL(&VSOBJID_IntentClass,0,NULL);
        SRPInterface -> ScriptCall(MyIntent,NULL,"putStringExtra","(ss)","value","press key back");
        SRPInterface -> ScriptCall(StarActivity,NULL,"setResult1","(io)",0,MyIntent);
        SRPInterface->FreeObject(MyIntent);
        SRPInterface -> ScriptCall(StarActivity,NULL,"finish","()");
        return VS_TRUE;
    } 
    return VS_FALSE;
}

SRPInterface -> CreateOVLFunction(StarActivity,&VSFUNCID_ActivityClass_onKeyDown,(void *)StarActivity_onKeyDown,NULL); 

Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Here we give our module name and sourcefile(s)
LOCAL_CFLAGS += -Wno-write-strings -O0 -DENV_ANDROID
LOCAL_CPPFLAGS += -Wno-write-strings -O0 -fexceptions -DENV_ANDROID
LOCAL_LDFLAGS += -Wno-write-strings -O0 -DENV_ANDROID
LOCAL_C_INCLUDES += cle_files/include
#--------source file
MODULE_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)
# Here we give our module name and sourcefile(s)
LOCAL_CFLAGS += -Wno-write-strings -O0 -DENV_ANDROID
LOCAL_CPPFLAGS += -Wno-write-strings -O0 -fexceptions -DENV_ANDROID
LOCAL_LDFLAGS += -Wno-write-strings -O0 -DENV_ANDROID
LOCAL_C_INCLUDES += cle_files/include
#--------source file
MODULE_CXXSRCS := childcode.cpp SRPWrapAndroidEngine_UUIDDef.cpp
LOCAL_SRC_FILES := ${MODULE_CXXSRCS}
LOCAL_LDLIBS := cle_files/libs/armeabi/libstarlib.a
LOCAL_MODULE  := childcode
include $(BUILD_SHARED_LIBRARY)  
#------------------------
include $(CLEAR_VARS)
LOCAL_SRC_FILES := cle_files/so/armeabi/libstarcore.so
LOCAL_MODULE  := starcore
include $(PREBUILT_SHARED_LIBRARY)  
#------------------------
include $(CLEAR_VARS)
LOCAL_SRC_FILES := cle_files/so/armeabi/libstar_java.so
LOCAL_MODULE  := star_java
include $(PREBUILT_SHARED_LIBRARY)   

屏幕截图

父 Activity

子 Activity

© . All rights reserved.