一。基本设置
1.开启硬件加速
在 Manifest 中配置 activity 支持硬件加速 android:hardwareAccelerated=”true”
2.提高优先级
设置 webview 渲染的优先级为高级
webSettings.setRenderPriority(RENDERPRIORITY.HIGH);
3.图片延时加载
开始时阻塞图片加载,mWebSettings.setBlockNetworkImage(true);
当网页加载完成时,再取消阻塞图片加载,最好在
onPageFinished(WebView view, String url) 回调方法中设置mWebSettings.setBlockNetworkImage(false);
二。缓存方式
关于 webview 缓存的介绍参见这篇博文:http://www.jianshu.com/p/5e7075f4875f
此处仅以缓存图片说明具体实现方式
/**
* 图片 缓存表
*/
@Table(name = "cm_img_tbl")
public class CmImgTbl {
//主键 非空 唯一
@Column(name = "id" ,isId = true,property ="not null")
private int id;
//图片 文件在远程服务器上的地址
@Column(name = "remote_address",property = "not null")
private String remoteAddress;
//图片 文件在本地存储的地址
@Column(name = "local_address")
private String localAddress;
//数据插入时间
@Column(name = "insert_time")
private long insertTime;
//数据更新时间
@Column(name = "update_time")
private long updateTime;
@Column(name = "file_size",property = "not null")
private long fileSize;
//资源访问时间
@Column(name = "visit_time")
private long visitTime;
public long getVisitTime() {
return visitTime;
}
public void setVisitTime(long visitTime) {
this.visitTime = visitTime;
}
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRemoteAddress() {
return remoteAddress;
}
public void setRemoteAddress(String remoteAddress) {
this.remoteAddress = remoteAddress;
}
public String getLocalAddress() {
return localAddress;
}
public void setLocalAddress(String localAddress) {
this.localAddress = localAddress;
}
public long getInsertTime() {
return insertTime;
}
public void setInsertTime(long insertTime) {
this.insertTime = insertTime;
}
public long getUpdateTime() {
return updateTime;
}
public void setUpdateTime(long updateTime) {
this.updateTime = updateTime;
}
@Override
public String toString() {
return "CmImgTbl{" +
"id=" + id +
", remoteAddress='" + remoteAddress + '\'' +
", localAddress='" + localAddress + '\'' +
", insertTime=" + insertTime +
", updateTime=" + updateTime +
", fileSize=" + fileSize +
", visitTime=" + visitTime +
'}';
}
}
DAO部分
@Route(path = "/basemodule/cache/img")
public class ImgCacheServiceImpl implements IImgCacheService {
private final String TAG = getClass().getSimpleName().toString();
private SystemConfig config;
private DbManager manager;
@Override
public void init(Context context) {
//获取到系统配置
Object obj = SingletonManager.INSTANCE.getObj(Tag.TAG_SINGLETON_SYSTEM_CONFIG_HOLDER);
if (obj instanceof SystemConfig) {
config = (SystemConfig) obj;
}
try {
DbManager.DaoConfig daoConfig = new DbManager.DaoConfig()
//设置数据库名
.setDbName(config.getDB_NAME())
//设置数据库路径
.setDbDir(new File(config.getDB_DIR()))
//设置数据库版本
.setDbVersion(ApplicationUtil.getLocalVersion(config.getContext()))
//设置开启事务
.setAllowTransaction(true)
//监听数据库打开
.setDbOpenListener(new DbManager.DbOpenListener() {
@Override
public void onDbOpened(DbManager db) {
LogUtil.e(TAG, "数据库开启");
}
})
//监听数据库版本升级
.setDbUpgradeListener(new DbManager.DbUpgradeListener() {
@Override
public void onUpgrade(DbManager db, int oldVersion, int newVersion) {
LogUtil.e(TAG, "数据库版本升级:" + oldVersion + "-->" + newVersion);
db.getDaoConfig().setDbVersion(newVersion);
}
})
.setTableCreateListener(new DbManager.TableCreateListener() {
@Override
public void onTableCreated(DbManager db, TableEntity> table) {
LogUtil.e(TAG, "数据表创建:" + table.getName());
}
});
manager = x.getDb(daoConfig);
} catch (Exception e) {
e.printStackTrace();
LogUtil.e(TAG, "DBManager 创建失败");
}
}
/**
* 保存img 文件
* @param img
*/
@Override
public void saveImgFile(CmImgTbl img) {
if (img == null) {
LogUtil.e("img==null");
return;
}
if (!manager.getDatabase().isOpen()) {
manager = x.getDb(manager.getDaoConfig());
}
try {
//检查数据库是否有该条数据,没有则直接插入新记录
if(manager.selector(CmImgTbl.class).where("remote_address","=",img.getRemoteAddress()).count()<=0){
manager.save(img);
}else {
//已经有历史纪录,更新属性
CmImgTbl tempImg=manager.selector(CmImgTbl.class).where("remote_address","=",img.getRemoteAddress()).findFirst();
tempImg.setUpdateTime(img.getUpdateTime());
tempImg.setLocalAddress(img.getLocalAddress());
tempImg.setFileSize(img.getFileSize());
manager.update(tempImg,"update_time");
manager.update(tempImg,"local_address");
manager.update(tempImg,"file_size");
manager.update(tempImg,"visit_time");
}
} catch (DbException e) {
e.printStackTrace();
}
finally {
// try {
// manager.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}
/**
* 通过远程连接获取本地img文件地址
* @param remoteAddress
* @return
*/
@Override
public String getLocalImgAddress(String remoteAddress){
if(remoteAddress==null || remoteAddress.isEmpty()){
return "N";
}
if(!manager.getDatabase().isOpen()){
manager=x.getDb(manager.getDaoConfig());
}
try {
CmImgTbl tempImg=manager.selector(CmImgTbl.class).where("remote_address","=",remoteAddress).findFirst();
if(tempImg==null || tempImg.getLocalAddress()==null){
return "N";
}else {
String local=tempImg.getLocalAddress();
tempImg.setVisitTime(TimeUtil.getTimestamp());
//更新访问时间
manager.update(tempImg,"visit_time");
return local;
}
} catch (DbException e) {
e.printStackTrace();
}
finally {
// try {
// manager.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
}
return "N";
}
@Override
public CmImgTbl getCmImgTblByUrl(String url) {
if(url==null || url.isEmpty()){
return null;
}
if(!manager.getDatabase().isOpen()){
manager=x.getDb(manager.getDaoConfig());
}
try {
CmImgTbl tempImg=manager.selector(CmImgTbl.class).where("remote_address","=",url).findFirst();
return tempImg;
} catch (DbException e) {
e.printStackTrace();
}finally {
// try {
// manager.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
}
return null;
}
/**
* 自动清理图片
*/
@Override
public void autoClearImgCache() {
if(!manager.getDatabase().isOpen()){
manager=x.getDb(manager.getDaoConfig());
}
CacheUtil.deleteTemp(new File(com.sctjsj.basemodule.cache.commen.config.WEB_CACHE_DIR));
Calendar calendar=Calendar.getInstance();
//自动清理一个月没有访问的数据
calendar.add(Calendar.MONTH, -1);
long start=calendar.getTime().getTime();
try {
List list=manager.selector(CmImgTbl.class).where("visit_time","<",start).findAll();
if(list==null){
return;
}
for (CmImgTbl c:list){
//删除文件
File file=new File(c.getLocalAddress());
if(file.exists() && file.isFile()){
file.delete();
}
//清空数据库
manager.deleteById(CmImgTbl.class,c.getId());
}
} catch (DbException e) {
e.printStackTrace();
}
}
@Override
public void clearAllCache() {
if(!manager.getDatabase().isOpen()){
manager=x.getDb(manager.getDaoConfig());
}
try {
List list=manager.selector(CmImgTbl.class).findAll();
if(list==null){
return;
}
for (CmImgTbl c:list){
//删除文件
File file=new File(c.getLocalAddress());
if(file.exists() && file.isFile()){
boolean res=file.delete();
}
//清空数据库
manager.deleteById(CmImgTbl.class,c.getId());
}
} catch (DbException e) {
e.printStackTrace();
}
}
}
拦截资源请求,替换网络资源为本地资源
@Override
public WebResourceResponse shouldInterceptRequest(WebView webView, String s) {
//缓存图片
if (s.endsWith(".jpg") || s.endsWith(".JPG") || s.endsWith(".png") || s.endsWith("PNG")) {
String local = imgCacheService.getLocalImgAddress(s);
//本地没有,直接下载
if ("N".equals(local)) {
httpService.loadWebResource(s, "img");
return super.shouldInterceptRequest(webView, s);
} else {
InputStream isImg = null;
try {
isImg = new FileInputStream(local);
} catch (FileNotFoundException e) {
e.printStackTrace();
return super.shouldInterceptRequest(webView,s);
}
WebResourceResponse response = new WebResourceResponse("image/jpg", "UTF-8", isImg);
return response;
}
}
if (s.endsWith(".js")) {
String local = jsCacheService.getLocalJsAddress(s);
//本地没有,直接下载
if ("N".equals(local)) {
httpService.loadWebResource(s, "js");
return super.shouldInterceptRequest(webView, s);
} else {
InputStream is = null;
try {
is = new FileInputStream(local);
WebResourceResponse response = new WebResourceResponse("text/html", "utf-8", is);
return response;
} catch (IOException e) {
e.printStackTrace();
return super.shouldInterceptRequest(webView,s);
}
}
}
//缓存 css
if (s.endsWith(".css")) {
String local = cssCacheService.getLocalCssAddress(s);
//本地没有,直接下载
if ("N".equals(local)) {
httpService.loadWebResource(s, "css");
return super.shouldInterceptRequest(webView, s);
} else {
InputStream is = null;
try {
is = new FileInputStream(local);
WebResourceResponse response = new WebResourceResponse("text/html", "utf-8", is);
return response;
} catch (IOException e) {
e.printStackTrace();
return super.shouldInterceptRequest(webView,s);
}
}
}
return super.shouldInterceptRequest(webView, s);
}
四。注意事项
1.注意频繁的开启和关闭数据库,读写文件,需要做好各种异常处理
2.在下载资源文件时,可能还未下载完成,用户就已经结束该页面了,对于这种情况,下载的临时文件一定要定期清除
3.对于一个月之内没有访问过的资源文件要予以自动清除