断断续续总算完成了LeHe的开发。这个项目主要目的是应用新技术,练练手。目前项目使用了以下技术:Dragger2 + retrofit +greenDao+rxjava+ MVP+frescro。Dragger2 和retrofit 之前已经总结过,现在总结下其他技术的使用。
一.greenDao3.0使用
greenDao在3.0之前需要建立module来生成bean和dao,略微有点麻烦。不过,当大牛都用上apt 之后,greenDao在3.0也开始使用了。具体使用就不说了,baidu一大堆。这里说下我下我使用的情况。
通过结合rxjava,将项目中的笑话,笑图,搞笑GIF图,混合成一个输出结果。直接贴代码:
/**
* 从数据库中选择10条笑话,2张图片,1张GIF
*
*/
private void loadDadaFromDB() {
jokerList.clear();
Observable<List<Joker>> jokerObser = mDaoSession.getJokerDao().queryBuilder()
.where(JokerDao.Properties.Type.eq("1"))//笑话
.where(JokerDao.Properties.ReadState.eq(0))//未读
.limit(10)//10条记录
.rx()
.list();
Observable<List<Joker>> imgObser = mDaoSession.getJokerDao().queryBuilder()
.where(JokerDao.Properties.Type.eq("2"))
.where(JokerDao.Properties.ReadState.eq(0))
.limit(2)
.rx()
.list();
Observable<List<Joker>> gifObser = mDaoSession.getJokerDao().queryBuilder()
.where(JokerDao.Properties.Type.eq("3"))
.where(JokerDao.Properties.ReadState.eq(0))
.limit(1)
.rx()
.list();
//合并所有查询结果
Observable.concat(jokerObser, imgObser, gifObser)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<Joker>>() {
@Override
public void onCompleted() {
Log.d("loadMoreJokers", "jokerList= " + jokerList.size());
//查询结束显示出来
mView.showJokerList(jokerList);
changJokerStatue(jokerList);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(List<Joker> jokers) {
//每次的结果放到一个List中
jokerList.addAll(jokers);
}
});
}
顺便说下,greenDao也使用了rxjava,所以这个得好好研究下。
RxDao<Joker, String> jokerDao=mDaoSession.getJokerDao().rx();
二.frescro的使用
基本用法就不说了,这里说下使用时候遇到的坑。
在RecylerView 中图片混乱,按照网上的说法,这个理论是不存在的,frescro已经处理这种情况。通过分析,最后发现问题了。
由于GIF比较大,下载的比较慢,所以用setPlaceholderImage设置临时图片,下载过程放到点击后页面中。而fresrco 的处理这个混乱就是通过 uri来判断。所以会出现图片混乱的情况。
解决方法:就是把临时图片换成uri来设置。
还有就是保存图片,特别是保存GIF图片,这里直接上代码
public static void saveGif(final String url, Context context,BaseDataSubscriber<CloseableReference<PooledByteBuffer>> baseDataSubscriber) {
int index = url.lastIndexOf("/");
final String fileName =url.substring(index);
Uri uri = Uri.parse(url);
ImageRequest imageRequest = ImageRequestBuilder
.newBuilderWithSource(uri)
.setProgressiveRenderingEnabled(true)
.build();
ImagePipeline imagePipeline = Fresco.getImagePipeline();
DataSource<CloseableReference<PooledByteBuffer>>
dataSource = imagePipeline.fetchEncodedImage(imageRequest, context);
dataSource.subscribe(baseDataSubscriber, CallerThreadExecutor.getInstance());
}
public static void savePic(String fileName, ByteArrayOutputStream bos) {
String dir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/image/";
File dirs = new File(dir);
try {
FileUtils.mkdirs(dirs);
} catch (FileUtils.CreateDirectoryException e) {
e.printStackTrace();
}
File target = new File(dir, fileName);
FileOutputStream fos =null;
try {
fos = new FileOutputStream(target);
bos.writeTo(fos);
fos.flush();
Log.i(TAG, "已经保存");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(fos!=null)
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(bos!=null)
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
三.GSON转换
本项目中笑话和图片的返回json唯一的区别是在Joker中的text 换成Image中的 url,所以最好就是把这个换成同一个对象来存储。这里就需要把字段不同的json,转成同一个Bean。上代码:
在Bean中添加这个内部类:
public static class JokerDeserializer implements JsonDeserializer<Joker> {
@Override
public Joker deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Joker joker = new Joker();
JsonObject jsonObject = json.getAsJsonObject();
joker.setTitle(jsonObject.get("title").getAsString());
joker.setId(jsonObject.get("id").getAsString());
if(jsonObject.has("img")){
joker.setText(jsonObject.get("img").getAsString());
}else{
joker.setText(jsonObject.get("text").getAsString());
}
joker.setCt(jsonObject.get("ct").getAsString());
joker.setType(jsonObject.get("type").getAsInt()+"");
return joker;
}
}
然后在使用时:
Gson gson = new GsonBuilder().registerTypeAdapter(Joker.class, new Joker.JokerDeserializer()).create();
List<Joker> list = gson.fromJson(jokerArray.toString(), new TypeToken<List<Joker>>() { }.getType());