Android開發:經過 webview 將網頁打包成安卓應用

商業轉載請聯繫做者得到受權,非商業轉載請註明出處。

For commercial use, please contact the author for authorization. For non-commercial use, please indicate the source.

協議(License):署名-非商業性使用-相同方式共享 4.0 國際 (CC BY-NC-SA 4.0)

做者(Author):

連接(URL):https://www.35youth.cn/817.html

來源(Source):搬磚少年

近期團隊接到一個新的項目,企業內部的一個掌上超市項目,最初考慮經過公衆號或者小程序來作,後面說是部署在企業內網,就考慮到作網站應用,因爲須要經過運營商分配的apn鏈接企業內網,因此在打開應用以前須要檢測一下網絡,若是是web端的話,那就無法檢測網絡了,因此考慮使用安卓的 webview 封裝一下H5的應用。
一、配置網絡鏈接權限html

在AndroidManifest.xml文件中加上如下配置信息

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

注: 從Android 9.0(API級別28)開始,默認狀況下禁用明文支持。所以http的url均沒法在webview中加載 ,因此只配置以上信息可能會致使net::ERR_CLEARTEXT_NOT_PERMITTED報錯,還須要在配置文件的 application中加入下面的配置。參照文章: net::ERR_CLEARTEXT_NOT_PERMITTEDandroid

android:usesCleartextTraffic="true"

webview 網絡配置異常
net::ERR_CLEARTEXT_NOT_PERMITTED 配置
二、建立layout文件
使用idea的話,會自動建立MainActivity和對應的layout文件,直接在文件的基礎上修改便可,使用Webview控件,若是須要使用進度條的話,能夠將ProgressBar 的配置打開便可。web

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.ctjsoft.jxf.shop.MainActivity">
    <WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent"/>
    <!--<ProgressBar android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/progressbar"
                 style="@android:style/Widget.ProgressBar.Horizontal" android:max="100" android:progress="0"
                 android:visibility="gone"/>-->
</androidx.constraintlayout.widget.ConstraintLayout>

三、修改 MainActivity 文件
重寫onCreate方法:小程序

protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //progressBar = (ProgressBar) findViewById(R.id.progressbar);//進度條
 
        webView = (WebView) findViewById(R.id.webview);
        webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
        webView.getSettings().setAllowFileAccessFromFileURLs(true);
        // webview的設置中添加以下代碼
        try {
            if (Build.VERSION.SDK_INT >= 16) {
                Class<?> clazz = webView.getSettings().getClass();
                Method method = clazz.getMethod("setAllowUniversalAccessFromFileURLs", boolean.class);
                if (method != null) {
                    method.invoke(webView.getSettings(), true);
                }
            }
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //webView.loadUrl("http://172.17.1.176:8082/");//加載url
        webView.loadUrl(API);
 
        //使用webview顯示html代碼
//        webView.loadDataWithBaseURL(null,"<html><head><title> 歡迎您 </title></head>" +
//                "<body><h2>使用webview顯示 html代碼</h2></body></html>", "text/html" , "utf-8", null);
 
        webView.addJavascriptInterface(this, "android");//添加js監聽 這樣html就能調用客戶端
        webView.setWebChromeClient(webChromeClient);
        webView.setWebViewClient(webViewClient);
        WebSettings webSettings = webView.getSettings();
        /**
         * LOAD_CACHE_ONLY: 不使用網絡,只讀取本地緩存數據
         * LOAD_DEFAULT: (默認)根據cache-control決定是否從網絡上取數據。
         * LOAD_NO_CACHE: 不使用緩存,只從網絡獲取數據.
         * LOAD_CACHE_ELSE_NETWORK,只要本地有,不管是否過時,或者no-cache,都使用緩存中的數據。
         */
        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//不使用緩存,只從網絡獲取數據.
        webView.getSettings().setTextZoom(100);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);//設置js能夠直接打開窗口,如window.open(),默認爲false
        webView.getSettings().setJavaScriptEnabled(true);//是否容許執行js,默認爲false。設置true時,會提醒可能形成XSS漏洞
        webView.getSettings().setSupportZoom(true);//是否能夠縮放,默認
        webView.getSettings().setBuiltInZoomControls(true);//是否顯示縮放按鈕,默認false
        webView.getSettings().setUseWideViewPort(true);//設置此屬性,可任意比例縮放。大視圖模式
        webView.getSettings().setLoadWithOverviewMode(true);//和setUseWideViewPort(true)一塊兒解決網頁自適應問題
        webView.getSettings().setAppCacheEnabled(true);//是否使用緩存
        webView.getSettings().setDomStorageEnabled(true);//DOM Storage
    }

配置WebviewClientapi

//WebViewClient主要幫助WebView處理各類通知、請求事件
    private WebViewClient webViewClient = new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {//頁面加載完成
            //progressBar.setVisibility(View.GONE);
        }
 
        public void onPageStarted(WebView view, String url, Bitmap favicon) {//頁面開始加載
            //progressBar.setVisibility(View.VISIBLE);
        }
 
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            Log.i("ansen", "攔截url:" + request.getUrl());
            return super.shouldOverrideUrlLoading(view, request);
        }
 
    };
 
    //WebChromeClient主要輔助WebView處理Javascript的對話框、網站圖標、網站title、加載進度等
    private WebChromeClient webChromeClient = new WebChromeClient() {
        //不支持js的alert彈窗,須要本身監聽而後經過dialog彈窗
        public boolean onJsAlert(WebView webView, String url, String message, JsResult result) {
            AlertDialog.Builder localBuilder = new AlertDialog.Builder(webView.getContext());
            localBuilder.setMessage(message).setPositiveButton("肯定", null);
            localBuilder.setCancelable(false);
            localBuilder.create().show();
 
            //注意:
            //必需要這一句代碼:result.confirm()表示:
            //處理結果爲肯定狀態同時喚醒WebCore線程
            //不然不能繼續點擊按鈕
            result.confirm();
            return true;
        }
 
        //獲取網頁標題
        @Override
        public void onReceivedTitle(WebView view, String title) {
            super.onReceivedTitle(view, title);
            Log.i("ansen", "網頁標題:" + title);
        }
 
        //加載進度回調
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            // progressBar.setProgress(newProgress);
        }
    };
 
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Log.i("ansen", "是否有上一個頁面:" + webView.canGoBack());
        if (webView.canGoBack() && keyCode == KeyEvent.KEYCODE_BACK) {//點擊返回按鈕的時候判斷有沒有上一頁
            webView.goBack(); // goBack()表示返回webView的上一頁面
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
 
    /**
     * JS調用android的方法
     *
     * @param str
     * @return
     */
    @JavascriptInterface //仍然必不可少
    public void getClient(String str) {
        Log.i("ansen", "html調用客戶端:" + str);
    }
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
 
        //釋放資源
        webView.destroy();
        webView = null;
    }
相關文章
相關標籤/搜索