Android MVP架構

1.簡介

如今項目中採用了MVC和MVP的混合結構,我感受MVP和MVC各有各的有點,MVC更容易入手,寫的類也相對較少 ,MVP是至關於MVC的升級版 ,面向接口編程,是view和modle徹底解耦,更利於項目的維護,項目結構更清晰,各自的職責更加清晰 ,但也有缺點就是要寫的類更多,但整體來講MVP架構仍是更好的選擇編程

2.MVC

mvc是傳統的項目架構,在Android項目中bash

  • m : model 實體層 具體的業務實體模型
  • v :view 視圖層 相關佈局文件 Activity和Fragment也屬於視圖
  • c : control 控制層 只具體的業務邏輯數據,view和model之間的交互(Activity 和Fragment)

(MVC架構)    
複製代碼

(流程圖 model和view徹底耦合到一塊兒)網絡

3.MVP

mvp是爲了讓view和model進行解耦,項目結構更加清晰,解放Activity架構

  • m : model 實體層 具體的業務實體模型
  • v:view 視圖層 相關佈局文件 Activity和Fragment
  • p : presenter 代理層 負責業務邏輯的梳理 ,view和modle之間的交互

4.MVP 和MVC的區別

上圖明顯的歸納出了mvc和mvp的不一樣點,就是mvp是view和modle不直接交互,二者的交互交給presenter來處理,還有一點就是prsenter和view之間的交互是經過接口交互的mvc

5. Demo

我按照mvp的架構寫了一個demo,demo是新聞列表的一個item,效果圖以下ide

  • modle
public class NewMessage {
    public String title; //標題
    public String content; //內容
    public boolean colleciton; //收藏

    public NewMessage(String title ,String content ,boolean colleciton){
        this.title = title;
        this.content = content;
        this.colleciton = colleciton;
    }
}
複製代碼
  • 網絡處理類 ,是採用面向接口的

根據頁面邏輯,網絡處理主要有拉取新聞信息 和點贊和取消讚的操做oop

public interface INetOperation {
    /**
     * 獲取信息信息
     * @param netListener
     */
    public void getMessage(NetListener netListener);

    /**
     * 點贊取消贊
     * @param collection
     * @param netListener
     */
    public void collectionOperation(boolean collection,NetListener netListener);

    
    //網絡回調
    public abstract class NetListener{
        public void doMessge(NewMessage newMessage){};
        public void collectionSuccess(){};
        public void collectionFail(){};
    }
}
複製代碼

對應的實現類以下佈局

public class NetOperation implements INetOperation{

    Handler mainHandler = new Handler(Looper.getMainLooper());


    @Override
    public void getMessage(final NetListener netListener) {

        new Thread(){
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                final NewMessage newMessage =new NewMessage("中國雄起","改革開放後中國高速發展,改革開放後中國高速發展,",true);
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        netListener.doMessge(newMessage);
                    }
                });
            }
        }.start();
    }

    @Override
    public void collectionOperation(boolean collection, final NetListener netListener) {
        new Thread(){
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        netListener.collectionSuccess();
                    }
                });
            }
        }.start();
    }
}
複製代碼
  • v view

view和presenter交互是經過接口進行交互的,咱們定義了一個INewMessageView的一個接口 ,但這個接口具體有什麼方法呢,就須要根據具體的業務邏輯進行書寫,本demo中頁面處理有兩處 1:設置新聞相關內容,2:更新收藏狀態post

public interface INewMessageView {
    /**
     * 設置頁面新聞信息內容
     * @param message
     */
    void setContent(NewMessage message);

    /**
     * 更新收藏信息
     * @param collection
     */
    void setCollection(boolean collection);

}
複製代碼

下面看下具體的實現ui

public class MvpActivity extends AppCompatActivity implements View.OnClickListener , INewMessageView{
    public TextView title;
    public TextView content;
    public ImageView colleciotn;
    private MessagePresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mvp);
        title = findViewById(R.id.title);
        content = findViewById(R.id.content);
        colleciotn = findViewById(R.id.collection);
        colleciotn.setOnClickListener(this);
        presenter = new MessagePresenter(this);
        presenter.getMessage();

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.collection:
                presenter.collection();
                break;
        }
    }

    @Override
    public void setContent(NewMessage message) {
        title.setText(message.title);
        colleciotn.setSelected(message.colleciton);
        content.setText(message.content);
    }

    @Override
    public void setCollection(boolean collection) {
        colleciotn.setSelected(collection);
    }
}
複製代碼

上面能夠看到具體的實現是由Activity實現的

  • presenter

presenter主要用來view和model的交互的,根據本demo它該有什麼方法呢 主要有兩個方法,1:獲取新聞信息 2:點贊取消贊操做

public class MessagePresenter {

    private INewMessageView messageView;

    //強求回來的數據
    private NewMessage message;
    private INetOperation netOperation;


    public MessagePresenter(INewMessageView iNewMessageView){
        this.messageView = iNewMessageView;
        netOperation = new NetOperation();
    }

    /**
     *收藏
     */
    public void collection(){
        if (message ==null){
            return;
        }
        netOperation.collectionOperation(message.colleciton, new INetOperation.NetListener() {
            @Override
            public void collectionSuccess() {
                super.collectionSuccess();
                message.colleciton = !message.colleciton;
                messageView.setCollection(message.colleciton);
            }

            @Override
            public void collectionFail() {
                super.collectionFail();
            }
        });

    }

    /**
     * 獲取新聞信息
     */
    public void getMessage(){
        netOperation.getMessage(new INetOperation.NetListener() {
            @Override
            public void doMessge(NewMessage newMessage) {
                super.doMessge(newMessage);
                message = newMessage;
                messageView.setContent(newMessage);
            }
        });
    }
}

複製代碼

代碼如上,是否是比較清晰

presenter承接了頁面的業務邏輯處理,負責view和model的交互,從網絡上拉取數據,更新到頁面上

總結

到這本片文章就結束了 ,本文參考了鴻洋大神的博客,其中有些圖也是從他的博客中拉取的,第一次在掘金上寫blog,寫文章的脈絡還不太熟悉,寫的也比較慢,但願本身愈來愈好吧,加油

相關文章
相關標籤/搜索