Click here to Skip to main content
Click here to Skip to main content

Embedding lua in web page on android

By , 6 Apr 2013
Rate this:
Please Sign up or sign in to vote.

Introduction

Integrating a web server in android application can increase its flexibility, because it gives more interactive with other terminals. For web server, programmers need write web pages and these pages should be able to interoperate with host application. This article introduces an idea to embed lua in web page as dynamic language at server side and gives an example written based on starcore and SRPSHtmlEnvEngine, which is an embeddable web server supports http get and http post request.

Embedding lua

Lua is a tiny and easily use script language. To embed lua in the web page, we need define a tag for lua script, a server can find the tag, extract the lua code and execute the lua code. In addition, the lua code can call functions defined in host application to do more works.

Defining a tag for lua is simple, for example, “<?lua> <?>” can be used to mark a lua code segment. When the server handle http request, it read the web page, check whether there has lua tag. Then the server execute the code, receive the output from the code, and add the output to the html page.

For example:

<!DOCTYPE html>
<html>
<body>
<h1><?lua echo([[hello from lua]]) /> </h1>
</body>
</html> 

The lua code “echo([[hello from lua]])” should be extracted from html page, and executed. Then, the output value “hello from lua” should be inserted to the html page. The result is :

<!DOCTYPE html>
<html>
<body>
<h1>hello from lua</h1>
</body>
</html> 

The server engine needs do more work.

1. It should parse http request, create parameters for http get and post request for lua script.

2. It should be able to execute lua script.

3. It should enable lua to call java easily on android. Therefore most functions can be realized by host application.

The next part of this article gives an example to send sms from pc using web browser. It is based on starcore and "SRPSHtmlEnvEngine".

send sms from pc using web browser

1. lua code embedded in the sample page

 <?lua>
    if( _GET["submit"] == nil ) then
        echo("&nbsp;")
    else
        --send sms
        print(_POST["number"],_POST["text"])  --output info to console
        HostObject:SendSms(_POST["number"],_POST["text"])
        echo(hcode("Send sms to ".._POST["number"]))   --output result to web page
    end
<?>  

The _GET and _POST variable are table which is assigned by web server based on http request. The “_GET” is corresponding to http get request, for example, for http://XXX/index.html?a=123&b=456, the _GET variable will be {a=”123”,b=”456”}. The _POST variable is corresponding to http post request, which is extracted from html request body. The code first check whether there has “submit” parameter from request url. If not, then the request is submitted from web browser with message to send. It get send phone number and text, and call SemdSms function of HostObject to send short message. The HostObject is defined in host application, see below.

2. Create project

Create project and add libraries of starcore and SRPSHtmlEnvEngine into the project. As follow,

“libstar_java.so” is the interface of java and “libstarcore.so” is the core share library. “libSRPHtmlEnvEngineBasicModule_android.so” is the library of web server. The file “index.html” in assets directory is the web page. And the “SRPSHtmlEnvEngine.xml” is the service description file of web server. These files should be added to the project.

3. Add user permission in file “AndroidManifest.xml”

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.SEND_SMS"></uses-permission> 

These permission enables the app to send sms and receive internet request.

4. The main code “MainActivity”

a. Set work path for starcore

StarCoreFactoryPath.StarCoreCoreLibraryPath = "/data/data/"+getPackageName()+"/lib";
StarCoreFactoryPath.StarCoreOperationPath= "/data/data/"+getPackageName()+"/files";
StarCoreFactoryPath.StarCoreShareLibraryPath = "/data/data/"+getPackageName()+"/lib"; 

StarCoreCoreLibraryPath is the path for “libstarcore.so” and “libstar_java.so”. StarCoreOperationPath is the path of temporary file for starcore. This path may be set to null. StarCoreShareLibraryPath is the path for other share libraries for starcore.

b. Init starore.

starcore= StarCoreFactory.GetFactory();
SrvGroup =starcore._InitSimpleEx(0,0);
SrvGroup._ImportServiceFromXmlBuf(servicestr, true);
SrvGroup._CreateService( ""," test", "123",5,0,0,0,0,0,"" );  
Service = SrvGroup._GetService("root","123");
Service._CheckPassword(false);        

Using the above code to init starcore. servicestr is service description xml string, which is loaded from assets.

First, we get the object "starcore" through function "GetFactory", and call it's function “_InitSimpleEx” to initialize the starcore middleware. Second, we call the function “_ImportServiceFromXmlBuf” with service description string to import the web server. At last, we call “_CreateService” function to create new starcore service. For details about these functions, please refer to documentation of starcore. For service to be accessible by web server, “_CheckPassword” function must be called with input parameter “false”.

InputStream dataSource = getAssets().open("SRPSHtmlEnvEngine.xml");
int size=dataSource.available();
byte[] buffer=new byte[size]; 
dataSource.read(buffer); 
dataSource.close();        
servicestr=new String(buffer);  

c. Open web server port

SrvGroup._SetWebServerPort("",8080,100,0); 

The first parameter should be set to “”. The second parameter is the port number. The Third parameter is the maximum number of connections simultaneously. The fourth is the maximum post size, unit is Kbytes.

d. Create instance of SHtmlEnvSiteClass to handle web request

 StarObjectClass a = Service._GetObject("SHtmlEnvSiteClass")._New()._Assign(new StarObjectClass(){
            public Object[] FileOpen(StarObjectClass self,String Name,String RequestPara){
                if( Name.equals("/index.html"))
                    return new Object[]{1,false};
                else
                    return new Object[]{0,false};
            }
            public int FileSize(StarObjectClass self,int Handle){
                try{
                    InputStream dataSource = getAssets().open("index.html");
                       return dataSource.available();
                }
                catch(Exception e){
                    return 0;
                }
            }         
            public void FileClose(StarObjectClass self,int Handle){
                return;
            }        
            public int FileRead(StarObjectClass self,int Handle,StarBinBufClass Buf,int Size){
                try{
                    InputStream dataSource = getAssets().open("index.html");
                       byte[]  buffer = new byte[Size];  
                       int result = dataSource.read(buffer); 
                       Buf._Clear();
                       Buf._Write(0, buffer, result);
                       return result;
                   }
                catch(Exception e){
                    Buf._Clear();
                    return 0;
                }            
            }         
            public void ScriptInit(StarObjectClass self,String ScriptName){
                if( ScriptName.equals("lua") ){
                    SrvGroup._InitRaw("lua", Service);
                    StarObjectClass lua = Service._ImportRawContext("lua", "", false, "");
                    lua._Set("HostObject", new SendSmsClass());
                }
        });    

For the instance, we create five functions : “FileOpen”, “FileRead”, “FileSize”, “FileClose”, and “ScriptInit”.

In FileOpen function, we returns a file handle for other functions. Because index.html is in assets, we define a pseudo handle 1 for it.

For "FileRead" function, input parameter is Buf and Size. Type of Buf is StarBinBufClass, which is defined in starcore for binary buf. Size is the maximum size for each read operation. In the example, the web page is not copied to application directory. It exists in assets of the installation package. We directly call function “open” of asset manager to read the file content and call “_Write” method of “StarBinBufClass” to return the page to web server. The return value of “FileRead” function is the size of data in bytes.

"ScriptInit" will be call when the first script is executed in the web page. The input parameter is script name, which may be “lua” or “python”. In this function, we create an instance of SendSmsClass, and assign it to lua to be called by script.

e. SendSmsClass

The SendSmsClass is simple. It has one function SendSms with number and txt as input parameter.

     class SendSmsClass{
        public void SendSms(String number,String txt){
            if( number == null || txt == null )
                return;
            SmsManager sms=SmsManager.getDefault();
            sms.sendTextMessage(number, null, txt, null, null);
        }        
    }; 

f. Create a timer to drive starcore

The last step is to create a timer and call SRPDispatch method of starcore.

    private Handler handler = new Handler(){  
        @Override  
        public void handleMessage(Message msg)  
        {  
               while( starcore._SRPDispatch(false) == true );
        }
};
    timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask()  
    {  
        @Override  
        public void run()  
        {  
              Message message = handler.obtainMessage(); //handler is an instance of type Handler
               message.what = 1;
               message.sendToTarget();
        }  
    }, 0, 10);      /*change from 10 to 100 */   

 5. Screenshot 

About the sample 

 The sample uses some functions defined starcore. For details about these functions, please refer to the documentation of starcore. The code embeds lua in webpage. Furthermore we can also embed python in the web page. It is also simple for python can work on android too. 

License

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

About the Author

li9705

China China
No Biography provided

Comments and Discussions

 
QuestionPotential security risk Pinmemberpatbob12-Apr-13 10:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140415.2 | Last Updated 7 Apr 2013
Article Copyright 2013 by li9705
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid