如何实现 Splash 页面三秒跳转和动态下载最新背景图 | Android干货
Tips:
Android本月免费课程报名中,点击文末“阅读原文”快速抢!
最近公司产品大大说我们需要一个动态替换的闪屏页面,like 某猫,某东一样,可以动态替换。
产品大大就是厉害,说一句话我们就需要实现好几个功能:
创建一个冷启动后的闪屏页面(Splash 页面)
这个页面默认 3s 倒计时,点击倒计时按钮可以跳转并结束倒计时
点击图片如果有外链,则跳转应用的 web 页面用来作为活动页面(没错这点和某猫很像)
动态替换厉害了,我们需要在进入这个页面后去后台请求一下是否有新的图片,如果是新的图片则下载到本地,替换掉原来的图片,下次用户在进入 Splash 就会看到一个崭新的图片。
效果图
布局文件文件相对来说还是比较简单,就需要一个 ImageView 和 Button 即可,Button 的背景是一个自定义的 shape,透明度颜色啥的,根据UI妹砸说的算就好了。
实现倒计时的功能方法有很多,最基本的你可以使用 Handler 来实现吧,还可以是用 Timer 吧。
但是由于之前写验证码倒计时的时候发现 android.os 中有一个神奇的类叫 CountDownTimer 的类,此类神奇之处就在于你完全不需要理会那些线程交互他都给你处理好了,你只管在回调中处理时间设置跳转逻辑就好了。
但是有一个不足的地方就它的第一秒的倒计时有时候会不可见,所以我们将倒计时总时间设置为 4s 。
最后需要在有闪屏页面的情况下,进入开启倒计时:
private void startClock() {
mSpJumpBtn.setVisibility(View.VISIBLE);
countDownTimer.start();
}
上边说了我们 APP 点击图片需要可以跳转,下面代码给出了背景点击跳转的逻辑:
跳转逻辑可以根据实际的项目需求来规定,下面的代码中 Splash 为本地序列化的 model 用来存储网络下载的闪屏页面信息,稍后会有详细的序列化过程,此刻我们只需要关注跳转逻辑:
机智的你可能看出来我们并没有在离开页面的时候结束掉 timer,其实我们是复写了 onDestroy 方法。
@Override
protected void onDestroy() {
super.onDestroy();
if (countDownTimer != null)
countDownTimer.cancel();
}
其实跳转以后还有一个坑就是,从 web 页面返回的时候,因为闪屏页面是你应用的第一个页面,而跳转到 web 页面的是你 finish 掉了该页面,那么从 web 页返回的时候不做处理,用户就直接退出了 app 这样当然是不允许的。
所以请在 web 页面中添加以下逻辑:
上边说了我们有这样一个需求,就是如果后台的接口返回的图片与本地序列化的图片不同,我们需要将新的图片下载到本地,然后下次进入 Splash 的时候就展示的新的图片了。
这里你需要知道知识有下边几个:
java bean 序列化与反序列化的知识
IntentService 服务的知识
AsycTask 的使用
6.0 以上权限申请 EasyPermissions (https://github.com/googlesamples/easypermissions)的使用。
以上不熟悉的同学,看到下边的代码可能会引起适量身体不适
(1)权限管理
首先我们注意到已进入 Splash 页面我们就进行权限检查,因为我们需要下载最新的闪屏到本地,并取出序列化的对象,来展示对应的内容。
其中 checkSDCardPermission 涉及到 6.0 以上下载最新图片的逻辑,这里采用的是 官方的 EasyPermissions 来处理,关于 EasyPermissions 的使用这里就不多说了,需要了解的请移步 EasyPermissions;
https://github.com/googlesamples/easypermissions
简单来说在 EasyPermissions.hasPermissions 的回调中我们就可以正确的做我们下载图片的工作了。
(2)创建本地序列化对象 Splash Entity
Splash 内容如下:
(3)序列化反序列话的工具类 SerializableUtils
由于项目用到序列化地方还有挺多的,所以这里封装了一个序列化工具类SerializableUtils:
经过上边的努力我们已经完成了从本地反序列化内容,然后加载图片的工作了,剩下的需要做的就是下载最新图片的工作。
(4)请求接口下载最新的闪屏信息和图片
这里经过考虑,我决定采用服务去下载,因为这样可以少很多麻烦,也不影响程序的正常运行。但是绝不是你们要采用这样的方法,你们也可以单独写个工具类内部去开线程做这件事。
项目中使用开启 IntentServie 来下载图片,关于这中服务的最大的好处就是,我们不需要关注服务是否执行完任务,当他执行完 onHandleIntent 方法后他就自己挑用 stop 方法了。我们只需要关注下载逻辑和序列化逻辑就好。
checkSDCardPermission 中调用的 startImageDownLoad() 方法:
private void startImageDownLoad() {
SplashDownLoadService.startDownLoadSplashImage(this,
Constants.DOWNLOAD_SPLASH);
}
SplashDownLoadService 内容,IntentService 在调用了 startService 后会执行 onHandleIntent 方法,在这方法中我们去请求服务器最新的数据即 loadSplashNetDate:
由于是公司项目,请求方法就不给出了,但是需要讲下请求数据后如何判断是否需要执行下载任务:
getSplashLocal 方法即反序列话本地存储的 Splash Entity 的过程,上边已经给出这里就不细说,主要讲一下判断逻辑 isNeedDownLoad:
分隔 uri 取图片名称的方法:
满足下载条件后则调用 DownLoadTask 下载,
DownLoadTask:
由于下载完成后需要拿到文件存储地址这里写了一个 mDownLoadInterFace.afterDownLoad 的回调在 service 拿到回调后:
写在最后
上边 bb 这么多,我们可以看出产品一句话,我们程序员可能就需要工作一天了,所以我们需要将这个常见的功能记录下,下个公司产品再说实现一个闪屏功能,然后我们就可以说 这功能可能需要 1天时间,然后等他答应了,copy 一下,其他的时间你就可以学习下 Rxjava2 ,kotlin, js 之类的了。哈哈哈哈 我真tm机智。
后台回复「视频」,获取Kotlin视频学习资料。由于资源容易被删,发现删了请给我直接留言,我给你直发下载链接。
更多干货
学懂技术关键点,月薪3W,你也可以!
6月安卓免费课程报名中,名师答疑解惑,4天学做一个APP!
回复「姓名+微信号+城市」报名或点页面底部「阅读原文」报名。
回复「领取」免费下载安卓学习资料&工具&组件
各类干货和励志鸡血,更有各种好玩好看的资讯!
点击阅读原文报名Android免费课程