用安卓 WebView 做一個(gè)Cocos Creator“套殼”應(yīng)用

前言
目前手機(jī)應(yīng)用市場(chǎng)上的 APP 類型主要為以下兩種:
Native App(原生應(yīng)用):直接針對(duì)平臺(tái)(Android、iOS 等手機(jī)系統(tǒng))進(jìn)行開發(fā),屬于性能最優(yōu)的方案,也是開發(fā)成本最大的方案。
Hybrid App(混合應(yīng)用):即為原生 WebView 加 HTML5 網(wǎng)頁內(nèi)容的形式。只需要開發(fā)一套 HTML5 業(yè)務(wù)邏輯,就可以同時(shí)運(yùn)行在不同的平臺(tái)上,相對(duì)比較靈活,內(nèi)容可以快速更新,開發(fā)維護(hù)成本較低。最大的缺點(diǎn)就是性能遠(yuǎn)不及原生應(yīng)用,交互上也做不到原生的那么自然。
React Native 和 Weex 之類的框架不是本文討論的主題,這里就不展開了。
本文主要講解如何制作一個(gè)安卓原生的“殼”來加載我們的 H5 網(wǎng)頁,最終實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 Hybrid App(套殼應(yīng)用)。
文中創(chuàng)建的示例項(xiàng)目已上傳至碼云,點(diǎn)擊文章底部“閱讀原文”即可獲取
正文
本文不涉及到復(fù)雜的 Android 與 Java 知識(shí),小朋友不需要在家長的陪同下也能觀看 ?
1. 創(chuàng)建安卓項(xiàng)目
創(chuàng)建安卓項(xiàng)目需要用到 Android Studio,關(guān)于如何安裝 Android Studio 可以閱讀官方文檔。
安裝 Android Studio:https://developer.android.com/studio/install
1.1 創(chuàng)建新項(xiàng)目
首先打開 Android Studio,點(diǎn)擊 「Start a new Android Studio Project(創(chuàng)建一個(gè)新的 AS 項(xiàng)目)」。

1.2 選擇項(xiàng)目模板
項(xiàng)目模板這里我們選擇 「Empty Activity(空白活動(dòng))」,點(diǎn)擊 「Next(下一步)」。

1.3 項(xiàng)目配置
來到項(xiàng)目配置頁面,分別設(shè)置好以下選項(xiàng):
Name:應(yīng)用名 Package Name:包名 Save Location:項(xiàng)目保存路徑 Language:項(xiàng)目使用的編程語言 Minimum SDK:最低兼容 SDK 版本
這里語言選擇 Java(因?yàn)槲覜]寫過 Kotlin ?),而最低 SDK 則選擇了 API 23(示例用隨便選的 ?),配置完成后點(diǎn)擊 「Finished(完成)」。

至此我們已經(jīng)完成了項(xiàng)目的創(chuàng)建,接下來讓我們正式開始我們今天的主題。
2. 開發(fā)套殼程序
2.1 添加 WebView 布局
修改 「app/res/layout/activity_main.xml」 文件,去掉原有的 TextView 標(biāo)簽,添加一個(gè) WebView 標(biāo)簽并保存。

添加的代碼如下:
<WebView
????android:id="@+id/webview"
????android:layout_width="match_parent"
????android:layout_height="match_parent"?/>
在 Android 工程中,「app/res/layout/」 目錄主要用于存放定義用戶界面布局的 XML 文件。
上文提到的 activity_main.xml 即為應(yīng)用主界面的布局文件。
2.2 在入口處創(chuàng)建 WebView 實(shí)例
選擇 「app/java/{創(chuàng)建項(xiàng)目時(shí)指定的包名}/」 目錄下的 「MainActivity.java」 文件(我這里是 app/java/example/webviewdemo/MainActivity.java)。
隨后在 「MainActivity.java」 文件中添加一個(gè) createWebView 函數(shù)(不要忘記導(dǎo)入用到的包),并在生命周期 onCreate 中調(diào)用該函數(shù),來創(chuàng)建一個(gè) WebView 實(shí)例并對(duì)其進(jìn)行配置。

MainActivity.java 完整代碼如下:
package?com.example.webviewdemo;
import?androidx.appcompat.app.AppCompatActivity;
import?android.annotation.SuppressLint;
import?android.os.Bundle;
import?android.webkit.WebView;
import?android.webkit.WebViewClient;
public?class?MainActivity?extends?AppCompatActivity?{
????@Override
????protected?void?onCreate(Bundle?savedInstanceState)?{
????????super.onCreate(savedInstanceState);
????????setContentView(R.layout.activity_main);
????????this.createWebView();
????}
????/*?創(chuàng)建?WebView?實(shí)例?*/
????@SuppressLint("SetJavaScriptEnabled")
????private?void?createWebView()?{
????????//?創(chuàng)建?WebView?實(shí)例并通過?id?綁定我們剛在布局中創(chuàng)建的?WebView?標(biāo)簽
????????//?這里的?R.id.webview?就是?activity_main.xml?中的?WebView?標(biāo)簽的?id
????????final?WebView?webView?=?(WebView)?findViewById(R.id.webview);
????????//?設(shè)置?WebView?允許執(zhí)行?JavaScript?腳本
????????webView.getSettings().setJavaScriptEnabled(true);
????????//?確保跳轉(zhuǎn)到另一個(gè)網(wǎng)頁時(shí)仍然在當(dāng)前?WebView?中顯示
????????//?而不是調(diào)用瀏覽器打開
????????webView.setWebViewClient(new?WebViewClient());
????????//?加載指定網(wǎng)頁
????????String?url?=?"https://chenpipi.cn";
????????webView.loadUrl(url);
????}
}
在 Android 項(xiàng)目中,「app/java/」 目錄主要用于存放項(xiàng)目的源代碼。
在項(xiàng)目包名目錄(文中項(xiàng)目包名為
com.example.webviewdemo)下的 MainActivity.java 文件為應(yīng)用的主入口。
2.3 添加聯(lián)網(wǎng)權(quán)限
選擇 「app/minifests/AndroidMinifest.xml」 文件,在 application 標(biāo)簽前添加一個(gè) uses-permission 標(biāo)簽來聲明應(yīng)用的網(wǎng)絡(luò)訪問權(quán)限,最后保存。

添加的代碼如下:
<uses-permission?android:name="android.permission.INTERNET"?/>
AndroidManifest.xml 文件用于描述應(yīng)用的基本特性并定義了每個(gè)應(yīng)用組件。
2.4 使用虛擬機(jī)運(yùn)行應(yīng)用
我們開發(fā)的時(shí)候可以隨時(shí)使用模擬器來預(yù)覽我們的應(yīng)用,也可以將手機(jī)連接到電腦上進(jìn)行調(diào)試(這里就不展開了)。
如果想要打包成 APK 文件安裝到手機(jī)上運(yùn)行,執(zhí)行頂部菜單欄的 [ Build -> Build Bundle(s) / APK(s) -> Build APK(s) ] 即可。
調(diào)試工具欄在窗口右上方,選擇或安裝一個(gè)虛擬機(jī)(模擬器)。

點(diǎn)擊綠色播放鍵(三角形),然后 Android Studio 會(huì)自動(dòng)幫我們編譯并在虛擬機(jī) ? 中啟動(dòng)我們的應(yīng)用。
隨后可以看到我們的應(yīng)用已經(jīng)成功加載了 MainActivity.java 中設(shè)置好的鏈接 https://chenpipi.cn,計(jì)劃通 ?。

如果沒有安裝虛擬機(jī)的話,需要點(diǎn)擊窗口頂部菜單欄的 [ Tools -> AVD Manager ] 進(jìn)入 AVD 管理器安裝安卓虛擬機(jī)(模擬器)。
AVD 管理器:https://developer.android.com/studio/run/managing-avds#createavd
3. 加點(diǎn)料
3.1 隱藏標(biāo)題欄
修改 「app/res/values/styles.xml」 文件,將 name 為 AppTheme 的 style 標(biāo)簽的內(nèi)容換成以下代碼:
<item?name="windowNoTitle">trueitem>
<item?name="windowActionBar">falseitem>
修改完成后,重新預(yù)覽應(yīng)用發(fā)現(xiàn)之前騷得不行紫色標(biāo)題欄已經(jīng)不見啦~(希望標(biāo)題欄沒事 ?)

3.2 隱藏狀態(tài)欄
該方案在異形屏下會(huì)有些問題,且本文將不考慮異形屏的適配。
光隱藏標(biāo)題欄瀏覽體驗(yàn)還不夠沉浸,得把狀態(tài)欄也隱藏了,不能讓用戶看到時(shí)間和電量!?
修改 「MainActivity.java」 文件,在生命周期 onCreate 內(nèi)調(diào)用 setContentView 函數(shù)「之前」添加以下兩行代碼:
//?設(shè)置為全屏(隱藏狀態(tài)欄)
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,?WindowManager.LayoutParams.FLAG_FULLSCREEN);
再保存看看,duang~ 狀態(tài)欄也消失啦!(也希望狀態(tài)欄沒事 ?)

3.3 接管返回鍵
默認(rèn)情況下,在這個(gè)只有的 WebView 應(yīng)用中無論在什么頁面觸發(fā)返回(按鍵或手勢(shì))都是會(huì)直接退出應(yīng)用的,當(dāng)然這肯定不是我們想要的效果。
一般來說在應(yīng)用中觸發(fā)返回操作應(yīng)該是返回到上一個(gè)瀏覽的頁面,沒有上一個(gè)頁面時(shí)才會(huì)退出應(yīng)用。
我們可以通過以下兩種方法來修改:
修改 WebView 實(shí)例的按鍵監(jiān)聽器:
//?設(shè)置?WebView?的按鍵監(jiān)聽器,覆寫監(jiān)聽器的?onKey?函數(shù),對(duì)返回鍵作特殊處理
//?當(dāng)?WebView?可以返回到上一個(gè)頁面時(shí)回到上一個(gè)頁面
webView.setOnKeyListener(new?View.OnKeyListener()?{
????@Override
????public?boolean?onKey(View?v,?int?keyCode,?KeyEvent?event)?{
????????if?(keyCode?==?KeyEvent.KEYCODE_BACK?&&?webView.canGoBack())?{
????????????webView.goBack();
????????????return?true;
????????}
????????return?false;
????}
});
重寫當(dāng)前 Activity 的 onBackPressed函數(shù):
private?WebView?webView?=?null;
//?創(chuàng)建?WebView?實(shí)例時(shí)保存到?this.webView?中
/*
?*?接管返回鍵
?*/
@Override
public?void?onBackPressed()?{
????if?(this.webView.canGoBack())?{
????????this.webView.goBack();
????}?else?{
????????super.onBackPressed();
????}
}
3.4 支持明文傳輸(HTTP)
從 Android 9(API Level 28)開始「默認(rèn)不支持明文傳輸」,在 WebView 中加載 HTTP 網(wǎng)頁會(huì)報(bào) net::ERR_CLEARTEXT_NOT_PERMITTED 的錯(cuò)誤,不方便本地進(jìn)行調(diào)試。
我們可以在 「AndroidMinifest.xml」 文件中的 application 標(biāo)簽內(nèi)添加屬性 android:usesCleartextTraffic="true" 以支持明文傳輸。
<application
????...
????android:usesCleartextTraffic="true">
可以看到我本地的 Cocos Creator 項(xiàng)目已經(jīng)成功在安卓的 WebView 上跑起來啦~ ?

文中創(chuàng)建的示例項(xiàng)目已上傳至碼云,點(diǎn)擊文章底部“閱讀原文”即可獲取
相關(guān)資料
「Android 開發(fā)者」
https://developer.android.com
「文中的示例項(xiàng)目」
https://gitee.com/ifaswind/android-webview-demo
