這段時(shí)間公司需要將原項(xiàng)目重構(gòu)成mvp架構(gòu)铣揉,本人參考了網(wǎng)上一些關(guān)于Android的mvp項(xiàng)目說(shuō)明和demo抄罕,再加上自己項(xiàng)目中的一些實(shí)際需求屁药,整理了一份mvp的架構(gòu)寒瓦。這個(gè)架構(gòu)使用retrofit作為網(wǎng)絡(luò)框架情屹,使用post請(qǐng)求方式,并在接口請(qǐng)求時(shí)加入了緩存機(jī)制杂腰,使用rxbus替換廣播垃你,整個(gè)項(xiàng)目重構(gòu)+測(cè)試耗時(shí)兩個(gè)星期左右。
由于本項(xiàng)目參考了其他網(wǎng)友的項(xiàng)目喂很,如有網(wǎng)友發(fā)現(xiàn)我引用了自己的項(xiàng)目惜颇,可以聯(lián)系我,我會(huì)在文章中進(jìn)行說(shuō)明少辣。下面附上項(xiàng)目鏈接:
https://github.com/gongchenghao/
這里重點(diǎn)說(shuō)一下緩存機(jī)制凌摄,我在查找retrofit的時(shí)候,并沒(méi)有發(fā)現(xiàn)retrofit有自帶的緩存機(jī)制漓帅,而網(wǎng)上一些針對(duì)retrofit進(jìn)行緩存的方法大多也是針對(duì)get請(qǐng)求的锨亏,post請(qǐng)求的基本沒(méi)有,于是我只能是利用一個(gè)緩存的工具類(lèi)進(jìn)行緩存忙干,這個(gè)工具類(lèi)可以設(shè)置每個(gè)接口的緩存時(shí)間器予,緩存到期后會(huì)重新從服務(wù)器端拿最新數(shù)據(jù)。
以下是我在項(xiàng)目重構(gòu)時(shí)遇到的一些問(wèn)題的解決方法:
1:使用retrofit訪問(wèn)網(wǎng)絡(luò)時(shí)需要先創(chuàng)建javabean捐迫,對(duì)于一些需要拿到Json才能創(chuàng)建JavaBean或者需要看到Json返回的數(shù)據(jù)的開(kāi)發(fā)來(lái)說(shuō)乾翔,這種
封裝就顯得過(guò)猶不及,因此我在初始化retrofit的時(shí)候施戴,將addConverterFactory(GsonConverterFactory.create())這個(gè)方法注釋掉了反浓,
并在APIStores類(lèi)中將Observable后面的泛型改成ResponseBody:Observable postDaDian(@FieldMap Map map)萌丈,
這樣在ApiCallback的onSuccess()方法中拿到的就是ResponseBody的對(duì)象,通過(guò)new String(responseBody.string())就能拿到返回的Json
2:為了防止使用Gson解析Json字符串失敗導(dǎo)致APP崩潰的問(wèn)題雷则,在解析Json時(shí)需要加上try/catch浓瞪,對(duì)此我創(chuàng)建了DefaultParser泛型類(lèi)進(jìn)行統(tǒng)一解析
3:retrofit的緩存問(wèn)題:通過(guò)查閱一些資料我發(fā)現(xiàn)retrofit本身并沒(méi)有提供緩存,因此緩存需要我們自己?jiǎn)为?dú)添加巧婶。網(wǎng)上的一些示例多是針對(duì)get
請(qǐng)求添加緩存,而對(duì)于post請(qǐng)求涂乌,則很少提到艺栈。因此我從網(wǎng)上找了一個(gè)ACache的緩存工具類(lèi),這個(gè)工具類(lèi)可以設(shè)定每個(gè)接口的緩存時(shí)間湾盒,使用相當(dāng)靈活湿右。
我將ACache與retrofit結(jié)合,在用戶調(diào)用Presenter中的網(wǎng)絡(luò)請(qǐng)求方法時(shí)罚勾,如果緩存時(shí)間還沒(méi)到毅人,就直接返回緩存數(shù)據(jù)。
4:在沒(méi)有使用rxbus傳遞消息之前尖殃,一般使用廣播或者eventbus來(lái)傳遞數(shù)據(jù)丈莺,這次重構(gòu)直接使用rxbus來(lái)替換大部分的廣播來(lái)發(fā)送消息,rxbus可以傳遞各種
類(lèi)型的數(shù)據(jù)送丰,比如javabean缔俄,hashmap,arraylist器躏,string等俐载,這個(gè)在示例demo中均有示例。之所以說(shuō)替換大部分廣播登失,是因?yàn)轫?xiàng)目中用到了鬧鐘功能遏佣,這個(gè)
是需要發(fā)送廣播的。
5:對(duì)于在工具類(lèi)揽浙、adapter状婶、dialog中需要訪問(wèn)網(wǎng)絡(luò)的情況,可以直接調(diào)用retrofit的網(wǎng)絡(luò)請(qǐng)求方法馅巷,而不用結(jié)合mvp和rxjava太抓,但是需要注意的一點(diǎn)是,在
ApiStores中令杈,應(yīng)該將之前的Observable postGetIocnList(@FieldMap Map map)中的Observable替換成Call
6:rxbus重復(fù)接收到消息的問(wèn)題:重復(fù)注冊(cè)導(dǎo)致的問(wèn)題走敌。情景:發(fā)送一次消息,收到多次消息逗噩。在做列表刪除時(shí)掉丽,刪除成功后會(huì)調(diào)用rxbus發(fā)送和接收消息跌榔,更新
列表UI。在這里每次創(chuàng)建adapter都會(huì)注冊(cè)rxbus捶障,而每次下拉刷新都會(huì)重新創(chuàng)建adapter并注冊(cè)rxbus僧须,導(dǎo)致rxbus重復(fù)注冊(cè)。解決方法就是每次注冊(cè)時(shí)项炼,把當(dāng)次
注冊(cè)的tag加入到ArrayList集合中担平,下次注冊(cè)時(shí),遍歷集合判斷有無(wú)該tag锭部,如果有暂论,就不走注冊(cè)的代碼了。
public static boolean isAdded(Class tClass)
{
LogUtils.i("傳過(guò)來(lái)的tClass:"+tClass.toString());
boolean isAdd = false;
for (int i = 0; i
if (tClass.toString().equals(mArrayList.get(i)))
{
isAdd = true;
}
}
return isAdd;
}