Plugin management mechanism for Android and WebView

Source: Internet
Author: User
Tags getmessage

The previous article said that when using webviewclient or webchromeclient to handle requests sent by an HTML page, the corresponding service name, operation method and corresponding parameter data will be passed to a class called PlugInManager.

What is the role of the PlugInManager class?

You know, when using the Android native environment features, such as camera, such as photo albums, these functions are very decentralized, it is unclear when the need for these features, when the need for these features, so we want to be like a plug-in, the need to load in, Do not need to ignore him, and the PlugInManager class is one such management class.

It is mainly responsible for several things:

1) When you go to the HTML page, load the controls that we have defined.

Mpluginmanager = new PlugInManager (this); Mpluginmanager.loadplugin ();

So how does PlugInManager know how many plugin the app will load to respond to requests from HTML pages?

We are defined by a configuration file called Plugin.xml.

<plugins>    <plugin name= "App" class= "com.lms.xxx.bridge.plugin.App"/> <plugin name=    "Toast" class= "Com.lms.xxx.plugin.Toast"/>    <plugin name= "Dialog" class= "Com.lms.xxx.bridge.plugin.Dialog"/>       <plugin name= "User" class= "Com.lms.xxx.bridge.plugin.User"/></plugins>


For example, in the above configuration file, we will load the app, Toast, Dialog and User of the several plugin.

It can be thought that toast and dialog are all display windows in Android native environment, although we use HTML page to implement interface, but in order to maintain the consistency of the whole application, we will use the native environment toast or our custom dialog box and other controls.

What needs to be used, what is defined here.

Let's take a look at the Loadplugin method:

public void Loadplugin () {int identifier = Context.getresources (). Getidentifier ("Plugins", "xml", Context.getpackagename ()); if (identifier = = 0) {pluginconfigurationmissing ();} Xmlresourceparser XML = Context.getresources (). GETXML (identifier); try {int eventtype = -1;while ((EventType = Xml.next () ) = Xmlresourceparser.end_document) {if (EventType = = Xmlresourceparser.start_tag) {String name = Xml.getname (); if ("Plu Gin ". Equals (name)) {String pluginname = Xml.getattributevalue (null," name "); String className = Xml.getattributevalue (null, "class"); Configs.put (Pluginname, ClassName);}}} catch (Xmlpullparserexception e) {e.printstacktrace ();} catch (IOException e) {e.printstacktrace ()}}

As you can see, this is to parse the Plugins.xml file, and then put the corresponding plug-in class name into Configs, configs defined as follows:

Private hashmap<string, string> configs = new hashmap<string, string> ();p rivate hashmap<string, IPlugin& Gt Plugins = new hashmap<string, iplugin> ();

Through the Loadplugin method, we will be in the plugins.xml defined in the plug-in, to load into the configs, configs stored only the class name, and plugins storage is the implementation, but we do not need to care about this here.

In this case, the name attribute defined in the Plugins.xml file is the service.

2) According to the requested service name and operation method, and so on, for this request to find the corresponding plugin to deal with.

String Execresult = mpluginmanager.exec ("service", "action", args);

Take a look at the Exec method,

public string exec (string service, string action, Jsonobject args) throws pluginnotfoundexception {        IPlugin plugin = g Etplugin (Service), ..... Pluginresult result = plugin.exec (action, args), ...}

In the above logic can be seen, PlugInManager will use the Getplugin method to come up with the corresponding services, as follows:

Public IPlugin Getplugin (string pluginname) throws Pluginnotfoundexception {string className = Configs.get (pluginname); if (classname==null) {throw new pluginnotfoundexception (Pluginname);} if (Plugins.containskey (ClassName)) {return plugins.get (className);} else {return addplugin (className);}}


In this way, we get a plugin implementation class that implements the IPlugin interface.

IPlugin is an interface that is defined as follows:

Public interface IPlugin {public static final string service = "Service";p ublic static final string action = "ACTION";p UBL IC static final String args = "args";/** * Execute request *  * @param action *            function * @param ARGS *            parameter * @return Pluginresu LT results */public Pluginresult exec (String action, Jsonobject args) throws actionnotfoundexception;

The most important way to define the inside is the Exec method, each of our custom plug-ins to implement this interface, but here, we first implemented an abstract base class plugin, in the implementation of some common logic, and for the specific implementation, and then by the plugin subclass to inherit.

Public abstract class Plugin implements IPlugin {protected DROIDHTML5 context;

For example, if we take the toast class above, it will inherit plugin, then implement the corresponding logic according to the corresponding service, invoke the native environment toast.

public class Toast extends Plugin {@Overridepublic Pluginresult exec (String action, Jsonobject args) throws Actionnotfound Exception {if ("Maketextshort". Equals (Action)) {return maketextshort (args);} else if ("Maketextlong". Equals (Action)) {return Maketextlong (args)} else {throw new Actionnotfoundexception ("Toast", action);}} Private Pluginresult Maketextshort (Jsonobject args) {try {String text = args.getstring ("text"); Android.widget.Toast.makeText (context, text, Android.widget.Toast.LENGTH_SHORT). Show (); catch (Jsonexception e) {e.printstacktrace (); return Pluginresult.newerrorpluginresult (E.getmessage ());} return Pluginresult.newemptypluginresult ();} Private Pluginresult Maketextlong (Jsonobject args) {try {String text = args.getstring ("text"); Android.widget.Toast.makeText (context, text, Android.widget.Toast.LENGTH_LONG). Show (); catch (Jsonexception e) {e.printstacktrace (); return Pluginresult.newerrorpluginresult (E.getmessage ());} return Pluginresult.newemptypluginresult ();}}


From the above code, I believe you can easily understand the plugin mechanism.

3) Called from an HTML page.

We have defined a set of plugin mechanisms in the Android native environment, so in HTML, there is a set of interface methods to correspond to different plugin, so we also define a variety of objects in JavaScript.

For example, the toast plugin described above, we can define a corresponding object in JavaScript, as follows:

var toast = {Maketextshort:function (text) {return exec ("Toast", "Maketextshort", json.stringify (text));},maketextlong : function (text) {return exec ("Toast", "Maketextlong", json.stringify (text));}}

Here, we can see the toast of the Maketextshort method, will call the Exec method mentioned in the previous article, because the pop-up window shows that this thing is definitely synchronous, do not say a process, suddenly ran out of a box, tell me, you just did wrong, right.

In this case, we will use the Exec method, such as the service name (Toast), the action method (Maketextshort), and the displayed content (Json.stringfy (text)). Then, using Webchromeclient's Onjsprompt method, the command is passed to PlugInManager, which is handled by the PlugInManager.

public boolean onjsprompt (WebView view, string URL, String message,string defaultvalue, jspromptresult result) {System.ou T.println ("Onjsprompt:defaultvalue:" + defaultvalue + "|" + URL + "," + message); Jsonobject args = null; Jsonobject head = null;try {//message:{"service": "XX", "Action": "XX"}head = new Jsonobject (message); if (defaultvalue ! = null &&!defaultvalue.equals ("")) {try {args = new jsonobject (defaultvalue);} catch (Exception e) {e.printstacktrace ();}} String Execresult = mpluginmanager.exec (head.getstring (Iplugin.service), head.getstring (iplugin.action), args); Result.confirm (Execresult); return true;

4) We will put these definitions of plug-in objects, as well as synchronous (exec), asynchronous Execution (Exec_sync) methods are written into a JavaScript file, easy to manage, so generally this file content will be like this:

var toast = {Maketextshort:function (text) {return exec ("Toast", "Maketextshort", json.stringify (text));},maketextlong : function (text) {return exec ("Toast", "Maketextlong", json.stringify (text));}} var Dialog = {...} var AndroidHtml5 = {..../* * Exec_asyn method called @params {jsonobject} cmd service name and action command @params {String} args parameter */callnative:func tion (cmd, args, success, fail) {....},<span style= "White-space:pre" ></span>...callbackjs:function ( Result,key) {...}};/ * * HTML5 Sync interface with Android */var exec = function (service, action, args) {var json = {"Service": Service, "action": action};v Ar result_str = prompt (Json.stringify (JSON), args), var result;try {result = Json.parse (RESULT_STR);} catch (e) {CONSOLE.E Rror (e.message);} ...} /* * HTML5 with Android asynchronous interface */var Exec_asyn = function (service, action, args, success, fail) {var json = {"Service": Service , "action": action};var result = androidhtml5.callnative (JSON, args, success, fail);}

End.





Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.