先看几张软件截图吧:
创作目的:在各大视频app中观看视频时,动不动就需要VIP收费,此时前去网页搜索要看的视频,但是,广告实在太烦人了,于是萌生了做个能屏蔽广告的,干净的应用。
创作步骤:1、首先搭建app基础框架,使用MVP框架开发。
2、添加基础网络请求库,使用okhttp进行网络数据加载
3、使用jsoup1.10.2解析网页数据。
4、接入腾讯x5内核浏览器的API解决webView视频播放全屏问题。
5、接入有米积分墙广告获取利润
我们一条条具体说:
首先讲解MVP软件架构:先看一张图片:
Contract :为业务数据和回调接口层,主要封装了业务处理和需要更新UI时,回调的接口。
Presenter:为业务逻辑接口,主要负责异步数据的处理:如上图的:Presenter。
View:为接口回调,主要负责界面刷新:如上图的Fragment等。
废话不说:直接上代码:
/**
* 视频页面实现业务逻辑
* Created by liww on 2019/1/14.
*/
public interface VideoContrat {
interface View {
//获取数据成功,更新UI
void loadDataSuccess(List<VideoEntity> mOnePageList,int id,boolean isCacheData);
//获取数据失败(必须显示默认界面)
void loadDataFial(int id);
}
interface Presenter {
//开始加载页面,获取数据
void beginLoadIndexPageData(VideoTitleName oneVideoTitleName, boolean isNextPager);
//保存缓存数据
void saveCacheData(int urlId, List<VideoEntity> mOnePageList);
//获取缓存数据
void getCacheData(int urlId);
}
}
View 为数据异步加载完成后,更新接口,包含数据加载成功和失败后的通知UI更新的操作。
Presenter 为具体的异步任务实现接口。包含数据加载,数据存储操作。
我们看下Presenter 具体的实现方法:
/**
* 视频业务实现类
* Created by liww on 2019/1/14.
*/
public class VideoPresenImpl implements VideoContrat.Presenter {
private VideoContrat.View mTaskViews;
private ModelCacheInit mModelCacheInit;
private boolean isLoading;
public VideoPresenImpl(VideoContrat.View taskView) {
mTaskViews = taskView;
mModelCacheInit = new ModelCacheInit();
isLoading = false;
}
@Override
public void beginLoadIndexPageData(VideoTitleName oneVideoTitleName, boolean isNextPager) {
if (isLoading) {
ToastUtils.showToast("正在加载");
return;
}
if (null == oneVideoTitleName) {
if (null != mTaskViews) {
mTaskViews.loadDataFial(-1);
}
return;
}
isLoading = true;
if (isNextPager) {
//分页处理
oneVideoTitleName.pageIndex = oneVideoTitleName.pageIndex + 1;
if (oneVideoTitleName.titleUrl.contains(LinkName.HTML)) {
oneVideoTitleName.titleUrl = oneVideoTitleName.titleUrl.substring(0, oneVideoTitleName.titleUrl.lastIndexOf("/") + 1);
}
oneVideoTitleName.titleUrl = oneVideoTitleName.titleUrl + LinkName.ENDKEYINDEX + oneVideoTitleName.pageIndex + LinkName.HTML;
} else {
oneVideoTitleName.pageIndex = 1;
}
GetHtmlData.getHtmlSource(oneVideoTitleName.titleUrl, oneVideoTitleName.titleId, new MyStringCallback());
}
@Override
public void saveCacheData(int urlId, List<VideoEntity> mOnePageList) {
CachedList<VideoEntity> cachedList = new CachedList<>(
"VideoPresenImpl" + urlId);// key
cachedList.addAll(mOnePageList);
cachedList.save(mModelCacheInit.getModelCache());
}
@Override
public void getCacheData(int urlId) {
CachedList<VideoEntity> cachedCommentList = (CachedList<VideoEntity>) CachedList
.find(mModelCacheInit.getModelCache(),
"VideoPresenImpl" +urlId, CachedList.class);
if (null != cachedCommentList && cachedCommentList.size() > 0) {
if (null != mTaskViews) {
mTaskViews.loadDataSuccess(cachedCommentList.getList(), urlId,true);
}
}
}
private class MyStringCallback extends StringCallback {
@Override
public void onBefore(Request request, int id) {
}
@Override
public void onAfter(int id) {
}
@Override
pu