专栏首页菜鸟小栈用安卓 WebView 做一个“套壳”应用

用安卓 WebView 做一个“套壳”应用

前言

目前手机应用市场上的 APP 类型主要为以下两种:

  • Native App(原生应用):直接针对平台(Android、iOS 等手机系统)进行开发,属于性能最优的方案,也是开发成本最大的方案。
  • Hybrid App(混合应用):即为原生 WebView 加 HTML5 网页内容的形式。只需要开发一套 HTML5 业务逻辑,就可以同时运行在不同的平台上,相对比较灵活,内容可以快速更新,开发维护成本较低。最大的缺点就是性能远不及原生应用,交互上也做不到原生的那么自然。

React Native 和 Weex 之类的框架不是本文讨论的主题,这里就不展开了。

本文主要讲解如何制作一个安卓原生的“壳”来加载我们的 H5 网页,最终实现一个简单的 Hybrid App(套壳应用)。

文中创建的示例项目已上传至码云,点击文章底部“阅读原文”即可获取

正文

本文不涉及到复杂的 Android 与 Java 知识,小朋友不需要在家长的陪同下也能观看 ?

1. 创建安卓项目

创建安卓项目需要用到 Android Studio,关于如何安装 Android Studio 可以阅读官方文档。 安装 Android Studio:https://developer.android.com/studio/install

1.1 创建新项目

首先打开 Android Studio,点击 「Start a new Android Studio Project(创建一个新的 AS 项目)」

1.2 选择项目模板

项目模板这里我们选择 「Empty Activity(空白活动)」,点击 「Next(下一步)」

1.3 项目配置

来到项目配置页面,分别设置好以下选项:

  • Name:应用名
  • Package Name:包名
  • Save Location:项目保存路径
  • Language:项目使用的编程语言
  • Minimum SDK:最低兼容 SDK 版本

这里语言选择 Java(因为我没写过 Kotlin ?),而最低 SDK 则选择了 API 23(示例用随便选的 ?),配置完成后点击 「Finished(完成)」

至此我们已经完成了项目的创建,接下来让我们正式开始我们今天的主题。

2. 开发套壳程序

2.1 添加 WebView 布局

修改 「app/res/layout/activity_main.xml」 文件,去掉原有的 TextView 标签,添加一个 WebView 标签并保存。

添加的代码如下:

<!-- 展示一个 WebView -->
<WebView
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

在 Android 工程中,「app/res/layout/」 目录主要用于存放定义用户界面布局的 XML 文件。 上文提到的 activity_main.xml 即为应用主界面的布局文件。

2.2 在入口处创建 WebView 实例

选择 「app/java/{创建项目时指定的包名}/」 目录下的 「MainActivity.java」 文件(我这里是 app/java/example/webviewdemo/MainActivity.java)。

随后在 「MainActivity.java」 文件中添加一个 createWebView 函数(不要忘记导入用到的包),并在生命周期 onCreate 中调用该函数,来创建一个 WebView 实例并对其进行配置。

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();
    }

    /* 创建 WebView 实例 */
    @SuppressLint("SetJavaScriptEnabled")
    private void createWebView() {
        // 创建 WebView 实例并通过 id 绑定我们刚在布局中创建的 WebView 标签
        // 这里的 R.id.webview 就是 activity_main.xml 中的 WebView 标签的 id
        final WebView webView = (WebView) findViewById(R.id.webview);

        // 设置 WebView 允许执行 JavaScript 脚本
        webView.getSettings().setJavaScriptEnabled(true);

        // 确保跳转到另一个网页时仍然在当前 WebView 中显示
        // 而不是调用浏览器打开
        webView.setWebViewClient(new WebViewClient());

        // 加载指定网页
        String url = "https://chenpipi.cn";
        webView.loadUrl(url);
    }

}

在 Android 项目中,「app/java/」 目录主要用于存放项目的源代码。 在项目包名目录(文中项目包名为 com.example.webviewdemo)下的 MainActivity.java 文件为应用的主入口。

2.3 添加联网权限

选择 「app/minifests/AndroidMinifest.xml」 文件,在 application 标签前添加一个 uses-permission 标签来声明应用的网络访问权限,最后保存。

添加的代码如下:

<!-- 访问网络的权限 -->
<uses-permission android:name="android.permission.INTERNET" />

AndroidManifest.xml 文件用于描述应用的基本特性并定义了每个应用组件。

2.4 使用虚拟机运行应用

我们开发的时候可以随时使用模拟器来预览我们的应用,也可以将手机连接到电脑上进行调试(这里就不展开了)。 如果想要打包成 APK 文件安装到手机上运行,执行顶部菜单栏的 [ Build -> Build Bundle(s) / APK(s) -> Build APK(s) ] 即可。

调试工具栏在窗口右上方,选择或安装一个虚拟机(模拟器)。

点击绿色播放键(三角形),然后 Android Studio 会自动帮我们编译并在虚拟机 ? 中启动我们的应用。

随后可以看到我们的应用已经成功加载了 MainActivity.java 中设置好的链接 https://chenpipi.cn,计划通 ?。

如果没有安装虚拟机的话,需要点击窗口顶部菜单栏的 [ Tools -> AVD Manager ] 进入 AVD 管理器安装安卓虚拟机(模拟器)。 AVD 管理器:https://developer.android.com/studio/run/managing-avds#createavd

3. 加点料

3.1 隐藏标题栏

修改 「app/res/values/styles.xml」 文件,将 nameAppThemestyle 标签的内容换成以下代码:

<!-- 隐藏标题栏 -->
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>

修改完成后,重新预览应用发现之前骚得不行紫色标题栏已经不见啦~(希望标题栏没事 ?)

3.2 隐藏状态栏

该方案在异形屏下会有些问题,且本文将不考虑异形屏的适配。

光隐藏标题栏浏览体验还不够沉浸,得把状态栏也隐藏了,不能让用户看到时间和电量!?

修改 「MainActivity.java」 文件,在生命周期 onCreate 内调用 setContentView 函数「之前」添加以下两行代码:

// 设置为全屏(隐藏状态栏)
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

再保存看看,duang~ 状态栏也消失啦!(也希望状态栏没事 ?)

3.3 接管返回键

默认情况下,在这个只有的 WebView 应用中无论在什么页面触发返回(按键或手势)都是会直接退出应用的,当然这肯定不是我们想要的效果。

一般来说在应用中触发返回操作应该是返回到上一个浏览的页面,没有上一个页面时才会退出应用。

我们可以通过以下两种方法来修改:

  1. 修改 WebView 实例的按键监听器:
// 设置 WebView 的按键监听器,覆写监听器的 onKey 函数,对返回键作特殊处理
// 当 WebView 可以返回到上一个页面时回到上一个页面
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;
    }
});
  1. 重写当前 Activity 的 onBackPressed 函数:
private WebView webView = null;

// 创建 WebView 实例时保存到 this.webView 中

/*
 * 接管返回键
 */
@Override
public void onBackPressed() {
    if (this.webView.canGoBack()) {
        this.webView.goBack();
    } else {
        super.onBackPressed();
    }
}

3.4 支持明文传输(HTTP)

从 Android 9(API Level 28)开始「默认不支持明文传输」,在 WebView 中加载 HTTP 网页会报 net::ERR_CLEARTEXT_NOT_PERMITTED 的错误,不方便本地进行调试。

我们可以在 「AndroidMinifest.xml」 文件中的 application 标签内添加属性 android:usesCleartextTraffic="true" 以支持明文传输。

<application
    ...
    android:usesCleartextTraffic="true">

可以看到我本地的 Cocos Creator 项目已经成功在安卓的 WebView 上跑起来啦~ ?

文中创建的示例项目已上传至码云,点击文章底部“阅读原文”即可获取

相关资料

「Android 开发者」 https://developer.android.com

「文中的示例项目」 https://gitee.com/ifaswind/android-webview-demo

本文分享自微信公众号 - 菜鸟小栈(iamchenpipi),作者:文弱书生陈皮皮

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-08-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [Cocos Creator] 制作简版消消乐(二):实现基础组件和管理脚本

    在上一篇文章中我们初步建立了项目并搭建好了场景,那么本篇文章将和大家一起实现部分基础组件和管理脚本。

    陈皮皮
  • [Cocos Creator] 制作简版消消乐(六):方块下落与空位填充(完结)

    1. 方块的下落:我们从左下角第一个方块开始,向上遍历检查,发现有空位后,向上查找直到有可用的方块,将可用方块交换(做下落动画)到刚刚的空位,每一列都重复以上步...

    陈皮皮
  • 为什么选择 TypeScript

    相信经常关注前端技术的同学对 TypeScript 应该不陌生,或多或少看过一些关于 TypeScript 的文章。

    陈皮皮
  • WebView深度学习(一)之WebView的基本使用以及Android和js的交互

    //设置WebView缓存(当加载 html 页面时,WebView会在/data/data/包名目录下生成 database 与 cache 两个文件夹,请求...

    AWeiLoveAndroid
  • 混合开发之WebView秘笈

    注意: 每个 Application 只调用一次 WebSettings.setAppCachePath(),WebSettings.setAppCacheMa...

    蜻蜓队长
  • 手把手教你使用Bugly收集线上崩溃信息

    小蠢驴打代码
  • kubernetes控制器之CronJob

    一个 CronJob 对象类似于 crontab (cron table)文件中的一行。它根据指定的预定计划周期性地运行一个 Job,格式可以参考 Cron 。

    菲宇
  • 四块GPU即可训练BigGAN:「官方版」PyTorch实现出炉

    项目链接:https://github.com/ajbrock/BigGAN-PyTorch 该项目一出即引发了人们的广泛关注,有的人表示不敢相信,也有人哭晕...

    机器之心
  • 为何UI设计稿与开发出的界面有差异?设计师必读技术干货

    静电说:这是一篇技术流的干货,作者从开发者的角度给我们分析了为什么设计师在Sketch中设计出的设计稿与开发出来的效果会产生差异。不妨来读一读吧!所以,各位设计...

    用户5009027
  • pytest文档19-doctest测试框架

    doctest从字面意思上看,那就是文档测试。doctest是python里面自带的一个模块,它实际上是单元测试的一种。 官方解释:doctest 模块会搜索那...

    上海-悠悠

扫码关注云+社区

领取腾讯云代金券