启动的时候会有一个启动页的动画,并且首次的时候会下载启动页的图片到本地
image创建SplashActivity.java,记得在AndroidManifest.xml中注册
状态栏
private void initStatus() {
if (Build.VERSION.SDK_INT >= 21) {
View decorView = getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
}
注入SplashPresenter
设计接口
创建接口类 SplashContract.java
两个接口
- Presenter 接口中的
getSplash
方法是获取数据处理数据的 - View接口是为了提供View的
public interface SplashContract {
interface Presenter {
void getSplash(String deviceId);
}
interface View{}
}
创建SplashPresenter
这部分是真实的网络请求,处理数据的部分
创建SplashPresenter.java,实现SplashContract.Presenter接口。如下
public class SplashPresenter implements SplashContract.Presenter{
private SplashContract.View view;
private ApiService apiService;
@Inject
public SplashPresenter(SplashContract.View view, ApiService apiService) {
this.view = view;
this.apiService = apiService;
}
@Override
public void getSplash(String deviceId) {
}
}
接下来,我们需要在上面的getSplash中请求数据,这部分代码我们后面实现
创建SplashModule
-
@Module
注解标注 -
@Provides
注解标注,这些方法就是所提供的依赖,Dagger2 会在该类中寻找实例化某个类所需要的依赖。
@Module
public class SplashModule {
private SplashContract.View view;
public SplashModule(SplashContract.View view) {
this.view = view;
}
@Provides
public SplashContract.View provideView(){
return view;
}
}
创建SplashComponent
- module是SplashModule.class
- 还需要依赖网络的Component
-
@UserScope
网上说是和生命周期绑定
@UserScope
@Component (modules = SplashModule.class,dependencies = NetComponent.class)
public interface SplashComponent {
void inject(SplashActivity splashActivity);
}
UserScope.java 类代码如下
@Scope
public @interface UserScope {
}
Make Project
完成之后 **apt **会自动生成一个 以 Dagger 开头的 Component,此处,我们上面写的是 SplashComponent,生成了类名就为 DaggerSplashComponent,这个类我们可以直接使用
使用
此时,就注入了 SplashPresenter
DaggerSplashComponent.builder()
.netComponent(MyApplication.getInstance().getNetComponent())
.splashModule(new SplashModule(this))
.build()
.inject(this);
完整代码
上述都是在onCreate中实现的
public class SplashActivity extends BaseActivity implements SplashContract.View,EasyPermissions.PermissionCallbacks{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DaggerSplashComponent.builder()
.netComponent(MyApplication.getInstance().getNetComponent())
.splashModule(new SplashModule(this))
.build()
.inject(this);
initStatus();
}
}
数据请求处理
注入SplashPresenter之后,就需要用它来请求数据了
在ApiService创建网络请求
这部分代码在上一篇中已经介绍过了,不再详述
public interface ApiService {
@GET("static/picture_list.txt")
Observable<SplashEntity> getSplash(@Query("client") String client,@Query("version") String version,@Query("time") Long time,@Query("device_id") String deviceId);
}
数据处理并缓存
Long time = TimeUtil.getCurrentSeconds();
apiService.getSplash("android","1.3.0",time,deviceId)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(new Subscriber<SplashEntity>() {
@Override
public void onCompleted() {
Logger.e("load splash onCompleted");
}
@Override
public void onError(Throwable e) {
Logger.e("load splash Error"+e.toString());
}
@Override
public void onNext(SplashEntity splashEntity) {
//判断是不是wifi环境
if (NetUtil.isWifi(MyApplication.getInstance().getApplicationContext())) {
if (splashEntity != null){
List<String> urlist = splashEntity.getImages();
//拿到url之后下载图片数据
for (String url:urlist) {
OkHttpImageDownloader.download(url);
}
}
}else {
Logger.d("不是WIFI环境,不下载图片");
}
}
});
创建文件保存启动页
这部分就是文件的处理,有一些文件处理的方法参考文章下面附录中的 FileUtils.java
public class OkHttpImageDownloader {
public static void download(String url){
Request request = new Request.Builder().url(url).build();
HttpUtils.client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Logger.d(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
FileUtils.createSdDir();
String url = response.request().url().toString();
int index = url.lastIndexOf("/");
String pictureName = url.substring(index+1);
if(FileUtils.isFileExist(pictureName)){
return;
}
Logger.i("pictureName="+pictureName);
FileOutputStream fos = new FileOutputStream(FileUtils.createFile(pictureName));
InputStream in = response.body().byteStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf))!=-1){
fos.write(buf,0,len);
}
fos.flush();
in.close();
fos.close();
}
});
}
}
展示启动页图片
在展示之前需要做一些权限的处理,参考一下源码吧,这里就不写了
首先调用网络请求方法 ,在数据请求之后,在Oncreate中或者onStart中都可以调用
//只需要这一行代码就可以完成数据的请求
presenter.getSplash(deviceId);
完成数据请求之后,展示图片,会从缓存中的图片中随机出来一张图片做展示,原来的代码中还会判断上一次展示的图片序号,确保本次和上一次展示的图片不一样,我删掉了这部分代码。
private void delaySplash() {
List<String> picList = FileUtils.getAllAD();
if (picList.size() > 0) {
int index = new Random().nextInt(picList.size());
Logger.d("tuionf","----index---"+index);
File file = new File(picList.get(index));
InputStream fis = null;
try {
fis = new FileInputStream(file);
splashImg.setImageDrawable(InputStream2Drawable(fis));
animWelcomeImage();
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}else {
try {
AssetManager am = this.getAssets();
InputStream is = am.open("welcome_default.jpg");
splashImg.setImageDrawable(InputStream2Drawable(is));
animWelcomeImage();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
源码与附录
布局文件 activity_splash.xml
网友评论