MVP+RxJava+Dagger打造的Android(安卓)Album
MVP+RxJava+Dagger打造的Android Album
这个Demo类似Android的图库一样能扫描手机目录的大部分的图片,查看,管理,操作图片。这个Demo的组成是以MVP作为App的主要框架, Rxjava, Dagger作为辅助工具。
App的展示:
需要说明一下,我这个Album Demo只是我这个AllDemo
的一个子Demo,里面还包括了几个Demo的。而整个AllDemo也是采用MVP框架的。
这个Album Demo所涉及的代码文件有这些:
首先来说下ImageLoader和一些功能类。
这个类主要用来加载手机内的绝大部分图片,这不包括全部,原因有些其他App的图片是私有的。
loadDeviceImages方法用来加载手机图片,并返回Observable对象,这是RxJava的一个对象。想了解更多RxJava可以到官方wiki查看,毕竟我还没到熟悉程度,还在学习当中。
/** * load device images * @return Observable> */
private Observable> loadDeviceImages() { return new Observable>() { @Override protected void subscribeActual(Observer<? super List> observer) { Cursor cursor = mContext.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columnIndexs, null, null, MediaStore.Images.Media.DATE_ADDED); if (cursor == null) { observer.onError(new NullPointerException()); } // save all Image temporary List temp = new ArrayList<>(cursor.getCount()); // 用于缓存加载的图片 mCacheDirty = true; if (mCacheFolders == null) { mCacheFolders = new LinkedHashMap<>(); } if (cursor.moveToLast()) { do { long id = cursor.getLong(cursor.getColumnIndex(columnIndexs[0])); String name = cursor.getString(cursor.getColumnIndex(columnIndexs[1])); String path = cursor.getString(cursor.getColumnIndex(columnIndexs[2])); String bucket = cursor.getString(cursor.getColumnIndex(columnIndexs[3])); File file = new File(path); if (file.exists()) { Image image = new Image(id, name, path, false); temp.add(image); Folder folder = mCacheFolders.get(bucket); if (folder == null) { folder = new Folder(bucket); mCacheFolders.put(bucket, folder); } folder.getImages().add(image); } } while (cursor.moveToPrevious()); } cursor.close(); List folders = new ArrayList<>(mCacheFolders.values()); observer.onNext(folders); } }; }
该方法用到的是Observable.concat的操作方法,该方法用了两个参数方法,’loadCacheImages()’和’loadDeviceImages()’
而concat首先判断前一个是否返回null,如果返回null,再取第二个’loadDeviceImages()’返回值,如果又是null,
则取first,初始化List。然而,这样可以做到缓存的作用。
public Single> loadImages() { return Observable.concat(loadCacheImages(), loadDeviceImages()) .first(new ArrayList());}
public interface CameraModule { Intent getCameraIntent(Context context); void getImage(Context context, Intent intent, ImageCaptureReadyListener listener);}
CameraModule是一个接口。’getCameraIntent()’返回调用相机的一个intent, ‘getImage()’在调用
相机,拍照完照片后,在Activity的’onActivityResult()’方法调用,把拍照完的照片文件加入到media content里面。
如果不这么做,在调用'loadDeviceImages()'时,执行下面代码时获取不了那张图片的。所以需要注意。
Cursor cursor = mContext.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columnIndexs, null, null, MediaStore.Images.Media.DATE_ADDED);
DefaultCameraModule是CameraModule接口的实现类。
ImageCaptureReadyListener是一个监听接口,在调用CameraModule的’getImage()’方法时,在scanFile
完成后调用。
下面要讲下这个Album Demo的MVP框架
AlbumContract类是定义了V和P的方法,所有关于UI显示都写在这个V上,所有有关逻辑方面的都写在这个P上。
M就是我们数据的Model,比如这里的Image, Folder类。其实可以通过AlbumContract类的一些方法可以看出,
这个Demo所具有的一些功能表面,这也是MVP的好处,功能清晰,分明。如果对于整个项目来说,每一个功能及UI最好
写到一个包里面。
它们之间的关系如下图:
这里忘记要说的是,这个Demo只用了一个MainActivity,所有的界面都是用了Fragment。当然每个Fragment
都继承了一个基类的,基类都在base包。
希望大家可以看下AlbumFragment和AlbumPresenter对Contract的方法的实现。
下面就是要讲下用到的Dagger注入工具
AlbumModule和AlbumComponent是Dagger需要的类,具体还是看看官方文档。
Dagger比如要做一道菜,Module是所需要的配料,和材料,Compoenent犹如把各个配料和材料搞在一起或装在一起,
待放入锅里或煲里。对于Dagger自己还没有深入的了解,所以也是在实践和研究当中。因此这块暂时不多说,上来
先看代码,主要看怎么用先。等我有了深入了解,再来分享下囖。
这个AllDemo项目还在不断完善当中,里面有些UI,工具类,也有参考了他人的代码,自己也是新人吧,希望各路
大神可以给下建议和修改。毕竟自己写的代码还不是很优雅的,还要继续的提升。
更多相关文章
- android三种菜单介绍
- [Android] 问题记录 - Cupcake & Donut, Sdcard 正确使用方法
- android下播放器视频输出方法总结
- 【QQ登录】Android_SDK使用说明
- Android手动回收bitmap,引发Canvas: trying to use a recycled b
- Android系列之网络(三)----使用HttpClient发送HTTP请求(分别通过GET
- android真实项目教程(一)——App应用框架搭建_by_CJJ
- 关于Android的TimePicker和DatePicker一些简单的使用问题
- Android热补丁动态修复技术(四):完善框架①