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的應用。
1、配置網絡連接權限

在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_PERMITTED

android:usesCleartextTraffic="true"

webview 網絡配置異常
net::ERR_CLEARTEXT_NOT_PERMITTED 配置
2、創建layout文件
使用idea的話,會自動創建MainActivity和對應的layout文件,直接在文件的基礎上修改即可,使用Webview控件,如果需要使用進度條的話,可以將ProgressBar 的配置打開即可。

<?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>

3、修改 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
    }
		```
配置WebviewClient
//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;
}
	```


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM