Android Application Architecture Evolution

introduction

Summarizes many years of mobile development experience, especially in the end of the accumulation of Android, previously considered from a mobile terminal APP talk about architecture, in fact, a little held the banner, because most projects are doing business rationale, and often not great, no more complex data processing or high concurrency (only for personal purposes); architecture and has long held that the word is used in large-scale systems or Web end a little better, good good architecture, meaning the system more robust, high efficiency, greater body mass . In short, a kind of feeling of overkill, however, with the expansion of the scale of the Android application development, client-side business logic more and more complex, not simple data already show, APP also need to be architecture, and split view data, releasing the coupling between modules, internal modules to improve the degree of polymerization.

APP program structure

For developers in terms of project level determines how to build the entire project and dividing module, Android common program structure:

  • UI layer
    data display and manage
    user interaction
    to draw
    Adapter

  • Yewuluojiceng
    persistent data (memory, corresponding to the global data)
    data encryption formula (data layer is sometimes necessary data need be processed into the UI layer)
    data change notification mechanism

  • Data Layer
    Data Access (DB, file, network, etc.)
    cache (pictures, documents, etc.)
    configuration files (shared perference)

From the program structure, the architecture is everywhere in the APP, but we are not too concerned about the simplest fact, are involved Demo architecture (usually MVC). From Android since its inception, the mobile terminal architecture changed many times, from the initial MVC to MVP, from the unpopular Flutter (introduced by the RN to the mobile terminal) to Google's AAC / MVVM; like thinking architecture has been changed, but the status quo a catch. It will be introduced in turn MVC, MVP, MVVM these types of mainstream architecture design, there will not be any difference between the very in-depth analysis on the architecture of the code, but to analyze their design ideas in the project to facilitate the choice of suitable infrastructure.

MVC

Very classic architecture, no matter which platform, have such architecture, easy to use and affordable. Android uses XML file to achieve a page layout, developing business logic in Activity by Java, this development model has actually adopted the MVC ideas, view and controller separation. Mode MVC (Model-view-controller) software engineering is a software architecture model, the software is divided into three basic parts: the model (the Model), view (View) and a controller (Controller).

Wikipedia:
MVC model was first proposed in 1978 by the Trygve Reenskaug, is a software architecture of the Xerox Palo Alto Research Center (XeroxPARC) in the 1980s as a programming language Smalltalk invention. MVC pattern object is to achieve a dynamic programming, so that subsequent modifications and extensions of the simplified procedures, and the re-use of a part of the program becomes possible. In this mode by simplifying the complexity of the program structure more intuitive. Software system itself by simultaneously separating the basic portion of the respective basic part also gives proper function. Professionals can be grouped by their expertise:

  • Controller (Controller) - responsible for forwarding the request to process the request.
  • View (View) - interface designer graphical interface design.
  • Model (Model) - programmers to write programs should function (algorithm, etc.), database expert data management and database design (can realize specific functions).

In Android programming, View layout file corresponding to xml, Model corresponding to the solid model (network, database, I / O), Controller Activity corresponding to business logic, data processing and the UI processing. As shown below:

Android Application Architecture Evolution

//Model
public interface WeatherModel {
    void getWeather(String cityNumber, OnWeatherListener listener);
}
................

public class WeatherModelImpl implements WeatherModel {
    @Override
    public void getWeather(String cityNumber, final OnWeatherListener listener) {
        /*数据层操作*/
        VolleyRequest.newInstance().newGsonRequest(http://www.weather.com.cn/data/sk/ + cityNumber + .html,
        Weather.class, new Response.Listener<weather>() {
            @Override
            public void onResponse(Weather weather) {
                if (weather != null) {
                    listener.onSuccess(weather);
                } else {
                    listener.onError();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                listener.onError();
            }
        });
    }
}

//Controllor(View)层
public class MainActivity extends ActionBarActivity implements OnWeatherListener, View.OnClickListener {
    private WeatherModel weatherModel;
    private EditText cityNOInput;
    private TextView city;
    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        weatherModel = new WeatherModelImpl();
        initView();
    }

    //初始化View
    private void initView() {
        cityNOInput = findView(R.id.et_city_no);
        city = findView(R.id.tv_city);
        ...
        findView(R.id.btn_go).setOnClickListener(this);
    }

    //显示结果
    public void displayResult(Weather weather) {
        WeatherInfo weatherInfo = weather.getWeatherinfo();
        city.setText(weatherInfo.getCity());
        ...
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_go:
                weatherModel.getWeather(cityNOInput.getText().toString().trim(), this);
                break;
        }
    }

    @Override
    public void onSuccess(Weather weather) {
        displayResult(weather);
    }

    @Override
    public void onError() {
        Toast.makeText(this, 获取天气信息失败, Toast.LENGTH_SHORT).show();
    }

    private T findView(int id) {
        return (T) findViewById(id);
    }
}

Examples of analysis:

  • Activity inside the control must care services and data, in order to know how their own show.
  • All logic in the activity inside.

Therefore, in the actual development process, purely as an individual XML file View function is weak, Activity View and Controller are basically fit, it is necessary to view the display and also is responsible for adding control logic, many assume the function, resulting in the amount of code great. All current conventional development should be more appropriate to say View-Model mode, most of them are coordinated through the Activity.

MVP

MVP is the transition from the MVC, MVP architecture consists of three parts: View responsible for displaying, Presenter responsible for logic processing, Model provided data. Android developers transition from MVC to MVP, the most important change is the Activity responsible for business logic code to the Presenter, Activity only act as MVP of View, association responsible for initializing and establishing interface controls the interface with the Presenter.

For example, MVC, the business logic in the page a little more complicated, and more than a thousand Activity code is very easy, but it is not a standard MVC Activity Mode Controller, its primary responsibility is to load the application layout and user initialization interface, and receiving and processing operation request from the user, and thus respond. With the complexity of the interface and its logic of continuous improvement, growing responsibilities Activity class, so that it becomes bloated, it is natural to think split. After this split, Presenter undertook a large number of logic operations, avoiding the Activity bloated. The whole structure as shown below:

Android Application Architecture Evolution

//Model层
/**
 * 定义业务接口
 */
public interface IUserBiz {
    public void login(String username, String password, OnLoginListener loginListener);
}

/**
 * 结果回调接口
 */
public interface OnLoginListener {
    void loginSuccess(User user);

    void loginFailed();
}

/**
 * 具体Model的实现
 */
public class UserBiz implements IUserBiz {
    @Override
    public void login(final String username, final String password, final OnLoginListener loginListener) {
        //模拟子线程耗时操作
        new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //模拟登录成功
                if ("zhy".equals(username) && "123".equals(password)) {
                    User user = new User();
                    user.setUsername(username);
                    user.setPassword(password);
                    loginListener.loginSuccess(user);
                } else {
                    loginListener.loginFailed();
                }
            }
        }.start();
    }
}

//View
public interface IUserLoginView {
    String getUserName();

    String getPassword();

    void clearUserName();

    void clearPassword();

    void showLoading();

    void hideLoading();

    void toMainActivity(User user);

    void showFailedError();
}

//然后Activity实现这个这个接口:
public class UserLoginActivity extends ActionBarActivity implements IUserLoginView {
    private EditText mEtUsername, mEtPassword;
    private Button mBtnLogin, mBtnClear;
    private ProgressBar mPbLoading;
    private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);

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

    private void initViews() {
        mEtUsername = (EditText) findViewById(R.id.id_et_username);
        mEtPassword = (EditText) findViewById(R.id.id_et_password);
        mBtnClear = (Button) findViewById(R.id.id_btn_clear);
        mBtnLogin = (Button) findViewById(R.id.id_btn_login);
        mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading);
        mBtnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mUserLoginPresenter.login();
            }
        });
        mBtnClear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mUserLoginPresenter.clear();
            }
        });
    }

    @Override
    public String getUserName() {
        return mEtUsername.getText().toString();
    }

    @Override
    public String getPassword() {
        return mEtPassword.getText().toString();
    }

    @Override
    public void clearUserName() {
        mEtUsername.setText("");
    }

    @Override
    public void clearPassword() {
        mEtPassword.setText("");
    }

    @Override
    public void showLoading() {
        mPbLoading.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoading() {
        mPbLoading.setVisibility(View.GONE);
    }

    @Override
    public void toMainActivity(User user) {
        Toast.makeText(this, user.getUsername() +
                " login success , to MainActivity", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showFailedError() {
        Toast.makeText(this,
                "login failed", Toast.LENGTH_SHORT).show();
    }
}

//Presenter
public class UserLoginPresenter {
    private IUserBiz userBiz;
    private IUserLoginView userLoginView;
    private Handler mHandler = new Handler();

    //Presenter必须要能拿到View和Model的实现类
    public UserLoginPresenter(IUserLoginView userLoginView) {
        this.userLoginView = userLoginView;
        this.userBiz = new UserBiz();
    }

    public void login() {
        userLoginView.showLoading();
        userBiz.login(userLoginView.getUserName(), userLoginView.getPassword(), new OnLoginListener() {
            @Override
            public void loginSuccess(final User user) {
                //需要在UI线程执行
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        userLoginView.toMainActivity(user);
                        userLoginView.hideLoading();
                    }
                });
            }

            @Override
            public void loginFailed() {
                //需要在UI线程执行
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        userLoginView.showFailedError();
                        userLoginView.hideLoading();
                    }
                });
            }
        });
    }

    public void clear() {
        userLoginView.clearUserName();
        userLoginView.clearPassword();
    }
}

Description:

  • Model through the callback data to the manner in Presenter;
  • View (Activity) is responsible for responding to user operation, the requested data by the method Presenter exposed;
  • Presenter After obtaining the data, the interface control achieved by the method of View (Activity) is exposed, to obtain data by Model, Model includes a network, and a database I / O and the like.

Using MVP obvious advantage is to avoid the case of the conventional development and Model View mode coupling improves the convenience of the code can be extended, assembly multiplexing capability, efficiency, and teamwork unit testing. But there are also some disadvantages, such as:

  • Presenter Model data transfer process requires a callback;
  • View (Activity) needs to hold a reference Presenter at the same time, also need to hold a reference Presenter View (Activity), increasing the complexity of the control;
  • Activity in MVC code is very bloated, transferred to the Presenter in MVP, also caused Presenter code when complex business logic bloated.

So, MVC to MVP simply said, it is the addition of an interface layer to reduce coupling.

MVVM

MVVM 架构模式是微软在 2005 年诞生的,MVVM是Model-View-ViewModel的简称,它由三个部分组成,也就是 Model、View 和 ViewModel,其中视图模型(ViewModel)其实就是 PM 模式中的展示模型,在 MVVM 中叫做视图模型。从实际效果来看,ViewModel是View的数据模型和Presenter的结合,具体结构如下图所示:

Android Application Architecture Evolution

说明:

  • Model(模型层)通过网络和本地数据库获取视图层所需数据;
  • View(视图层)采用XML文件进行界面的描述;
  • ViewModel(视图-模型层)负责View和Model之间的通信,以此分离视图和数据。

View和Model之间通过Android Data Binding技术,实现视图和数据的双向绑定;ViewModel持有Model的引用,通过Model的方法请求数据;获取数据后,通过Callback(回调)的方式回到ViewModel中,由于ViewModel与View的双向绑定,使得界面得以实时更新。同时,界面输入的数据变化时,由于双向绑定技术,ViewModel中的数据得以实时更新,提高了数据采集的效率。

MVVM架构将Presenter改名为ViewModel,基本上与MVP模式完全一致,唯一的区别是,它采用双向绑定(data-binding)View的变动,自动反映在 ViewModel,反之亦然,这就导致了我们如果要完整的采用 MVVM 必须熟练的掌握 DataBinding 等基础组建,这就给我们MVVM引入项目带了困难。

总结

In fact, MVC, MVP and MVVM is no absolute good or bad, in software programming, did not need one or the other, from the actual project comparing the merits of these patterns is meaningless, various modes have advantages and disadvantages, there is no good or bad points. The more complex the more advanced architecture to implement, requires more manpower costs more to learn, so that the technology selection key is in the limit with a development time of the characteristics of your own project, the level of the team, resources, these are the focus! But many teams putting the cart before the mvvm rigidly applied to their own projects. The most important thing is to let the software high cohesion, low coupling, maintainable and scalable.

Architectural thinking can be understood as a mobile terminal "MVX", that is to say the division of labor according to this rule, we do not have to think hard and consider issues narrowly hierarchical architecture, and will follow the Model-View-X can be (of course, you can also add their own some auxiliary module layer).

Guess you like

Origin blog.51cto.com/14332859/2425931