注入前:
注入后:
主界面:
- package com.example.webviewjsdemo;
- import android.os.Bundle;
- import android.app.Activity;
- import android.view.Menu;
- import android.webkit.WebChromeClient;
- import android.webkit.WebSettings;
- import android.webkit.WebView;
- import android.webkit.WebViewClient;
- import android.widget.Toast;
- public class MainActivity extends Activity {
- private WebView wv;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- wv = (WebView) findViewById(R.id.wv_main);
- wv.setWebChromeClient(new WebChromeClient() {
- });
- wv.setWebViewClient(new WebViewClient() {
- @Override
- public void onPageFinished(final WebView view, String url) {
- Toast.makeText(getApplicationContext(), "3秒后改变内容", 1).show();
- new Thread(){
- public void run() {
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- view.loadUrl("javascript:function myFunction(){x=document.getElementById("demo"); x.innerHTML="改变了html内容!";}");
- view.loadUrl("javascript:myFunction()");
- };
- }.start();
- super.onPageFinished(view, url);
- }
- });
- WebSettings wvSettings = wv.getSettings();
- wvSettings.setJavaScriptEnabled(true);
- wv.loadUrl("file:///android_asset/demo.html");
- }
- }
主界面layout:
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity" >
- <WebView
- android:id="@+id/wv_main"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_centerHorizontal="true"
- android:layout_centerVertical="true" />
- </RelativeLayout>
assets目录下的demo.html文件
- <!DOCTYPE html>
- <html>
- <body>
- <h1>Js注入</h1>
- <p id="demo" style="color:red;font-size:16px;">
- 这里将会改变。
- </p>
- </body>
- </html>
-
Android中向webview注入js代码可以通过webview.loadUrl("javascript:xxx")来实现,然后就会执行javascript后面的代码。
但是当需要注入一整个js文件的时候,貌似就有点麻烦了。
不过理清以下思路,方法其实也很简单,如下:
我们通过在webview的onPageFinished方法中执行js代码注入:第一种:
当webview加载完之后,读取整个js文件中的内容,然后将整个文件内容以字符串的形式,通过webview.loadUrl("javascript:fileContentString")注入URL url = new URL("http://www.rayray.ray/ray.js"); in = url.openStream(); byte buff[] = new byte[1024]; ByteArrayOutputStream fromFile = new ByteArrayOutputStream(); FileOutputStream out = null; do { int numread = in.read(buff); if (numread <= 0) { break; } fromFile.write(buff, 0, numread); } while (true); String wholeJS = fromFile.toString();
@Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); webview.loadUrl("javascript:" + wholeJS); }
第二种:
页面加载完之后,直接向webview对应的html中加入<script>便签,并包含要注入的js的Url地址,如下:String js = "var newscript = document.createElement("script");"; js += "newscript.src="http://www.123.456/789.js";"; js += "document.body.appendChild(newscript);";
@Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); webview.loadUrl("javascript:" + js); }
后记:上面两种方式中,第二种方法更加简单方便一点。不过第二种方法也有问题,当你注入完JS之后你想要立即调用其中的方法,第一种方法没问题可以调用到。但是第二种方法中,你要确保注入的<script>便签对应的js文件加载完才可调用成功。
解决:在第二种方法中为加入script标签添加onload事件,确保该script已加载完成。代码可更改如下:String js = "var newscript = document.createElement("script");"; js += "newscript.src="http://www.123.456/789.js";"; js += "newscript.onload=function(){xxx();};"; //xxx()代表js中某方法 js += "document.body.appendChild(newscript);";
IOS中也一样,按照同样的思路然后在-(void)webViewDidFinishLoad:(UIWebView *)webView 中使用[webView stringByEvaluatingJavaScriptFromString:@"xxx"];即可 。
-