单读学习-启动页

作者: tuionf | 来源:发表于2018-01-15 14:25 被阅读52次

启动的时候会有一个启动页的动画,并且首次的时候会下载启动页的图片到本地

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

两个接口

  1. Presenter 接口中的getSplash方法是获取数据处理数据的
  2. 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();
        }
    }
}

源码与附录

源码

SplashActivity.java

布局文件 activity_splash.xml

FileUtils.java工具类

相关文章

网友评论

    本文标题:单读学习-启动页

    本文链接:https://www.haomeiwen.com/subject/okvroxtx.html