場(chǎng)景:
你可能遇到過(guò)類似的情況:同一條數(shù)據(jù)在多個(gè)頁(yè)面上展示躬存,并且這些頁(yè)面同時(shí)存在,在其中某一個(gè)頁(yè)面上修改數(shù)據(jù)舀锨,其他頁(yè)面能夠及時(shí)更新岭洲。我在工作當(dāng)中就遇到了一個(gè)類似的場(chǎng)景:我們APP內(nèi)部做了一個(gè)論壇,每條帖子都可以被點(diǎn)贊坎匿,可以在列表頁(yè)點(diǎn)贊也可以在詳情頁(yè)點(diǎn)贊盾剩。以前只有一個(gè)列表頁(yè),一個(gè)詳情頁(yè)替蔬,所以直接通過(guò)startActivityForResult和onActivityResult就可以在返回列表頁(yè)的時(shí)候更新列表頁(yè)的狀態(tài)告私。后來(lái)又增加了一個(gè)列表頁(yè),跟前一個(gè)列表頁(yè)有重復(fù)數(shù)據(jù)进栽,上面的那個(gè)方法就玩不轉(zhuǎn)了德挣,只得另外在想辦法。本文就是從這個(gè)問(wèn)題出發(fā)快毛,提出一個(gè)解決同類問(wèn)題的通用方法格嗅。
架構(gòu):
核心思想:
-
借助EventBus構(gòu)建一個(gè)Publish/Subscribe系統(tǒng)
; - 每個(gè)頁(yè)面就是一個(gè)Observer唠帝,向EventBus訂閱自己感興趣的事件屯掖;
- 當(dāng)數(shù)據(jù)對(duì)象(Subject)發(fā)生改變,發(fā)布(Publish)一個(gè)事件出來(lái)襟衰;
- 頁(yè)面接收到事件更新自己持有的數(shù)據(jù)贴铜、修改頁(yè)面展示。
實(shí)現(xiàn):
- 事件基類:
public class BaseEvent {
public String uuid;
public BaseEvent(String uuid){
this.uuid = uuid;
}
public BaseEvent(){}
public boolean isMe(String me){
if(TextUtils.isEmpty(uuid)){
return true;
}
return me.equals(uuid);
}
}
- 事件樣例:
public class PraiseEvent extends BaseEvent {
public String data;
public PraiseEvent(String uuid,String data){
super(uuid);
this.data = data;
}
}
- 頁(yè)面處理樣例:(這里展示了RecyclerView當(dāng)中更新數(shù)據(jù)的做法)
public void onEventMainThread(PraiseEvent event) {
int count = recyclerView.getChildCount()-1;
for(int i=0;i<count;i++){
View child = recyclerView.getChildAt(i);
if(child.getTag() != null){
ItemViewHolder holder = (ItemViewHolder) child.getTag();
if(event.isMe(holder.data.getId())){
Data data = holder.data;
String target = event.data;
if (target.equals(data.getIsLike())) {
return;
}
data.setIsLike(target);
holder.binding.ivLike.setImageResource("Y".equals(data.getIsLike()) ?
R.drawable.ic_like_normal :
R.drawable.ic_like_pressed);
return;
}
}
}
int size = datas.size();
for(int i = 0;i<size;i++){
Data data = datas.get(i);
if(event.isMe(data.getId())){
String target = event.data;
if (target.equals(data.getIsLike())) {
return;
}
data.setIsLike(target);
return;
}
}
}
可能存在的問(wèn)題:
本方案把所有的subscriber
都注冊(cè)到了默認(rèn)的EventBus實(shí)例上瀑晒,可能會(huì)影響性能绍坝。如果應(yīng)用模塊劃分比較明確,可以為每個(gè)模塊單獨(dú)分配一個(gè)EventBus實(shí)例苔悦。