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

来源:https://www.cnblogs.com/35youth/archive/2020/03/25/12565001.html

商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。 For commercial use, please contact the author for authorization. For non commercial use, please indicate the source. 協議(Lice ...


商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

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;
}
	```

您的分享是我們最大的動力!

更多相關文章
  • 上一篇介紹了邏輯備份工具mysqldump,本文將通過應用更為普遍的物理備份工具xtrabackup來演示數據備份及恢復的第二篇內容。 1. xtrabackup 工具的安裝 1.1 安裝依賴包 /* xtrabackup 的使用需要安裝相關的依賴包 否則使用過程中會報相關錯誤 */ yum ins ...
  • MySQL 字元串截取函數:left(), right(), substring(), substring_index()。還有 mid(), substr()。 其中,mid(), substr() 等價於 substring() 函數,substring() 的功能非常強大和靈活。 1. 字元串 ...
  • MySQL資料庫 前言: 隨著時代的進步,大數據也逐漸走進大家的生活中,成為大家密不可分的一樣東西。因此,作為程式員的我們,要學習並會使用資料庫。 什麼是資料庫? 資料庫就是一個文件系統,通過標準的SQL語句獲取數據 MySQL資料庫又是什麼呢? MySQL資料庫是一個關係型資料庫。 (關係型資料庫 ...
  • 7.關於pyinstaller打包生成exe的方法 安裝pip 、 pyinstaller 在pycharm 的Terminal視窗中輸入 註:輸入參數的含義 F 表示生成單個可執行文件 w 表示去掉控制台視窗,這在GUI界面時非常有用。不過如果是命令行程式的話那就把這個選項刪除吧! p 表示你自己 ...
  • 經常提到資料庫的事務,那你知道資料庫還有事務隔離的說法嗎,事務隔離還有隔離級別,那什麼是事務隔離,隔離級別又是什麼呢?本文就幫大家梳理一下。 MySQL 事務 本文所說的 MySQL 事務都是指在 InnoDB 引擎下,MyISAM 引擎是不支持事務的。 資料庫事務指的是一組數據操作,事務內的操作要 ...
  • 不適配深色模式 直接在info新加一個欄位 設置值為 適配深色模式 適配深色模式info裡面的那個欄位就不用添加了 但是需要在每個 裡面增加下麵的這個方法 在這個方法里去判斷和更改當前界面所有元素的顏色 我專門做了一個單例,把應用程式中的所有顏色都單獨保存起來 還有兩個方法,分別是把所有的顏色改成與 ...
  • 1.win10安裝ubuntu 18.04或Ubuntu發行版 搜索:Microsoft Store >搜索:Ubuntu //下載即可 >下載完之後安裝,啟動即可. 搜索:ubuntu啟動即可. 註意:源最好不要替換 2.安裝所需的庫 安裝emacs的cscope + autocomplete需要 ...
  • 本文旨在成為iOS動畫的入門讀物,目的是詳盡地介紹不同的實現方法。 鑒於該主題的廣泛性,我們將在相當高的層次上簡潔地涵蓋每個部分。這樣做的目的是通過一組選項來教育讀者將動畫添加到他/她的iOS應用程式中。 在我們開始討論與IOS相關的主題之前,讓我們先簡單地看一看動畫的速度。 60 Fps動畫 通常 ...
一周排行
  • 上一篇文章(https://www.cnblogs.com/meowv/p/12943699.html)完成了項目的全局異常處理和日誌記錄。 在日誌記錄中使用的靜態方法有人指出寫法不是很優雅,遂優化一下上一篇中日誌記錄的方法,具體操作如下: 在.ToolKits層中新建擴展方法Log4NetExte ...
  • 先安裝幾個包 獲取地址如下https://www.nuget.org/packages/QRCoder/https://www.nuget.org/packages/SixLabors.Fonts/https://www.nuget.org/packages/SixLabors.ImageSharp ...
  • 0. 前言 前一篇我們詳細的介紹了SqlSugar的增刪改查,那些已經滿足我們在日常工程開發中的使用了。但是還有一點點在開發中並不常用,但是卻非常有用的方法。接下來讓我們一起來看看還有哪些有意思的內容。 1. 不同尋常的查詢 之前介紹了針對單個表的查詢,同樣也是相對簡單的查詢模式。雖然開發完全夠用, ...
  • 最新.net core 圖片合併生成二維碼合成圖片 圖片添加文字 先安裝幾個包 獲取地址如下 https://www.nuget.org/packages/QRCoder/ https://www.nuget.org/packages/SixLabors.Fonts/ https://www.nug ...
  • 前言 之前我寫過一篇關於 Blazor WebAssembly 的文章瀏覽器中的 .Net Core —— Blazor WebAssembly 初體驗,如今已經更新到 RC-1,與預覽版有著較大的差異,為此補充這篇文章。 正文 與預覽版的主要差異 1、這次的候選版修改了大部分包名和命名空間,因此無 ...
  • 藍牙設置相關界面,以下是通過C#方式打開的幾個方式,記錄一下 藍牙設置界面 1.控制面板命令bthprops.cpl 可以用控制面板 control+bthprops.cpl,也可以直接bthprops.cpl。更多的命令見:所有運行命令指令大全、CMD & CPL:快捷系統命令和控制面板命令 bt ...
  • 一:背景 1. 講故事 去年阿裡聚石塔上的所有isv簡訊通道全部對接阿裡通信,我們就做了對接改造,使用阿裡提供的.net sdk。 網址:https://help.aliyun.com/document_detail/114480.html 同事當時使用的是ons-.net v1.1.3版本,程式上 ...
  • 一.相關介紹 Dockerfile:關於Dockerfile的使用說明,我在文章《讓.NetCore程式跑在任何有docker的地方》中有說到,這裡不在贅述,需要的可以先看下,本文主要介紹Jenkinsfile結合dockerfile配合使用,自動構建.NetCore應用程式。 Jenkinsfil ...
  • 當用戶嚮應用程式發出請求時,伺服器將解析該請求,生成響應,然後將結果發送給客戶端。用戶可能會在伺服器處理請求的時候中止請求。就比如說用戶跳轉到另一個頁面中獲取說關閉頁面。在這種情況下,我們希望停止所有正在進行的工作,以浪費不必要的資源。例如我們可能要取消SQL請求、http調用請求、CPU密集型操作 ...
  • 在.NET中,我們可以通過Task.WhenAll用來等待多個任務。任務完成之後,我們可以使用await等待他們來獲取結果。 Task<int> task1 = Task.Run(() => 1); Task<string> task2 = Task.Run(() => "hello"); awai ...