Android欢迎页预加载首页数据
2016-11-04 本文已影响1159人
knock_knock
项目需求:展示欢迎页的同时执行token登录和首页预加载
背景:
在此之前,展示欢迎页和token登录等网络操作是串行的,所以用户点开App到最终看到首页的时间就是:"展示欢迎页的时间"+"登录时间"+"请求首页数据时间"。单线程处理这些事情的优点是逻辑清晰,控制简单。缺点也非常突出:用户的体验并不好,特别是网络状况不佳的时候,等待时间大幅增加。
这个版本我们加入了跳过功能,对于等待时间的要求更高了,我不得不“磨刀霍霍”着手解决这个问题。
场景:
- 欢迎页可能执行的网络操作:检查版本更新、token登录、预加载首页数据(两个接口);
- 如果本地保存有用户的登录信息,执行token登录;
- 如果本地未保存用户的登录信息,跳转到登录页;
- 如果出现网络连接错误(断网、超时等),直接提示用户"网络错误",退出软件;
- 如果需要强制更新,跳转到登录页进行更新;
- token登录失败,跳转到登录页;
- 全部接口请求完成(仅指token登录成功),携带数据启动首页。
思路:
- 展示欢迎页的同时启动所有网络请求;
- 使用AtomicInteger计数,使用AtomicBoolean标记关键事件(是否达到展示时间、是否发生网络错误、是否需要跳转到登录页);
- 每个网络操作完成时要及时更新计数器,如果发生“关心”事件要进行登记;
- 每个网络操作完成时都要进行终点测试(判断自己是否是最后完成者,是的话就要执行跳转)。
关键代码:
网络请求样例:
VersionModelImpl.CheckVersionListener listener = new VersionModelImpl.CheckVersionListener() {
@Override
public void onSuccess(JSONObject data) {
try {
final Version version = new Gson().fromJson(data.toString(), Version.class);
if (isMustUpdate(version)) {
mNeedLogin.set(true);//登记状态
}
isCheckVersionSuccess = true;// 记录检查版本的结果
mStepsAtomicInteger.getAndIncrement();// 计数
finalTest();//终点测试
} catch (Exception e) {
e.printStackTrace();
mNeedLogin.set(true);
mStepsAtomicInteger.getAndIncrement();
finalTest();
}
}
@Override
public void onFailure(String code, String message) {
mIsNetworkError.set(true);// 登记网络错误
mStepsAtomicInteger.getAndIncrement();
finalTest();
}
};
终点测试方法:
//终点测试,判断预加载是否都完成
private synchronized void finalTest() {
if (!mAllowFinalTestAtomicBoolean.get()) {//时间是否满足
return;
}
if(mIsNetworkError.get()){//如果网络错误
try {
final Dialog dialog = confirm("网络信号不好哟~宝宝卡得要哭了~");
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
onBackPressed();
}
});
} catch (Exception e) {
e.printStackTrace();
}
return;
}
if (mNeedLogin.get()) {//如果需要登录
LoginActivity.enterLogin(PictureActivity.this);
return;
}
if (mStepsAtomicInteger.intValue() >= 4) {//所有网络请求都已返回
if (isCheckVersionSuccess && isLoginByTokenSuccess) {
enterMainActivity();
} else {
LoginActivity.enterLogin(PictureActivity.this);
}
}
}