使用場景:
1.在下載的時候,可以通知某個activity進行更新下載進度,或者提示下載完成,如果,需要多多個頁面中的fragment進行界面更新,就需要使用多個同時通知
2.在寫數據長連接的時候需要在service中使用數據連接,但是需要所有的activity或者fragment中需要獲得消息後的回調。
在這些情況下,單個的自定義回調不好實現,可以使用觀察者模式來實現。
2,觀察者模式需要創建目標和觀察者,觀察者一般會有多個,一般先創建接口,再在你的一些activity或fragment中實現。
例:
public interface Holder {
public void channelReadListener(String msg);
}
,
在創建了觀察者後可以創建目標
public interface Subject {
public void addHolder(Holder holder);
public void RemoveHolder(Holder holder);
public void updataAllHolder();
}
然後實現下
public class SubjectImp implements Subject {
private ArrayList<Holder> list = new ArrayList<>();
private String msg;
public static SubjectImp imp;
public static SubjectImp getImp() {
if (imp == null) {
imp = new SubjectImp();
}
return imp;
}
@Override
public void addHolder(Holder holder) {
list.add(holder);
}
@Override
public void RemoveHolder(Holder holder) {
int step = list.indexOf(holder);
if (step >= 0) {
list.remove(holder);
}
}
public void RemoveAllHolder() {
list.clear();
}
@Override
public void updataAllHolder() {
for (Holder holder
: list) {
holder.channelReadListener(msg);
}
}
public void setMsg(String msg) {
this.msg = msg;
updataAllHolder();
}
}
注意:在實現這個目標時需要使用單例的時候,需要考慮線程安全問題,如果想簡單,可直接使用餓漢式的模式實現,如果使用懶漢式可以查看這篇文章:
由於我這裏都是在主線程生成,所以不涉及這個問題。
我在service的oncreate() 中使用:
imp = SubjectImp.getImp();
在需要通知的時候 調用下:
imp.setMsg(msg);
在實現過 Holder的activity或fragment中會被回調,一般activity被destory後,holder也不需要使用了,所以在onpause()的時候我RemoveHolder(this),在使用fragment的時候需要同時受到消息,可以不用remove,那麼多個fragment就同時得到消息,然後對消息進行處理:
public class FirstActivity extends Activity implements View.OnClickListener, Holder{
@Override
public void channelReadListener(final String msg) {
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
imp = SubjectImp.getImp();
}
@Override
protected void onResume() {
super.onResume();
imp.addHolder(this);
}
@Override
protected void onPause() {
super.onPause();
imp.RemoveHolder(this);
}
}
public class LoginActivityextends Activity implements View.OnClickListener, Holder{
@Override
public void channelReadListener(final String msg) {
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
imp = SubjectImp.getImp();
}
@Override
protected void onResume() {
super.onResume();
imp.addHolder(this);
}
@Override
protected void onPause() {
super.onPause();
imp.RemoveHolder(this);
}
}