自定義回調一對多的方法

使用場景:
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();
    }
}

注意:在實現這個目標時需要使用單例的時候,需要考慮線程安全問題,如果想簡單,可直接使用餓漢式的模式實現,如果使用懶漢式可以查看這篇文章:

http://blog.csdn.net/cselmu9/article/details/51366946

由於我這裏都是在主線程生成,所以不涉及這個問題。

我在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);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章