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 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 getNextLevelList(String jsonStr) {

List 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 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 getNextLevelList(String jsonStr) {

List 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 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 getNextLevelList(String jsonStr) {

List 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()判断内容高度来实现显示完成的监听,结果任然不理想。于是我最终版是这样的

/**

*  可以监听显示完成的webview

*/

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;

}

源码地址:

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

android实现在线阅读功能,Android使用WebView实现离线阅读功能相关推荐

  1. android调用在线天气服务,android通过google api获取天气信息示例

    android通过google API获取天气信息 复制代码 代码如下: public class WeatherActivity extends Activity { private TextVie ...

  2. 有道云笔记 协作android版,有道云笔记Android版升级_软件资讯软件快报-中关村在线...

    有道云笔记2.5.0发布: 有道云笔记2.5.0 软件大小:17.6MB 应用平台:Android 软件特点:增加笔记离线阅读与收藏. 有道云笔记Android版升级至2.5版,增加了iPhone版中 ...

  3. 有道云笔记Android app离线缓存,有道云笔记Android版升级 增加笔记离线阅读与收藏...

    近日,有道云笔记Android版升级至2.5版,增加了iPhone版中颇受用户好评的离线阅读功能,同时增加了微信分享笔记,收藏笔记等实用功能. 升级后,用户可以在离线阅读设置页面,选择需要离线阅读的笔 ...

  4. android 上下滚动文字_计算机毕设项目004之Android系统在线小说阅读器

    计算机毕设项目004之Android系统在线小说阅读器 一. 项目名称 基于Android系统的在线小说阅读器 二. 项目简介 项目中的角色功能: 支持翻页动画:仿真翻页.覆盖翻页.上下滚动翻页等翻页 ...

  5. android 上线apk,码云 Android apk 在线构建功能上线啦!

    原标题:码云 Android apk 在线构建功能上线啦! #点击上图,立即参与OSC珠海源创会# duang duang duang -- 各位看官,开源中国码云 Android 项目构建新功能上线 ...

  6. Android的webview支持HTML5的离线应用功能

    HTML5的离线应用功能可以使得WebApp即使在网络断开的情况下仍能正常使用,这是个非常有用的功能.近来工作中也要用到HTML5离线应用功能,由于是在Android平台上做,所以自然而然的选择Web ...

  7. android webview epub,《webview实现epub阅读器详解》.pdf

    <webview实现epub阅读器详解>.pdf webview实现epub阅读器详解 主讲:eoe移动开发者社区 移动老师 课程地址:/course/座机电话号码72 简易epub阅读器 ...

  8. android订餐系统app、android购物商城系统app 手机端+服务器端 mysql数据库,界面简单,功能齐全 安卓购物商城 安卓在线订餐系统

    android订餐系统app.android购物商城系统app 一.简介 该项目可作为毕业设计开发使用,包含项目源代码.数据库.开题报告.毕业论文.答辩ppt等. 毕业设计题目:"基于And ...

  9. 了解适用于Android应用程序的本机,WebView和混合模板

    让我们从一些统计数据开始: 75%的人使用移动设备作为上网的主要方式. 在移动设备上进行的搜索中,有80%产生了销售. 90%的移动用户在应用程序上花费的时间比在网络上花费的时间多. 接触移动用户的最 ...

最新文章

  1. Unity + SQL数据库创建管理玩家排行榜学习教程
  2. 怎样才能高效的在家办公或者远程办公呢?
  3. (转)linux运行tomcat时JRE_HOME显示不对怎么办?
  4. 实现本网站图片保护功能之加水印
  5. html中红色星号,谨慎使用CSS中的星号(*)通配符
  6. B. Bogosort codeforces(思维)
  7. 前端学习(1885)vue之电商管理系统电商系统之首页路由的重定向
  8. Windows平台RTSP|RTMP播放端SDK集成说明
  9. mysql ssd优化_mysql ssd 优化
  10. JavaScript基础之Array对象和Boolean对象
  11. checking for tgetent()... configure: error: NOT FOUND!
  12. 颠覆大数据分析之Storm简介
  13. spring源码学习
  14. 计算机软件项目实施工程师要掌握哪些知识
  15. Mac SpotLight无法搜索
  16. Windows引导过程(BIOS,UEFI)
  17. Win11任务栏太宽了怎么办?教你一招快速修改任务栏大小
  18. 计算雅思成绩C语言,雅思总成绩计算四舍五入查分表
  19. 小轿车燃烧爆炸 洒水车变身“消防车”
  20. fat16和fat32文件系统学习

热门文章

  1. word大纲级别始终为一级的解决方案
  2. javascript分支语句
  3. C++ 中string数组怎么求长度(元素个数)
  4. lol个服务器系统更新先后,英雄联盟:年前服务器的最后一次更新 版本的英雄沉浮及详细解析...
  5. Linux docker(01) 基础操作
  6. 鸿蒙系统4g以上,华为四款手机发布:预装鸿蒙系统,全部支持4G!
  7. linux iostat
  8. 重新梳理JScript基础知识之函数篇
  9. 华茅酒的酿制,不能缺少这位“空中酿酒师”!
  10. “傻瓜”不是瓜,“肮脏”本不脏