Introduction
In my previous article, we saw an example of how to create and launch a child activity using Python. In this article, the example is rewritten with C++. Using C++ to create child activities, each activity should be built as a share library, and is loaded with the interface function DoFile
of CLE.
The example given in this article is similar to the previous article, except that it is written with C++. The example contains two activities, root and child. The root activity contains an edit widget, which is used to get input from the user, and a button widget. When users press the button, a child activity is created with the input as parameter. The child activity displays the parameter in text widgets, and shows an edit widget for the user to input the result for the parent. Lastly, the text returned from the child is shown in the parent activity.
Root Activity
Layout XML file
We use an XML file layout. The XML file contains text view, button, and edit view, which is listed below.
="1.0"="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>
Code of activity
The boot code of the activity is written in Java, which is simple. Its function is to load the C++ share library.
public class ActivityActivity extends WrapAndroidActivity {
@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” is the main code of the root activity.
Step 1:
The first step of the C++ code is to get the service group object and the activity object created by the Java code.
class ClassOfBasicSRPInterface *BasicSRPInterface;
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));
Step 2:
Step 2 obtains widgets defined in the layout file and sets the onClick
event listener of the button. When the event is triggered, we build an intent and create a child activity. The child activity is named ChildActivity
. It must be declared in AndroidManifest.xml. Otherwise, the call will fail.
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>
Get the button defined in the layout file and set the onClick
listener:
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","()");
Step 3:
When the child activity returns, we can get the result from the child and show it in a text view. To receive the result, we should override the activity’s function 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);
Child Activity
Layout XML file
The XML file also contains a text view, button, and edit view, which are listed below.
="1.0"="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>
Code of child activity
The boot code of the child activity is the same as the parent activity.
code.cpp
Step 1:
The first step of the C++ code is to get the service group object and activity object created by the Java code, which is the same as the parent activity.
Step 2:
First, we get the start intent, which is set by the parent. Then, obtain the text view defined in the layout file and show the string of the intent in the text view. Now get the button widget and set its onClick
event listener. When the event is triggered, we build the result intent for the parent and call the finish function to end the child 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);
Get the button defined layout and set the onClick
listener.
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","()");
We also should capture the “BACK” key event. When the key is pressed, we also end the 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)
Screenshot
Parent Activity
Child Activity