The business logic of the project is constantly changing, and the requirements are constantly expanding, which makes it more and more tedious to deal with the original code base. At this time, the project framework and code specification are very necessary. Google Android Architecture Blueprints on GitHub provides many framework demos, now do a simple analysis of todo MVP among them, and write a simple Demo.

1. MVP basic structure

MVP evolved from the older MVC framework and has some similarities with MVC: Controller/Presenter handles logic, Model provides data, and View displays. On Android, you can greatly reduce the burden of activities, while increasing scalability and coupling.

View: Is responsible for drawing UI elements and interacting with the user (in Android it is an Activity). As the intermediate link between View and Model interaction, responsible logic for dealing with user interaction ii. TodoMVP framework structure

There are several steps:

Initialize the Fragment and Presenter instance in the Activity, and assign Presenter to the Fragment to implement the View interface and have Presenter references. Non-ui operations on the Fragment are performed by calling Presenter, and Presenter sends the result back to the Fragment by calling the View back to show that Presenter owns a reference to the View. Because the UI is separated from the implementation, an Activity only needs to render the UI based on the returned state. Presenter only needs to consider the processing logic and inform the View of the processed state. There are huge advantages when the application UI changes frequently.

Write a simple Demo

Write a simple search Demo, enter the keywords, start the search when the search button is clicked, and display the returned results.

SearchContract implementation, View contains search success and search failure callback, Presenter is mainly search method and Activity lifecycle methods.

public interface SearchContract { interface View extends BaseView<SearchContract.Presenter> { void onSearchSuccess(String result); void onSearchFailure(String message); } interface Presenter extends BasePresenter { void stop(); void startSearch(String searchKey); }}Copy the code

MainActivity implements searchContract. View, creates an instance of SearchPresenter, and initializes the UI.

public class MainActivity extends AppCompatActivity implements SearchContract.View {

    private SearchContract.Presenter mPresenter;

    private EditText etSearchKey;
    private TextView tvResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new SearchPresenter(this, new DataManager());

        etSearchKey = (EditText) findViewById(R.id.et_search_key);
        tvResult = (TextView) findViewById(R.id.tv_result);

        findViewById(R.id.btn_search).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String searchKey = etSearchKey.getText().toString();
                if (TextUtils.isEmpty(searchKey)) {
                    showToast("Search keywords cannot be empty!");
                    return; } mPresenter.startSearch(searchKey); }}); } @Override public voidonResume() {
        super.onResume();
        mPresenter.start();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mPresenter.stop();
    }

    @Override
    public void onSearchSuccess(String result) {
        tvResult.setText(result);
    }

    @Override
    public void onSearchFailure(String message) {
        tvResult.setText(message);
    }

    @Override
    public void setPresenter(SearchContract.Presenter presenter) { mPresenter = presenter; } public void showToast(String message) { Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); }}Copy the code

Create SearchPresenter to implement the SearchContract.Presenter interface, where the search method gets data by calling the Model layer interface and calls back the state to the View after processing the result.

public class SearchPresenter implements SearchContract.Presenter {

    private SearchContract.View searchView;
    private CompositeSubscription mCompositeSubscription;
    private DataManager dataManager;
    private String mResult;

    public SearchPresenter(SearchContract.View searchView, DataManager dataManager) {
        this.searchView = searchView;
        this.dataManager = dataManager;

        this.searchView.setPresenter(this);
    }

    @Override
    public void start() {
        mCompositeSubscription = new CompositeSubscription();
    }

    @Override
    public void stop() {
        if (mCompositeSubscription.hasSubscriptions()) {
            mCompositeSubscription.unsubscribe();
        }
    }

    @Override
    public void startSearch(String searchKey) {
        mCompositeSubscription.add(dataManager.getSearchResult(searchKey)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<ResponseBody>() {
                    @Override
                    public void onCompleted() {
                        if(mResult ! = null) { searchView.onSearchSuccess(mResult); } } @Override public void onError(Throwable e) { e.printStackTrace(); searchView.onSearchFailure("Request failed!!);
                    }

                    @Override
                    public void onNext(ResponseBody responseBody) {
                        if(responseBody ! = null) { try { mResult = responseBody.source().readUtf8(); } catch (IOException e) { e.printStackTrace(); }}}}); }}Copy the code

The original blog: http://www.apkbus.com/blog-928212-77226.html