App Webview and embedded web interaction implementation, appwebview embedded web
Requirements:
In a company App project, functions implemented through web are embedded. With the continuous expansion of functions, embedded web interfaces need to call App-related information or implement functions through apps, so I studied how the WebView of the APP interacts with embedded web pages.
After clarifying the requirements, the individual is relatively lazy and can see if others have already implemented the requirements. Fortunately, there was an implementation method for IOS and Web, and it felt very good. Refer to the Website: Ghost.
The implementation logic is generally like this. The webview of the APP can intercept the request link address, agree with the request prefix (for example, webjs2app: //) with the embedded interface, and then accept the request content.
The request content is as follows:
{"FunctionName": "sayHello '," args ": [" haha "]," success ":" onSuccess "," error ":" onError "}
It is a Json string, including the name of the called App interface method, the passed parameters, the name of the js method called after the call is successful, and the name of the js method called after the call fails. Abstract is in place and can be universal.
The final web Request interface address is: webjs2app: // {"functionname": "sayHello", "args": ["haha"], "success": "onSuccess ", "error": "onError"}, when the App webview receives a request address headers by webjs2app: //, it will parse the subsequent request content... On the code.
I already have IOS and Web code in the link, and I can explain it clearly. I would like to add the implementation of Android.
Step 1: rewrite shouldOverrideUrlLoading to block the agreed request.
Private String protocolPrefix = "webjs2app: //"; // The prefix must be in lower case, because webview automatically converts the request protocol type to lower case.
MWebView. setWebViewClient (new WebViewClient (){
@ Override
Public boolean shouldOverrideUrlLoading (WebView view, String url ){
Return processURL (url );
}
....
}
Step 2: parse request interface data
Private boolean processURL (String url ){
Int I = url. indexOf (protocolPrefix );
System. out. println (url );
If (url. indexOf (protocolPrefix) = 0 ){
// Strip protocol from the URL. We will get input to call a native method
Url = url. substring (protocolPrefix. length ());
// Decode the url string
HashMap callInfo = JsonUtil. read (url, HashMap. class );
If (callInfo = null ){
// TODO: a message indicating an error occurred while calling the resolution.
Return false;
}
// Get function name. It is a required input
Object functionName = callInfo. get ("functionName ");
If (functionName = null ){
// TODO: The system prompts that the call method is not found.
Return false;
}
Object success = callInfo. get ("success ");
Object error = callInfo. get ("error ");
Object args = callInfo. get ("args ");
CallNativeFunction (String) functionName, args, success, error );
Return false;
}
Return true;
}
Step 3: Use java reflection to call interfaces.
/**
* Method interface call
*
* @ Param functionName
* @ Param args
* @ Param success
* @ Param error
*/
Private void callNativeFunction (String functionName, Object args, Object success, Object error ){
Try {
// Use reflection. Do not confuse the JsFunctions class.
Method method = JsFunctions. class. getMethod (functionName, WebView. class, Object. class );
Object invoke = method. invoke (JsFunctions. getInstance (), mWebView, args, success, error );
} Catch (NoSuchMethodException e ){
// TODO: The system prompts that the call method is not found.
} Catch (InvocationTargetException e ){
E. printStackTrace ();
} Catch (IllegalAccessException e ){
// TODO: a prompt is displayed for permission access.
E. printStackTrace ();
}
}
Step 4: interface processing class
Public class JsFunctions {
/**
* Singleton
*/
Private static JsFunctions instance = new JsFunctions ();
/**
* SayHello Interface
* @ Param webView
* @ Param args
* @ Param successFunc
* @ Param errorFunc
*/
Public void sayHello (WebView webView, Object args, Object successFunc, Object errorFunc ){
If (args! = Null ){
Object name = (ArrayList) args). get (0 );
Log. d (name. toString ());
If (successFunc! = Null)
CallJSFunction (webView, successFunc. toString (), args );
} Else {
If (errorFunc! = Null)
CallJSFunction (webView, errorFunc. toString (), args );
}
}
/**
* Callback Processing
* @ Param webView
* @ Param functionName
* @ Param args
*/
Public void callJSFunction (WebView webView, String functionName, Object args ){
String argsJsonStr = null;
If (args! = Null ){
ArgsJsonStr = JsonUtil. write2String (args );
}
If (argsJsonStr! = Null)
WebView. loadUrl ("javascript:" + functionName + "('" + argsJsonStr + "')");
Else
WebView. loadUrl ("javascript:" + functionName + "()");
}
Public static JsFunctions getInstance (){
Return instance;
}
}
Now, let's get there. please correct me if you have any shortcomings...