iis服务器助手广告
返回顶部
首页 > 资讯 > 移动开发 >Android使用WebView实现离线阅读功能
  • 560
分享到

Android使用WebView实现离线阅读功能

2024-04-02 19:04:59 560人浏览 泡泡鱼
摘要

目录1、先看效果图,加载动画:2、使用实现3、进度提示1、先看效果图,加载动画: 加载完成,注意当前为飞行模式! 2、使用 1)、让你的javabean实现OffLineLeve

1、先看效果图,加载动画:

加载完成,注意当前为飞行模式!

2、使用

1)、让你的javabean实现OffLineLevelItem接口,因为我的这个离线阅读支持多级下载,比如Demo中的每个频道下面的第一页item都可以缓存


package com.zgh.offlinereader;

import java.util.List;

public interface OffLineLevelItem  {
    //是否有下一级
    boolean haveNextLevel();
    //内容url
    String getWEBUrl();
    //下一级的url
    String getNextLevelListUrl();
    //生成下一级
    List<OffLineLevelItem> getNextLevelList(String JSONStr);
}

public class Channel implements OffLineLevelItem {
    String title;
    String url;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    @Override
    public boolean haveNextLevel() {
        return true;
    }

    @Override
    public String getWebUrl() {
        return null;
    }

    @Override
    public String getNextLevelListUrl() {
        return url;
    }

    @Override
    public List<OffLineLevelItem> getNextLevelList(String jsonStr) {
        List<OffLineLevelItem> items = GsonUtil.jsonToBeanList(jsonStr, NewsItem.class);
        return items;
    }
}

2)、初始化


OfflineReaderServer.init(this, getCacheDir(), new MyFirstLevel(),new WaterWaveProgressUI(this));

3)、启动


 @Override
    public void onClick(View v) {
        Intent intent=new Intent(this, OfflineReaderServer.class);
        startService(intent);
    }

4)、记得在你的webview使用前调用


    //设置缓存目录
    WebViewHelper.setWebViewConfig(webView);

就这么简单!

实现

首先我们为什么要使用webview实现离线阅读,因为简单。webview自带的缓存机制可以实现图片,js,CSS的缓存。不然你自己得实现数据库html下载,js下载,css保存,html的拼装。下面我将讲解一些webview设置缓存,实现多级下载,webview遍历url,webview显示完成监听。

1.WebView设置缓存

这一部分比较简单,主要是缓存目录的设置,然后设置缓存模式为:


WebSettings.LOAD_CACHE_ELSE_NETWORK

这种模式下webview会优先加载本地缓存,如果没有缓存的话再加载网络


        mWebView.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
        // 建议缓存策略为,判断是否有网络,有的话,使用LOAD_DEFAULT,无网络时,使用LOAD_CACHE_ELSE_NETWORK

        mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); // 设置缓存模式
        // 开启DOM storage api 功能
        mWebView.getSettings().setDomStorageEnabled(true);
        // 开启database storage API功能
        mWebView.getSettings().setDatabaseEnabled(true);
        // String cacheDirPath = getFilesDir().getAbsolutePath()
        //         + APP_CACHE_DIRNAME;
        String cacheDirPath = ConfigUtil.getCacheDir()
                + APP_CACHE_DIRNAME;
        Log.i(TAG, "cachePath=" + cacheDirPath);
        // 设置数据库缓存路径
        mWebView.getSettings().setDatabasePath(cacheDirPath); // API 19 deprecated
        // 设置Application caches缓存目录
        mWebView.getSettings().setAppCachePath(cacheDirPath);
        // 开启Application Cache功能
        mWebView.getSettings().setAppCacheEnabled(true);
        mWebView.getSettings().setAppCacheMaxSize(MAX_SIZE);

2.多级缓存

我的项目中需要将每个频道的首页中的每个item都缓存下来,所以涉及到多级缓存于是我设计了一个接口在离线阅读的时候最重要的是拿到叶子节点也就是每个item的url地址,如果是每叶子节点也就是haveNextLevel()返回true的时候就调用getNextLevelListUrl获取下一级的url,一般都是Jason字符串,再把json字符串传入getNextLevelList()方法获取下一级,如果到达叶子节点,则调用getWebUrl()获取url地址保存在一个集合中,当所有的url都获取以后,就开始用webview遍历url实现缓存。


public interface OffLineLevelItem  {
    //是否有下一级
    boolean haveNextLevel();
    //内容url
    String getWebUrl();
    //下一级的url
    String getNextLevelListUrl();
    //生成下一级
    List<OffLineLevelItem> getNextLevelList(String jsonStr);
}

频道的javabean


public class Channel implements OffLineLevelItem {
    String title;
    String url;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    @Override
    public boolean haveNextLevel() {
        return true;
    }

    @Override
    public String getWebUrl() {
        return null;
    }

    @Override
    public String getNextLevelListUrl() {
        return url;
    }

    @Override
    public List<OffLineLevelItem> getNextLevelList(String jsonStr) {
        List<OffLineLevelItem> items = GsonUtil.jsonToBeanList(jsonStr, NewsItem.class);
        return items;
    }
}

item的javabean


public class NewsItem implements OffLineLevelItem{
    String title;
    String url;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    @Override
    public String toString() {
        return title;
    }

    @Override
    public boolean haveNextLevel() {
        return false;
    }

    @Override
    public String getWebUrl() {
        return url;
    }

    @Override
    public String getNextLevelListUrl() {
        return null;
    }

    @Override
    public List<OffLineLevelItem> getNextLevelList(String jsonStr) {
        return null;
    }
}

当然为了获取到频道列表需要一个第一级的目录,而这个目录在初始化的时候就设置进去了。


public class MyFirstLevel implements OffLineLevelItem {
    @Override
    public boolean haveNextLevel() {
        return true;
    }

    @Override
    public String getWebUrl() {
        return null;
    }

    @Override
    public String getNextLevelListUrl() {
        return "raw://news_list";
    }

    @Override
    public List<OffLineLevelItem> getNextLevelList(String jsonStr) {
        List<OffLineLevelItem> items = GsonUtil.jsonToBeanList(jsonStr, Channel.class);
        return items;
    }
}

3.使用WebView遍历URL,我原来的思路是给webview设置WebViewClient然后重写onPageFinished方法,在这个方法中获取下一个需要换成的url,然后再调用webview.loadurl()结果是很多页面加载出来是空的。而且在Android4.4以上onPageFinished会调用两次

于是乎,我重写了WebView的OnDraw()方法,在OnDraw()方法里设置了一个监听回调,但是由于我的WebView是在Service中创建的所以ondraw方法根本不会调用,但是这难得的我吗?,呵呵,于是我在service的onCreat方法中使用WindowManger将webview添加到屏幕,长宽都是一个像素


   @Override
    public void onCreate() {
        super.onCreate();
        if (!haveInit) {
            throw new RuntimeException("请先调用init()方法,初始化OfflineReaderServer");
        }
        windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        params=new WindowManager.LayoutParams();
        params.type = WindowManager.LayoutParams.TYPE_TOAST;
        params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        params.gravity = Gravity.LEFT | Gravity.TOP;
        params.width = 1;
        params.height = 1;
        initWebView();
        windowManager.addView(mWebView,params);
    }

结果还是很明显的大部分的页面都能缓存下来,但是任然有部分页面是空白的,后来发现webview的OnDraw()方法会多次持续,webview的页面加载时间隙的,我通过getContentHeight()判断内容高度来实现显示完成的监听,结果任然不理想。于是我最终版是这样的



public class LoadWebView extends WebView {
    private boolean isRendered = false;
    private static final int MSG_FINISH=1;
    private static final int MIN_CONTENT_HEIGHT=1000;
    public LoadWebView(Context context) {
        this(context, null);
    }
    public LoadWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    private int contentHeight=MIN_CONTENT_HEIGHT;
    Handler handler=new Handler(Looper.getMainLooper()){
        @Override
        public void handleMessage(Message msg) {
            if(msg.what==MSG_FINISH) {
                if (finishListenter != null) {
                    finishListenter.onFinish();
                    contentHeight=MIN_CONTENT_HEIGHT;
                }
            }
        }
    };
    @Override
    protected void onDraw(canvas canvas) {
        //与上一次的contentHeight比较,如果比上一次大,说明还在加载
        if(getContentHeight()>=contentHeight){
            //更新contentHeight
            contentHeight=getContentHeight();
            //取消消息
            handler.removeMessages(MSG_FINISH);
            //延迟200ms发送,如果在200ms内webview又加载了则这条消息会被取消,知道webview加载完成,
            //这条消息会被发送,所以每离线一个页面有200ms的延迟,但是与功能相比这点是可以接受的。
            handler.sendEmptyMessageDelayed(MSG_FINISH,200);
        }
    }

    public interface OnLoadFinishListenter{
        void onFinish();
    }

    private OnLoadFinishListenter finishListenter;
    public void setFinishListenter(OnLoadFinishListenter listenter){
        finishListenter=listenter;
    }
}

3、进度提示

为了让用户知道离线的进度我抽取出了一个接口


public interface OffLineProgressUI {
    void showProgress();

    void closeProgress();

    void updateProgress(int progress);
}

并默认实现了一个水波纹的进度球

设置进度提示有两种方式,一种是在初始化的时候设置


OfflineReaderServer.init(this, getCacheDir(), new MyFirstLevel(),new WaterWaveProgressUI(this));

还有一种是调用OfflineReaderServer的setProgressUI方法


   public static void setProgressUI(@NonNull OffLineProgressUI progressUI) {
        sProgressUI = progressUI;
    }

源码地址:

https://GitHub.com/zhuguohui/OffLineReaderDem

以上就是Android使用WebView实现离线阅读功能的详细内容,更多关于Android 实现离线阅读功能的资料请关注编程网其它相关文章!

--结束END--

本文标题: Android使用WebView实现离线阅读功能

本文链接: https://www.lsjlt.com/news/123455.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android使用WebView实现离线阅读功能
    目录1、先看效果图,加载动画:2、使用实现3、进度提示1、先看效果图,加载动画: 加载完成,注意当前为飞行模式! 2、使用 1)、让你的javabean实现OffLineLeve...
    99+
    2024-04-02
  • Android怎么实现阅读进度记忆功能
    小编给大家分享一下Android怎么实现阅读进度记忆功能,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!具体内容如下用户提了一个要求,要求保存他的阅读进度,然后在他...
    99+
    2023-05-30
    android
  • android离线推送功能怎么实现
    在Android中实现离线推送功能,可以通过以下步骤来操作:1. 首先,你需要选择一个适合的推送服务提供商,这些服务提供商通常会提供...
    99+
    2023-09-28
    android
  • 在Android项目使用 WebView实现点击图片放大功能
    这篇文章将为大家详细讲解有关在Android项目使用 WebView实现点击图片放大功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。图示:项目的知识点:加载网页后如何捕捉网页中的图片点击事...
    99+
    2023-05-31
    android webview 大功
  • java怎么实现小说阅读器功能
    要实现一个简单的小说阅读器功能,你可以按照以下步骤进行: 创建一个小说类(Novel),包含属性如小说名称、作者、分类、章节列表等...
    99+
    2023-10-26
    java
  • java如何实现小说阅读器功能
    要实现一个基本的小说阅读器功能,可以考虑以下步骤:1. 创建一个图形界面,可以使用Java Swing或JavaFX来实现。界面可以...
    99+
    2023-08-25
    java
  • android实现NFC读写功能
    一、NFC是什么? 近距离无线通讯技术,这个技术由非接触式射频识别(RFID)演变而来,由飞利浦半导体(现恩智浦半导体公司)、诺基亚和索尼共同研制开发,其基础是RFID及互连技术。近...
    99+
    2024-04-02
  • 使用SpringBoot 如何实现一个MySQL 读写分离功能
    本篇文章给大家分享的是有关使用SpringBoot 如何实现一个MySQL 读写分离功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。主从同步的局限性: 这里分为主数据库和从数...
    99+
    2023-06-06
  • 使用CSS实现点击展开阅读全文功能的案例
    这篇文章主要介绍了使用CSS实现点击展开阅读全文功能的案例,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。参考了文章 caibaojian.com/css-tonggle&am...
    99+
    2023-06-08
  • UiBot离线功能的使用方法
    本篇内容主要讲解“UiBot离线功能的使用方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“UiBot离线功能的使用方法”吧!UiBot离线功能使用方法下载UiBot:https://www.u...
    99+
    2023-06-03
  • HTML5如何实现离线存储功能
    这篇文章给大家分享的是有关HTML5如何实现离线存储功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 HTML5 离线功能介绍 HTML5 是目前正在讨论的新一代 HTML...
    99+
    2024-04-02
  • 如何在Android应用中利用ADT实现一个离线下载功能
    今天就跟大家聊聊有关如何在Android应用中利用ADT实现一个离线下载功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Android ADT 离线下载操作步骤可以利用在线安装地址...
    99+
    2023-05-31
    android adt roi
  • 如何使用PHP实现微信小程序的文档阅读功能?
    如何使用PHP实现微信小程序的文档阅读功能?微信小程序是目前非常火热的一种移动应用程序,其中文档阅读功能是小程序中非常重要的一部分。本文将介绍如何使用PHP来实现微信小程序的文档阅读功能,并提供具体的代码示例。一、环境准备首先,我们需要准备...
    99+
    2023-10-27
    PHP 微信小程序 文档阅读
  • Android实现自动朗读功能(TTS)
    前言: Android提供了自动朗读支持。可以对指定文本内容进行朗读,从而发生声音;还允许把文本对应的音频录制成音频文件,方便以后播放。Android的自动朗读主要通过TextToS...
    99+
    2024-04-02
  • 如何使用PHP实现微信小程序的电子书阅读功能?
    如何使用PHP实现微信小程序的电子书阅读功能?随着移动互联网的快速发展,电子书阅读成为人们获取知识的重要途径之一。而微信小程序作为一种轻量级的应用程序,也开始在移动端的应用中扮演重要角色。本文将介绍如何使用PHP实现微信小程序的电子书阅读功...
    99+
    2023-10-27
    PHP微信小程序电子书 PHP电子书阅读功能
  • 使用Android原生WebView+Highcharts实现可左右滑动的折线图
    目录前言开发的思路如下:(一)设计Android端的View层(二)设计与JS交互的方法(三)开发html以及js逻辑总结前言 今天的内容是使用Android原生webview配合H...
    99+
    2024-04-02
  • Android使用AudioRecord实现录音功能
    前言 Android使用AudioRecord实现录音 提示:以下是本篇文章正文内容,下面案例可供参考 一、AudioRecord使用 Android平台可以使用AudioRecor...
    99+
    2022-11-13
    Android AudioRecord 录音
  • android中NFC读写功能的实现方法
    本文实例为大家分享了android中NFC读写功能的具体代码,供大家参考,具体内容如下 首先检查一下设备是否支持NFC功能 private void checkNFCFuncti...
    99+
    2024-04-02
  • Win10 Build 9888怎么使用离线地图功能
    据外媒报道,在实现Windows Phone和Windows无缝连接的过程中,有一项功能直到现在都还没有出现,那就是将地图保存到系统中然后在离线的情况下加以使用。不过现在,外媒在Windows 10 build 9888...
    99+
    2023-06-09
    Win10 Build9888 离线地图 地图功能 离线
  • AmazonAurora的读写分离功能如何实现和配置
    Amazon Aurora的读写分离功能可以通过创建一个只读的数据库实例来实现。在Amazon Aurora中,可以通过设置一个只读...
    99+
    2024-04-09
    AmazonAurora
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作