Java is used as the main language on Android to write applications. Although NDK is provided, it is difficult to write native GUI applications. Can we write programs with other languages? The answer is yes. We can wrap Android Java classes to expose to special languages, and then uses that language to develop applications. The work should be done once instead of doing it for each language again and again. Using the middleware named CLE (Common Language Extension), we can achieve this. Using CLE, all the work needed to be done to encapsulate Android classes into CLE objects is done, then multiple languages are supported through the CLE interface.
1. Create CLE service and object description.
OnCreate
OnDestroy
Here we use a simple example to explain the above procedure in detail. In this example, we encapsulate a button class.
<!--?xml version="1.0" encoding="utf-8" ?--> <?xml version="1.0" encoding="utf-8" ?> <service ID="0d0af7b9-32f3-4708-ab91-c32f57e15dca" Password="123" Name="WrapAndroidService"> <sysrootitem> <BasicServiceItem ID="c15c5dfa-253f-4198-b1c3-34473487fb90" NameID="cb0338e8-e22f-48c0-931e-01b97502e374"> <object> <AndroidBaseClass ID="e51b7626-160e-485e-b4ee-1f37686736dd"> <attribute> <AndroidRefCount Type="VS_INT32" SyncFlag="1" /> </attribute> <function> <incAndroidRef ID="b4b43eb0-ec45-44aa-8af7-93b3f09a847c" /> <decAndroidRef ID="d7f5f007-b86f-4fd9-bc8f-86e1e5285e3b" /> <getActivity ID="e183d80f-1544-447a-928a-83702f475e0d"> <output Type="VS_OBJPTR" /> </getActivity> </function> </AndroidBaseClass> <ViewClass ID="2f669713-d0e6-484b-9473-5c50afd8bbd2" Class="AndroidBaseClass" /> <ActivityClass ID="16371687-dc7e-4177-a7cc-76fd118c9c3c" Class="AndroidBaseClass"> <attribute> <ViewGroupQueue Type="void *" Class="AbsoluteLayoutClass" /> </attribute> <function> <runScript ID="1d7668e4-b7e2-4c85-99cd-3cdb11ce5438"> <input Name="scriptInterface" Type="VS_CHAR *" /> <input Name="script" Type="VS_CHAR *" /> <output Type="VS_BOOL" /> </runScript> <DoFile ID="542be0a5-bd21-4765-b004-5e336587367c"> <input Name="scriptInterface" Type="VS_CHAR *" /> <input Name="path" Type="VS_CHAR *" /> <output Type="VS_BOOL" /> </DoFile> <DoAssetsFile ID="e894f038-1776-47c3-a6ec-802e5b86403c"> <input Name="scriptInterface" Type="VS_CHAR *" /> <input Name="path" Type="VS_CHAR *" /> <output Type="VS_BOOL" /> </DoAssetsFile> <pushActivity ID="b8b252ec-e3e7-4194-a557-4f98a5e43c22"> <input Name="activity" Type="VS_OBJPTR" /> </pushActivity> <popActivity ID="e024762e-cd83-4032-917b-9984bd91d725"> <output Type="VS_OBJPTR" /> </popActivity> <getCurrent ID="cfcabd6e-028d-45b4-9e34-ebe7dc4c56b6"> <output Type="VS_OBJPTR" /> </getCurrent> </function> </ActivityClass> <AbsoluteLayoutClass ID="155920e1-fdaa-489f-b4e9-4e3ac4cf5d7e" Class="ViewClass"> <attribute> <ViewQueue Type="void *" Class="ViewClass" /> </attribute> </AbsoluteLayoutClass> <ButtonClass ID="f12ab1a2-2694-4165-8b4f-889b8f9aa872" Class="ViewClass"> <function> <setText ID="1c6e8c3b-42db-41b9-988d-b7fb540b93be"> <input Name="text" Type="VS_CHAR *" /> </setText> </function> <outevent> <onClick ID="328adf46-b65a-49d4-a10a-bd308552de05" /> </outevent> </ButtonClass> </object> </BasicServiceItem> </sysrootitem> </service>
/* _OnCreate Event */ public Object[] _OnCreate(Hashtable Ev){ StarObjectClass self = (StarObjectClass)Ev.get("_DesObject"); StarObjectClass parent = (StarObjectClass)self._Get("_Parent"); StarObjectClass activity = (StarObjectClass)self._Call("getActivity"); /* create android button instance */ StarCLEButton button = new StarCLEButton((Activity)WrapAndroidClass.GetAndroidObject(activity,"AndroidObject"),self); /* record android button instance */ WrapAndroidClass.SetAndroidObject(self,"AndroidObject",(Object)button); /* set android button instance’s parent */ if( parent != null ){ if( activity == parent ){ Activity android_activity = (Activity)WrapAndroidClass.GetAndroidObject(parent,"AndroidObject"); android_activity.setContentView(button); }else{ ViewGroup android_viewgroup = (ViewGroup)WrapAndroidClass.GetAndroidObject(parent,"AndroidObject"); android_viewgroup.addView(button); } self._LockGC(); self._Call("decAndroidRef"); // release with parent } /* Add event listener */ button.setOnClickListener(new View.OnClickListener(){ public void onClick(View v) { StarObjectClass self = ((BasicAndroidInterface)v).getBasicAndroid().getStarObject(); /* trigger CLE object’s event onClick */ self._ProcessEvent("onClick"); } }); return null; }
public void setText(StarObjectClass self,String Text){ /*get recorded android instance*/ TextView textview = (TextView)WrapAndroidClass.GetAndroidObject(self,"AndroidObject"); if( textview != null ) /*call android instance’s function setText*/ textview.setText(Text); }
Copy “wrapandroid.jar” and “starcore_android_r5.jar” to your project directory. Add jar library to your project.
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
Create the code.lua file in the asserts directory, input text
SrvGroup = libstarcore._GetSrvGroup() Service = SrvGroup:_GetService("","") --get activity StarActivity = Service.ActivityClass.getCurrent(); --create AbsoluteLayout MyLayout = Service.AbsoluteLayoutClass:_New(StarActivity); --create Button MyButton = Service.ButtonClass:_New(MyLayout); MyButton:setText("Hello"); function MyButton:onClick(Event) self:setText("Is Clicked"); end