Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Android

Writing an Android GUI using C++: Part 4 - Activity

4.76/5 (24 votes)
20 Jan 2014CPOL3 min read 103.6K   2.6K  
The example given in this article is similar to the previous article, except that it is written with C++.

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.

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>

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.

Java
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” 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.

C++
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)); 
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:
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:

C++
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.

C++
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.

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> 

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.

C++
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.

C++
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.

C++
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

Image 1

Child Activity

Image 2

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)