Android中webview的使用,重點處理圖片和附件下載

  1. webview基本使用:

    //加載網頁鏈接
    webView.loadUrl("http://keithxiaoy.com");
    //加載本地assets目錄下的網頁
    webView.loadUrl("file:///android_asset/keithxiaoy.html");
    //加載手機本地的html頁面
    webView.loadUrl("content://com.android.htmlfileprovider/sdcard/keithxiaoy.html");
    //加載 HTML 頁面的一小段內容。參數1:需要截取展示的內容、參數2:展示內容的類型、參數3:字節碼
    webView.loadData(String data, String mimeType, String encoding)
    webview.loadData(Html.fromHtml(notice.getContent()).toString(), "text/html", "UTF-8");
    
  2. webview配置:

    WebSettings settings = mWebView.getSettings();
    //如果訪問的頁面中要與Javascript交互,則webview必須設置支持Javascript
    webSettings.setJavaScriptEnabled(true);  
    // 若加載的 html 裏有JS 在執行動畫等操作,會造成資源浪費(CPU、電量)
    // 在 onStop 和 onResume 裏分別把 setJavaScriptEnabled() 給設置成 false 和 true 即可
    settings.setLoadsImagesAutomatically(true);//自動加載圖片
    settings.setAppCacheEnabled(false);//禁止緩存
    settings.setDatabaseEnabled(false);//禁止緩存
    
  3. WebChromeClient

    private class MyWebChromeClient extends WebChromeClient {
        //設置標題
        @Override
        public void onReceivedTitle(WebView view, String title) {
            super.onReceivedTitle(view, title);
        }
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            if (newProgress<100){
                if (progressBar.getVisibility() == View.GONE) progressBar.setVisibility(View.VISIBLE);
                progressBar.setProgress(newProgress);//改變進度條
            }else if (newProgress ==100){
                progressBar.setVisibility(View.GONE);
            }
            super.onProgressChanged(view, newProgress);
        }
    }
    
  4. js調用Android原生方法:

    //1. 先聲明一個類,可以理解爲js的對象,對象的名稱是下面的第二部的第二個參數
    class MyJavaInterFace{
        @JavascriptInterface//加上註解,表明js可有調用這個方法
        public void openFile(String url){
            FileDisplayActivity.show(ArticleDetailActivity.this,url);
        // startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
        }
    }
    //2. webview和聲明的類產生關聯,第二個參數相當於js中的對象名稱(上面類的別名),前端js通過webInterFace.openFile(參數)調用原生方法並傳遞參數
    webview.addJavascriptInterface(new MyJavaInterFace(),"webInterFace");
    
  5. Android調用js方法

     final String params = "android參數111111";//需要給前端傳遞的參數
     button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //調用js方法,以javascript表明調用的是前端js函數,funFromJs是前端js定義的函數名稱,傳遞參數時注意函數後的單引號和雙引號,我也不知道啥意思。
            webview.loadUrl("javascript:funFromJs('"+params+"')");
        }
    });
    
        /**
         * 4.4以上可用 evaluateJavascript 效率高
         */
        private void load(String jsCode) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                //
                evaluateJavascript(jsCode, null);
            } else {
                loadUrl(jsCode);
            }
        }
    //在Android中打印js中的console信息,以便進行聯調
    private class MywebChromeClient extends WebChromeClient {
        @Override
        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
            TLog.e("level:"+consoleMessage.messageLevel()+",message:"+consoleMessage.message()+",sourceId:"+consoleMessage.sourceId()+",lineNumber:"+consoleMessage.lineNumber());
            return super.onConsoleMessage(consoleMessage);
        }
    }
    
  6. 處理後退

     private boolean doubleBackToExit = false;
    /** 處理回退邏輯 */
     @Override
     public void onBackPressed() {
         //可以回退則回退到上一頁面
         if (webview.canGoBack()){
             webview.goBack();
         }else if (!webview.canGoBack()){
             if (doubleBackToExit){
                 super.onBackPressed();
                 return;
             }
             //不可以回退,提示
             Toast.makeText(MainActivity.this,"再按一次退出",Toast.LENGTH_SHORT).show();
             doubleBackToExit = true;//第一次按返回鍵後,標誌值爲true,兩秒中後置位false,這兩秒之內連續按返回鍵就可以退出
             new Handler().postDelayed(new Runnable() {
                 @Override
                 public void run() {
                     doubleBackToExit = false;
                 }
             }, 2000);
         }
    
  7. 處理圖片和附件下載

    //這裏處理了webview裏有超鏈接附件是不能下載的問題,識別超鏈接後可以調用原生方法,調用系統瀏覽器下載附件,files[i].removeAttribute('href')是阻止超鏈接的默認行爲,防止超鏈接點擊時在webview內打開空白頁,圖片通過修改maxWidth屬性修改爲圖片最大寬度爲手機寬度的90%,這裏保證js是在html代碼加載完畢再執行,這裏可以使用前端IDE,比如Vscode先把js代碼寫好後之間粘貼在AndroidStudio中,以免煩人的string拼接錯誤
    String varjs = "<script>\n" +
            "        window.onload = function () {\n" +
            "            var files = document.getElementsByTagName(\"a\");\n" +
            "            for (var i = 0; i < files.length; i++) {\n" +
            "                var fileUrl = files[i].getAttribute('href')\n" +
            "                if (fileUrl.endsWith('pdf') || fileUrl.endsWith('doc') || fileUrl.endsWith('docx') || fileUrl.endsWith('xls') || fileUrl.endsWith('xlsx')) {\n" +
            "                    files[i].removeAttribute('href')\n" +
            "                    files[i].onclick = function () {\n" +
            "                        webInterFace.openFile(fileUrl)\n" +
            "                    }\n" +
            "                }\n" +
            "            }\n" +
            "            var $imgs = document.getElementsByTagName(\"img\");\n" +
            "            for (var p = 0; p < $imgs.length; p++) {\n" +
            "                $imgs[p].style.maxWidth = '90%';\n" +
            "                $imgs[p].style.height = 'auto';\n" +
            "            }\n" +
            "        }\n" +
        //防止webview裏使用相對路徑,和使用retrofit的baseUrl性質一樣,這裏把js和原生的html組裝爲真正執行的html代碼,這裏加載的是html代碼片段,沒有html和body標籤,索性就直接把js代碼方法放在了html代碼的最前面,如果html是一個完整的,複雜的操作可以使用Jsoup解析後進行復雜操作jsoup地址`https://jsoup.org/`
        webview.loadDataWithBaseURL(baseUrl,varjs + newsArticle.getContent(), "text/html", "UTF-8",null);
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章