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動畫 通常 ...
一周排行
  • 一、引言 按照專用隊列解釋: MachineName\Private$\QueueName,只針對於本機的程式才可以調用的隊列,有些情況下為了安全起見定義為私有隊列。所以剛開始的時候認為,要想訪問遠程消息隊列,只能使用公共隊列。但是後來發現,公共隊列依賴Domain Controller(域控),在 ...
  • 本文只對api介面,header請求參數進行簡單驗證,起到拋磚引玉使用,需要深入驗證,請自行擴展 項目目錄結構如圖 中間件類 using ApiMiddleware.Common.DataEnityModel; using ApiMiddleware.Common.DbContext; using ...
  • 前言:由於公司占時沒有運維,出於微服務的需要,Apollo只能先裝在windows 阿裡雲上跑起來,由於環境及網路等問題,在安裝過程中遇到很多坑,算是一個個坑填完後,最終實現。 一. java jdk環境 java jdk 1.8下載地址: https://www.oracle.com/java/t ...
  • 前言 nuget 是 .net 的常用包管理器,目前已經內置到 Visual Studio 2012 以後的版本。大多數 .net 包都托管在 nuget.org,包括 .net core 框架基礎包,得益於 .net core 的模塊化設計,很多非核心包都可以進行一定程度的獨立升級。 製作並上傳 ...
  • 簡單的介紹一下集合,通俗來講就是用來保管多個數據的方案。比如說我們是一個公司的倉庫管理,公司有一堆貨物需要管理,有同類的,有不同類的,總而言之就是很多、很亂。我們對照集合的概念對倉庫進行管理的話,那麼 數組就是將一堆貨整整齊齊的碼在倉庫的某個地方,普通列表也是如此;Set就是在倉庫里有這麼一個貨架, ...
  • 中間件分類 ASP.NET Core 中間件的配置方法可以分為以上三種,對應的Helper方法分別是:Run(), Use(), Map()。 Run(),使用Run調用中間件的時候,會直接返回一個響應,所以後續的中間件將不會被執行了。 Use(),它會對請求做一些工作或處理,例如添加一些請求的上下 ...
  • 字元串的常用操作 很好理解 字元串可以用 ' + ' 連接,或者乘一個常數重覆輸出字元串 字元串的索引操作 通過一對中括弧可以找到字元串中的某個字元 可以通過正負數雙向操作噢 用一個中括弧來實現 為什麼沒有-0??去清醒腦子想想 -0 和 0 有差嗎? 還有一個切片操作 就像切菜那樣簡單,同樣是中括 ...
  • title: Java基礎語法(3) 運算符 blog: "CSDN" data: "Java學習路線及視頻" 1.算術運算符 算術運算符的註意問題 如果對負數取模,可以把模數負號忽略不記,如:5% 2=1。 但被模數是負數則不可忽略。此外,取模運算的結果不一定總是整數。 對於除號“/”,它的整數除 ...
  • 下麵是互相轉換的代碼: 有想要瞭解更多關於python知識的請在下方評論或私信小編 ...
  • 引言 構建分散式系統並不容易。然而,人們日常所使用的應用大多基於分散式系統,在短時間內依賴於分散式系統的現狀並不會改變。ApacheZooKeeper旨在減輕構建健壯的分散式系統的任務。ZooKeeper基於 分散式計算的核心概念而設計,主要目的是給開發人員提供一套容易理解和開發的介面,從而簡化分佈 ...
x