android---WebView实例

news2024/11/17 11:31:27

        现在很多 App 里都内置了 Web 网页,比如电商平台淘宝、京东等。那么这种该如何实现呢?其实这是 Android 里一个叫 WebView 的组件实现的。下面将介绍 WebView 的实例。下面的实例是以组件化为基础搭建的。

新建项目 WebView,然后对整个项目做统一的版本管理。在 project 下的 build.gradle 里添加如下代码。

 修改 app 下的build.gradle 代码如下,即将统一管理的版本引进来,同时添加对 viewBinding 的使用。使用 viewBinding 就是为了避免繁琐的 findViewById() 操作

添加 WebView module模块,用来实现 WebView 相关功能。File --> new --> new module --> Android Library

 对 WebView 模块的 build.gradle 做与 app 模块相同的版本管理,并添加 viewBinding。

添加网络访问权限

这是前提!在WebView 模块里的 AndroidManifest.xml 里添加访问网络的权限。

<uses-permission android:name="android.permission.INTERNET"/>

在 WebView 模块里新建 WebViewActivity.java,然后对应的 xml 布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".WebViewActivity">

    <WebView
        android:id="@+id/web_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

WebViewActivity,java 主要实现网页的打开,这里以 https://www.baidu.com 练习。代码如下

public class WebViewActivity extends AppCompatActivity {

    private ActivityWebViewBinding mBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = ActivityWebViewBinding.inflate(LayoutInflater.from(this));
        setContentView(mBinding.getRoot());
        //TODO 设置可以与 JS 交互,因为百度网页代码是有js代码的
        mBinding.webView.getSettings().setJavaScriptEnabled(true);
        // LoadUrl 打开对应网址的内容
        mBinding.webView.loadUrl("https://www.baidu.com");
    }
}

注意:这里的网址以https开头的,如果是http的话,需要在 WebView模块的 AndroidManifest.xml 里添加 android:usesCleartextTraffic="true"。

 app 模块下的 MainActivity.java 主要实现点击跳转到 WebViewActivity 的功能。

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding mBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = ActivityMainBinding.inflate(LayoutInflater.from(this));
        setContentView(mBinding.getRoot());

        mBinding.openWebView.setOnClickListener(v -> {
            startActivity(new Intent(this, WebViewActivity.class));
        });
    }
}

注意:MainActivity.java 与 WebViewActivity.java 是位于两个 module 下的 java 代码,是不能直接调用的。要在 app 模块里的 MainActivity 里调用 WebView 模块里的 WebViewActivity,需要在 app 模块的 build.gradle 里添加 api project(":WebView"),添加对 WebView 模块的引用。

 到此,通过上面的代码,我们就简单的实现了通过 WebView 打开网页的功能!

        我们要通过组件化实现上面的功能,上面 MainActivity 中的调用明显不是组件化,且也不能这么写代码。WebView模块是一个单独的组件,而组件之间是互不交互的,所以要通过组件间通信来完成。常见的组件间通信有 arouter、cc 以及 auto service,我们这里将使用 auto service 来完成。

 

使用 auto service 我们首先要加入一个依赖。

在 project 下的 build.gradle 里添加如下代码

googleAutoServiceDependency ='com.google.auto.service:auto-service:1.0.1'

 在 WebView 模块的 build.dradle 里添加如下代码,把 auto service 加上

annotationProcessor rootProject.googleAutoServiceDependency
implementation rootProject.googleAutoServiceDependency

 要满足组件化的需求,WebView 里打开网页的操作我们要给其它组件或者 app 模块使用,所以我们要在 common 层写一个接口,然后在 WebView 模块把这个接口实现,其它组件就能通过 common 层的接口在 WebView 模块中找到实现,这种方法称为接口下沉。

我们新建一个 moduel 为 common,并修改版本操作。

 然后创建一个 IWebViewInterface 的接口

public interface IWebViewInterface {
    void startWebViewActivity(Context context, String url, String title);
    
}

在 WebView 模块中,创建一个 WebViewserviceImpl.java 来实现 IWebViewInterface 接口,实现到 WebViewActivity 的跳转。

在 WebView 模块中的build.gradle 里添加对 common 层的依赖。

api project(":common")

 WebViewserviceImpl.java 的代码如下。Constants 是一个存放静态常量的类。

//TODO 添加注解,说明 WebViewServiceImpl 实现了 IWebViewService 接口的
@AutoService(IWebViewInterface.class)
public class WebViewserviceImpl implements IWebViewInterface {
    @Override
    public void startWebViewActivity(Context context, String url, String title) {
        Intent intent = new Intent(context, WebViewActivity.class);
        intent.putExtra(Constants.URL, url);
        intent.putExtra(Constants.TITLE, title);

        context.startActivity(intent);
    }
}

最后,在 app 模块完成对IWebViewInterface 接口的调用,app 模块也要用到 auto service,所以也要添加依赖:

annotationProcessor rootProject.googleAutoServiceDependency
implementation rootProject.googleAutoServiceDependency

 MainActivity.java 的代码修改如下

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding mBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = ActivityMainBinding.inflate(LayoutInflater.from(this));
        setContentView(mBinding.getRoot());

        mBinding.openWebView.setOnClickListener(v -> {
            //startActivity(new Intent(this, WebViewActivity.class));
            // TODO 使用 auto service 完成跳转
            IWebViewInterface iWebViewInterface = ServiceLoader.load(IWebViewInterface.class).iterator().next();
            if (iWebViewInterface != null) {
                iWebViewInterface.startWebViewActivity(this, "https://www.baidu.com", "百度");
            }
        });
    }
}

上面代码里的 ServiceLoader.load(IWebViewInterface.class).iterator().next(); 这一句可以包装一下,应该放到 base 层,所以我们又要新建一个 base module,来完成对这句代码的封装。

同样对 base 模块下的 build.gradle 也进行统一的版本管理

在 base 层新建 AutoServiceLoader.java 实现对  ServiceLoader.load(IWebViewInterface.class).iterator().next() 的封装

public class AutoServiceLoader {
    // 其它类是不能 new 的
    private AutoServiceLoader(){

    }

    // 泛型方法 TODO 传进来的是 S 类 , 返回去的还是 S 类
    public static <S> S load(Class<S> service){
        try {
            return ServiceLoader.load(service).iterator().next();
        }catch (Exception e){
            return null;
        }
    }
}

 在 common 层的build.gradle 里添加对 base 层的依赖

api project(":base")

以 api 添加的模块之间的依赖是向下传递的,即 app 中依赖 WebView, WebView 中依赖 common, common 中依赖 base,那么 app 中就能依赖到 common 和 base。所以 app 模块中的 MainActivity 就能调用 base 层的 AutoServiceLoader 类。

修改 MainActivity.java 里的代码如下

 至此,我们通过组件化完成了 WebView 的使用了!

完成 Demo

链接:https://pan.baidu.com/s/1B09-JNuqlDyoh3FB4BXbRw 
提取码:gxpb

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/339470.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络安全攻防中,Rock-ON自动化的多功能网络侦查工具,Burpsuite被动扫描流量转发

网络安全攻防中&#xff0c;Rock-ON自动化的多功能网络侦查工具&#xff0c;Burpsuite被动扫描流量转发。 #################### 免责声明&#xff1a;工具本身并无好坏&#xff0c;希望大家以遵守《网络安全法》相关法律为前提来使用该工具&#xff0c;支持研究学习&#xff…

linux003之远程操作

Xshell简介&#xff1a; Xshell 是一个强大的安全终端模拟软件&#xff0c;它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET 协议。Xshell 通过互联网到远程主机&#xff0c;可以操控到linux服务器。  Xshell可以在Windows界面下用来访问远端不同系统下的服务器&#…

一些常见错误

500状态码: 代表服务器业务代码出错, 也就是执行controller里面的某个方法的过程中报错, 此时在IDEA的控制台中会显示具体的错误信息, 所以需要去看IDEA控制台的报错404状态码: 找不到资源找不到静态资源 检查请求地址是否拼写错误 检查静态资源的位置是否正确 如果以上都没有问…

Docker中安装Oracle-12c

前言 MySQL和Oracle是开发中常用到的两个关系型数据库管理系统&#xff0c;接上一期内容&#xff0c;这一期在Docker中完成oracle-12c的安装和配置。 安装oracle-12c 1、拉取oracle-12c镜像 启动Docker Desktop后在cmd窗口中执行docker search oracle命令&#xff0c;搜索O…

LeetCode-1138. 字母板上的路径【哈希表,字符串】

LeetCode-1138. 字母板上的路径【哈希表&#xff0c;字符串】题目描述&#xff1a;解题思路一&#xff1a;首先考虑坐标位置&#xff0c;字符是有序的从0开始&#xff0c;当前字符c的行为(c-a)/5,列为(c-a)%5。其次是考虑特殊情况z。若当前从‘z’开始则只能往上走;若是其他字符…

Spring MVC 之返回数据(静态页面、非静态页面、JSON对象、请求转发与请求重定向)

文章目录1. 默认情况下返回静态页面2. 返回一个非静态页面的数据2.1 ResponseBody 返回页面内容2.2 RestController ResponseBody Controller3. 实现登录功能&#xff0c;返回 JSON 对象3.1 前端使⽤ ajax&#xff0c;后端返回 json 给前端3.2 前端发送 JSON 的标准格式4. 请…

ChatGPT 怎么用最新详细教程一看就会

ChatGPT 以其强大的信息整合和对话能力惊艳了全球&#xff0c;在自然语言处理上面表现出了惊人的能力。这么强大的工具我们都想体验一下&#xff0c;那么 ChatGPT 怎么用呢&#xff1f;本文将给你逐步详细介绍。 使用 ChatGPT 主要有4步&#xff1a; 注册 ChatGPT 账号通过短…

Maven_第五章 核心概念

目录第五章 其他核心概念1、生命周期①作用②三个生命周期③特点2、插件和目标①插件②目标3、仓库第五章 其他核心概念 1、生命周期 ①作用 为了让构建过程自动化完成&#xff0c;Maven 设定了三个生命周期&#xff0c;生命周期中的每一个环节对应构建过程中的一个操作。 …

智慧办公管理系统

随着大数据、物联网和新一代通讯技术的发展&#xff0c;智慧地球、智慧城市、智慧办公正在逐步变成现实。 智慧办公管理系统主要分为会议室管理、考勤管理以及系统设置三部分功能。 架构图&#xff1a; 功能介绍 一、会议室管理 &#xff08;1&#xff09;、会议室信息 会议室…

如何将 Windows 11/10 许可证转移到另一台 PC

如果您最近购买了新的台式机或笔记本电脑&#xff0c;您可能希望在上面安装 Windows 11。对于某些用户来说&#xff0c;为新计算机购买新的 Windows 11 许可证可能会有点贵。 但是&#xff0c;如果您在旧计算机上安装了 Windows 11 并购买了一台新计算机来替换它&#xff0c;您…

JavaSE-线程池(1)- 线程池概念

JavaSE-线程池&#xff08;1&#xff09;- 线程池概念 前提 使用多线程可以并发处理任务&#xff0c;提高程序执行效率。但同时创建和销毁线程会消耗操作系统资源&#xff0c;虽然java 使用线程的方式有多种&#xff0c;但是在实际使用过程中并不建议使用 new Thread 的方式手…

【c++】数据类型

文章目录整型实型科学计数法sizeof关键字字符型字符串类型转义字符bool布尔类型c规定在创建一个变量或者常量时&#xff0c;必须要指定出相应的数据类型&#xff0c;否则无法给变量分配内存。 整型 作用&#xff1a;整型变量表示的是整数类型的数据。 实型 float f3.14; //默…

JavaCollection集合

5 Collection集合 5.1 Collection集合概述 是单列集合的顶层接口&#xff0c;它表示一组对象&#xff0c;这些对象也称Collection元素JDK不提供此接口的直接实现&#xff0c;它提供更具体的子接口&#xff08;Set 和 List&#xff09;实现 package ceshi;import java.util.A…

【C++1】函数重载,类和对象,引用,/string类,vector容器,类继承和多态,/socket,进程信号

文章目录1.函数重载&#xff1a;writetofile()&#xff0c;Ctrue和false&#xff0c;C0和非02.类和对象&#xff1a;vprintf构造函数&#xff1a;对成员变量初始化析构函数&#xff1a;一个类只有一个&#xff0c;不允许被重载3.引用&#xff1a;C中&取地址&#xff0c;C中…

C语言深度剖析之文件操作

&#x1f497; &#x1f497; 博客:小怡同学 &#x1f497; &#x1f497; 个人简介:编程小萌新 &#x1f497; &#x1f497; 如果博客对大家有用的话&#xff0c;请点赞关注加关注 &#x1f31e; 什么是文件 磁盘上的文件是文件。 但是在程序设计中&#xff0c;我们一般谈的文…

计算机组成原理(四)

1.理解存储器的分类方法&#xff1b;理解存储器的层次结构&#xff1b;熟悉存储器的几个技术指标&#xff08;主要是存储容量、存取时间、存取周期、存储器带宽等&#xff09;&#xff1b; 存储器分类方法&#xff1a;   按与CPU的连接和功能分类&#xff1a;     主存储…

关于HLS直播Buffer PlayQueue多图分析

文章目录前言hls配置m3u8单码流1.开始进入播放页&#xff0c;默认是暂停态2.等几十秒后的状态3.开始播放后的状态其他多码流前言 hls配置 backBufferLength:60 // 默认无限制 缓存媒体播放后要保留的最长持续时间&#xff08;以秒为单位&#xff09;。 liveSyncDurationCount…

【优化算法1】模拟退火算法(含MATLAB实例)

模拟退火算法&#xff08;含MATLAB实例&#xff09;模拟退火算法1.1 简介1.2 原理1.3 MATLAB实例模拟退火算法 1.1 简介 模拟退火算法的思想借鉴于物体退火过程&#xff1a;当温度很高时&#xff0c;物体内能比较大&#xff0c;其内部粒子处于快速无序运动状态&#xff1b;当…

【计算机网络期末复习】第一章 概述

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4e3;专栏定位&#xff1a;为想复习学校计算机网络课程的同学提供重点大纲&#xff0c;帮助大家渡过期末考~ &#x1f4da;专栏地址&#xff1a; ❤️如果有收获的话&#xff0c;欢迎点…

第一个C语言代码(visual studin创建调试以及项目文件功能讲解)

这里我主要使用visual Studio进行编程 目录 一.创建项目 二.编写代码 1.代码编写 2.代码分析 3.main() 4.注释符 5.{} 花括号 6.声明 7.赋值 8.printf()函数 9.return 0; 一.创建项目 这里大家可能会比较疑惑&#xff0c;为啥都是C&#xff0c;没看见C的项目&…