Android App design architecture MVC MVP MVVM and architecture experience

Android App design architecture MVC MVP MVVM and architecture experience

Like the MVC framework mode, the Model model handles data in the same code. In Android App development, many people often have a headache about how to design the App architecture:

  • Does my app need to apply these design frameworks?
  • What are MVC, MVP and other architectures? What are the differences?

This article will analyze the characteristics, advantages and disadvantages of these architectures, as well as the issues that should be paid attention to in App architecture design.

1. Purpose of architecture design

By designing the program to be modular, we can achieve high aggregation within the module and low coupling between modules. The advantage of this is that during the development of the program, developers only need to focus on one point, which improves the efficiency of program development and makes it easier to conduct subsequent tests and locate problems. However, the design cannot violate the purpose. For projects of different magnitudes, the implementation methods of the specific architecture must be different. We must avoid the mistakes of designing for the sake of design and architecture for the sake of architecture.

Let's take a simple example:

  • If an Android App has only three Java files, then it only needs to be divided into modules and levels. Introducing a framework or architecture will increase the workload and reduce productivity.

However, if the final code volume of the currently developed App is more than 100,000 lines, complex operations need to be performed locally, and synchronization with other Android developers and backend developers needs to be considered, then some thinking needs to be done on the architecture!

2.MVC design architecture

Introduction to MVC

The full name of MVC is Model View Controller. As shown in the figure, it is the abbreviation of model-view-controller. It is a software design paradigm that organizes code in a way that separates business logic, data, and interface display. While improving and personalizing the interface and user interaction, there is no need to rewrite the business logic.

The M layer processes data, business logic, etc.; the V layer processes the display results of the interface; the C layer acts as a bridge to control the communication between the V layer and the M layer to separate the view display and business logic layers.

MVC in Android

The interface part of Android also adopts the currently popular MVC framework. In Android:

View

Generally, XML files are used to describe the interface. These XML files can be understood as AndroidApp Views. They can be easily imported when used. They are also convenient for later interface modifications. If the ID corresponding to the interface in the logic does not change, the code does not need to be modified, which greatly enhances the maintainability of the code.

Controller

The responsibility of the control layer of Android usually falls on the shoulders of many Activities. This sentence also implies that you should not write code in the Activity, but hand it over to the Model business logic layer through the Activity. Another reason for this is that the response time of Activity in Android is 5s. If time-consuming operations are placed here, the program will be easily recycled.

Model

The data structure and related classes we build for the business model can be understood as the Model of AndroidApp. The Model is not related to the View, but to the business (thanks to @Xander for the explanation). Operations on the database and the network should be processed in the Model. Of course, operations such as business calculations must also be placed in this layer. It is the binary data in the application.

MVC Code Examples

Let's take a look at how MVC is applied in Android development!

First, the interface picture

Controller & View

  1. public class MainActivity extends ActionBarActivity implements OnWeatherListener, View .OnClickListener {
  2.  
  3. private WeatherModel weatherModel;
  4. private EditText cityNOInput;
  5. private TextView city;
  6. ...
  7.  
  8. @Override
  9. protected void onCreate(Bundle savedInstanceState) {
  10. super.onCreate(savedInstanceState);
  11. setContentView(R.layout.activity_main);
  12. weatherModel = new WeatherModelImpl();
  13. initView();
  14. }
  15.  
  16. //Initialize View  
  17. private void initView() {
  18. cityNOInput = findView(R.id.et_city_no);
  19. city ​​= findView(R.id.tv_city);
  20. ...
  21. findView(R.id.btn_go).setOnClickListener(this);
  22. }
  23.  
  24. // Display the results
  25. public void displayResult(Weather weather) {
  26. WeatherInfo weatherInfo = weather.getWeatherinfo();
  27. city.setText(weatherInfo.getCity());
  28. ...
  29. }
  30.  
  31. @Override
  32. public void onClick( View v) {
  33. switch (v.getId()) {
  34. case R.id.btn_go:
  35. weatherModel.getWeather(cityNOInput.getText().toString().trim(), this);
  36. break;
  37. }
  38. }
  39.  
  40. @Override
  41. public void onSuccess(Weather weather) {
  42. displayResult(weather);
  43. }
  44.  
  45. @Override
  46. public void onError() {
  47. Toast.makeText(this, failed to obtain weather information, Toast.LENGTH_SHORT).show();
  48. }
  49.  
  50. private T findView( int id) {
  51. return (T) findViewById(id);
  52. }
  53. }

From the above code, we can see that the Activity holds the WeatherModel model object. When the user clicks the Button to interact, the Activity, as the Controller control layer, reads the data of the View layer EditTextView, and then initiates a data request to the Model model, that is, calling the getWeather() method of the WeatherModel object. When the Model model finishes processing the data, it notifies the View layer through the OnWeatherListener interface that the data processing is complete and the View layer should update the interface UI. Then the View layer calls the displayResult() method to update the UI. At this point, the entire MVC framework process is reflected in the Activity.

Model

Let's take a look at the WeatherModelImpl code implementation

  1. public interface WeatherModel {
  2. void getWeather(String cityNumber, OnWeatherListener listener);
  3. }
  4.  
  5. ................
  6.  
  7. public class WeatherModelImpl implements WeatherModel {
  8. /*There is a problem with this code example. Network access should not be in the Model. Network access should be replaced by reading from the database*/
  9. @Override
  10. public void getWeather(String cityNumber, final OnWeatherListener listener) {
  11.  
  12. /*Data layer operations*/
  13. VolleyRequest.newInstance().newGsonRequest(http://www.weather.com.cn/data/sk/ + cityNumber + .html,
  14. Weather.class, new Response.Listener<weather>() {
  15. @Override
  16. public void onResponse(Weather weather) {
  17. if (weather != null ) {
  18. listener.onSuccess(weather);
  19. } else {
  20. listener.onError();
  21. }
  22. }
  23. }, new Response.ErrorListener() {
  24. @Override
  25. public void onErrorResponse(VolleyError error) {
  26. listener.onError();
  27. }
  28. });
  29. }
  30. }

As can be seen from the above code, a WeatherModel model interface is designed here, and then the interface WeatherModelImpl class is implemented. The controller activity calls the method in the WeatherModelImpl class to initiate a network request, and then obtains the result of the network request by implementing the OnWeatherListener interface to notify the View layer to update the UI. At this point, the Activity separates the View display from the Model data processing. The activity acts as a controller to complete the coordination between the model and the view.

As for why we don't just design a getWeather() method in the class to directly request network data? Consider this situation: the network request in the current code is implemented using the Volley framework. If one day your boss insists that you use the Afinal framework to implement network requests, how will you solve the problem? Modify the implementation of the getWeather() method? No no no, such a modification will not only destroy the previous code, but also be difficult to maintain. Considering the future expansion and maintainability of the code, we choose to design an interface to solve this problem. We implement another WeatherModelWithAfinalImpl class, inherit from WeatherModel, and rewrite the methods inside. This not only retains the previous WeatherModelImpl class network request method, but also adds the WeatherModelWithAfinalImpl class request method. The Activity calling code does not need any modification.

3.MVP Design Architecture

In the process of App development, a common problem is that the amount of code in a certain part is too large. Although module division and interface isolation are done, it is difficult to avoid it completely. From practice, this is more common in the UI part, that is, the Activity. Imagine an Activity with more than 2000 lines and basically no comments. My first reaction is to vomit. The reason why the Activity content is too much is actually easy to explain, because the Activity itself needs to be responsible for the operation interaction with the user and the display of the interface, not just a controller or view. Moreover, most of the current Activities also play a role similar to the [ViewController] in IOS for the entire App, which brings in a lot of logical code, causing the Activity to be bloated. To solve this problem, let us introduce the MVP framework.

Disadvantages of MVC

In Android development, Activity is not a standard Controller in the MVC model. Its primary responsibility is to load the layout of the application and initialize the user interface, and to accept and process operation requests from users and respond accordingly. As the complexity of the interface and its logic continues to increase, the responsibilities of the Activity class continue to increase, making it large and bloated.

What is MVP?

MVP evolved from the earlier MVC framework and has certain similarities with MVC: Controller/Presenter is responsible for logic processing, Model provides data, and View is responsible for display.

The MVP framework consists of three parts: View is responsible for display, Presenter is responsible for logic processing, and Model provides data. The MVP model usually contains three elements (four including the View interface):

  • View: responsible for drawing UI elements and interacting with users (reflected as Activity in Android)
  • Model: responsible for storing, retrieving, and manipulating data (sometimes also implementing a Model interface to reduce coupling)
  • Presenter: As the intermediate link between View and Model, it handles the logic of interaction with users.
  • *View interface: The interface that View needs to implement. View interacts with Presenter through View interface to reduce coupling and facilitate unit testing.

Tips: *Necessity of View interface

Think back to how you unit test the code logic when developing Android applications? Do you deploy the application to the Android emulator or real device every time, and then test it by simulating user operations? However, due to the characteristics of the Android platform, each deployment takes a lot of time, which directly leads to a decrease in development efficiency. In the MVP mode, the Presenter that handles complex logic interacts with the View (Activity) through the interface, which means that we can implement this interface through a custom class to simulate the behavior of the Activity to unit test the Presenter, saving a lot of deployment and testing time.

MVC → MVP

When we move the complex logic processing of Activity to another class (Presenter), Activity is actually the View in the MVP mode. It is responsible for initializing UI elements, establishing the association between UI elements and Presenter (Listener, etc.), and also handles some simple logic itself (complex logic is handled by Presenter).

The Presenter of MVP is the controller of the framework and undertakes a lot of logical operations, while the Controller of MVC often plays a forwarding role. Therefore, the reason for introducing MVP in App is to put a lot of logical operations previously included in Activty into the control layer to avoid bloated Activity.

The main differences between the two modes:

  • (The main difference) View does not interact directly with Model, but indirectly interacts with Model through interaction with Presenter. In MVC, View can interact directly with Model
  • Usually, View and Presenter are one-to-one, but complex View may bind multiple Presenters to handle logic. Controller is behavior-based and can be shared by multiple Views. Controller can be responsible for deciding which View to display.
  • The interaction between Presenter and View is carried out through interfaces, which is more conducive to adding unit testing.

Therefore, we can find the advantages of MVP as follows:

  1. The model is completely separated from the view, and we can modify the view without affecting the model;
  2. Models can be used more efficiently because all interactions happen in one place — inside the Presenter.
  3. We can use one Presenter for multiple views without changing the logic of the Presenter. This feature is very useful because views always change more frequently than models;
  4. If we put the logic in the Presenter, then we can test the logic independently of the user interface (unit testing).

Specifically for Android App, the App can generally be divided vertically according to the structure of the program. According to MVP, the App can be divided into the model layer (M), UI layer (V) and logic layer (P).

The UI layer generally includes Activity, Fragment, Adapter and other classes directly related to the UI. After the Activity of the UI layer is started, the corresponding Presenter is instantiated, and the control of the App is transferred from the UI to the Presenter. The communication between the two is completed through BroadCast, Handler or interface, and only events and results are transmitted.

To give a simple example, the UI layer notifies the logic layer (Presenter) that the user clicks a Button. The logic layer (Presenter) decides what behavior should be used to respond and which model (Model) to find to do it. Finally, the logic layer (Presenter) updates the completed results to the UI layer.

**MVP variant: Passive View

There are many variations of MVP, among which the most widely used is the Passive View mode. In this mode, the View and Model cannot interact directly, and the View interacts with the Model through the Presenter. The Presenter accepts the UI request of the View, completes simple UI processing logic, calls the Model for business processing, and calls the View to reflect the corresponding results. The View directly depends on the Presenter, but the Presenter indirectly depends on the View, and it directly depends on the interface implemented by the View.

Compared with the passive View, the Presenter is the active party. The activeness of the Presenter can be understood as follows:

  • Presenter is the control center of the entire MVP system, not just someone who handles View requests;
  • View is only a reporter of user interaction requests. View does not participate in decision-making regarding the logic and processes related to responding to user interactions. The real decision-maker is the Presenter.
  • When View sends a user interaction request to Presenter, it should adopt the tone of "I will send the user interaction request to you now, you can handle it, and I will assist you when you need me", not like this: "I am processing the user interaction request now, I know what to do, but I need your support because the Model that implements the business logic only trusts you";
  • For data bound to the View, the View should not "pull" it back from the Presenter, but the Presenter should actively "push" it to the View;
  • View tries not to maintain data status as much as possible, because it only implements simple and independent UI operations; Presenter is the coordinator of the entire system, and it arranges work for View and Model according to the logic used for interaction.

Problems and solutions of MVP architecture

Add Template Method

After the transfer logic operation, there may still be a lot of code in some more complex Activities, so it is necessary to add a template method on the basis of layering.

The specific method is to layer the Activity. The top layer is BaseActivity, which does not display anything, but provides some basic styles, Dialog, ActionBar and other content. The Activity displayed to the user inherits BaseActivity and rewrites the reserved methods of BaseActivity. If necessary, perform secondary inheritance. The number of inheritances between Activities in the App shall not exceed 3 times.

Model Internal Layering

The overall amount of code in the model layer (Model) is the largest, and is generally composed of a large number of packages. What needs to be done for this part is to divide the modules, isolate the interfaces, and perform internal layering during the program design process.

Enhanced Presenter

Strengthening the role of the Presenter and placing all logical operations in the Presenter can easily lead to an excessive amount of code in the Presenter. For this, one method is to set up a mediator between the UI layer and the Presenter, and place lightweight logical operations such as data verification and assembly in the Mediator; use a proxy between the Presenter and the Model; and use the above two to share part of the Presenter's logical operations, but the control of the overall framework is still in the hands of the Presenter. Mediator and Proxy are not necessary, and are only recommended when the Presenter is overloaded.

The final architecture is shown in the figure below:

MVP code example

Let's take a look at how MVP is applied in Android development!!

Let us explain with another example.

Let's look at the package structure first

Creating Beans

  1. public class UserBean {
  2. private String mFirstName;
  3. private String mLastName;
  4. public UserBean(String firstName, String lastName) {
  5. this.mFirstName = firstName;
  6. this. mLastName = lastName;
  7. }
  8. public String getFirstName() {
  9. return mFirstName;
  10. }
  11. public String getLastName() {
  12. return mLastName;
  13. }
  14. }

Building Model

(Processing business logic, here refers to data reading and writing), write the interface first, then write the implementation

  1. public interface IUserModel {
  2. void setID( int id);  
  3. void setFirstName(String firstName);  
  4. void setLastName(String lastName);  
  5. int getID();  
  6. UserBean load ( int id); // Read user information by id and return a UserBean
  7. }

The implementation is not written here

Presenter Controller

Create a presenter (the main controller that operates the model and view through the iView and iModel interfaces). The activity can delegate all logic to the presenter, so that the Java logic is separated from the phone's activity.

  1. public class UserPresenter {
  2. private IUserView mUserView;
  3. private IUserModel mUserModel;
  4.  
  5. public UserPresenter(IUserView view ) {
  6. mUserView = view ;
  7. mUserModel = new UserModel();
  8. }
  9.  
  10. public void saveUser( int id, String firstName, String lastName) {
  11. mUserModel.setID(id);
  12. mUserModel.setFirstName(firstName);
  13. mUserModel.setLastName(lastName);
  14. }
  15.  
  16. public void loadUser( int id) {
  17. UserBean user = mUserModel. load (id);
  18. mUserView.setFirstName( user .getFirstName()); // Update the display by calling IUserView's method
  19. mUserView.setLastName( user .getLastName());
  20. }
  21. }

View

Create a view (update the view status in the UI). Here are the methods that need to operate the current view, which is also an interface

  1. public interface IUserView {
  2. int getID();  
  3. String getFristName();  
  4. String getLastName();  
  5. void setFirstName(String firstName);  
  6. void setLastName(String lastName); }

Implement the iview interface in the activity, operate the view in it, and instantiate a presenter variable.

  1. public class MainActivity extends Activity implements OnClickListener,IUserView {
  2.  
  3. UserPresenter presenter;
  4. EditText id, first , last ;
  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.activity_main);
  9.  
  10. findViewById(R.id. save).setOnClickListener( this);
  11. findViewById(R.id. load ).setOnClickListener( this);
  12. id = (EditText) findViewById(R.id.id);
  13. first = (EditText) findViewById(R.id. first );
  14. last = (EditText) findViewById(R.id. last );
  15.  
  16. presenter = new UserPresenter( this);
  17. }
  18.  
  19. @Override
  20. public void onClick( View v) {
  21. switch (v.getId()) {
  22. case R.id.save:
  23. presenter.saveUser(getID(), getFristName(), getLastName());
  24. break;
  25. case R.id.load :
  26. presenter.loadUser(getID());
  27. break;
  28. default :
  29. break;
  30. }
  31. }
  32.  
  33. @Override
  34. public   int getID() {
  35. return new Integer (id.getText().toString());
  36. }
  37.  
  38. @Override
  39. public String getFristName() {
  40. return   first .getText().toString();
  41. }
  42.  
  43. @Override
  44. public String getLastName() {
  45. return   last .getText().toString();
  46. }
  47.  
  48. @Override
  49. public void setFirstName(String firstName) {
  50. first .setText(firstName);
  51. }
  52.  
  53. @Override
  54. public void setLastName(String lastName) {
  55. last .setText(lastName);
  56. }
  57.  
  58. }

Therefore, the Activity is freed from the Controller in MVC, and the Activity mainly displays the View and interacts with the user. Each Activity can implement the View interface IUserView according to the different Views it displays.

By comparing the MVC and MVP codes of the same example, some advantages of the MVP pattern can be confirmed:

  • In MVP, the Activity code is not bloated;
  • In MVP, changes to the Model (implementation class of IUserModel) will not affect the Activity (View), and the two will not interfere with each other, while in MVC;
  • In MVP, the IUserView interface can facilitate testing of Presenter;
  • In MVP, UserPresenter can be used in multiple views, but not in Activity in MVC.

4. The relationship between MVC, MVP and MVVM

First, let me introduce MVVM.

MVVM

MVVM can be regarded as an upgraded version of MVP, where VM is the abbreviation of ViewModel. ViewModel can be understood as the combination of View's data model and Presenter. The interaction between ViewModel and View is completed through Data Binding, and Data Binding can realize two-way interaction, which further reduces the coupling between the view and control layer, separates concerns more thoroughly, and reduces the pressure on Activity.

Before comparing, let's look at the similarities and differences between the three from the picture.

When I first understood these concepts, I thought that although these modes all meant to decouple the view and model, it didn't matter if they were one or the other, and an application would only use one mode. Later, I gradually discovered that the world is definitely not just black and white, and the largest area in the middle is actually the gray area. Similarly, the boundaries of these modes are not so obvious, and you may use all of them in your own applications. In fact, there is no need to worry about whether you are using MVC, MVP or MVVP. It doesn't matter whether the cat is black or white, as long as it catches the mouse, it is a good cat.

Evolution from MVC->MVP->MVVM

MVC -> MVP -> MVVM are software design patterns that have evolved step by step. MVVM is a further development and specification of MVP. MVP isolates the direct connection between M and V in MVC and relies on Presenter for transfer. Therefore, when using MVP, P directly calls the View interface to implement operations on the view. The View interface is generally showData, showLoading, etc. M and V have been isolated, which is convenient for testing, but the code is not elegant and concise enough, so MVVM makes up for these defects. The concept of Data Binding appears in MVVM, which means that the implementation methods of the View interface showData can be omitted and implemented through Binding.

same

If we compare these three together, let's first talk about what they have in common, namely Model and View:

  • Model: Data object. It also provides an interface for external applications to operate on application data. It may also send change notifications when data changes. Model does not depend on the implementation of View. As long as the external program calls the Model interface, it can implement the addition, deletion, modification and query of data.
  • View: UI layer, which provides interactive operation functions for end users, including UI presentation code and some related interface logic code.

different

The difference between the three lies in how to bond View and Model to achieve user interaction and change notification.

Controller

The Controller receives the operation events of the View. Depending on the event, it either calls the Model's interface to perform data operations or redirects the View, which means that one Controller can correspond to multiple Views. The Controller does not care much about the implementation of the View and only receives it passively. The data changes of the Model are not directly notified to the View through the Controller. Usually, the View uses the observer mode to monitor the changes of the Model.

Presenter

The Presenter, like the Controller, receives commands from the View and operates on the Model. Unlike the Controller, the Presenter reacts to the View. The Model's change notification is first received by the Presenter, and then the Presenter updates the View. A Presenter corresponds to only one View. Depending on the degree to which the Presenter and View share the logic code, this mode has two cases: Passive View and Supervisor Controller.

ViewModel

Note that the "Model" here refers to the Model of the View, which is different from the Model in MVVM. The so-called Model of the View is something that contains some data attributes and operations of the View. The key technology of this model is data binding. Changes in the View will directly affect the ViewModel, and changes or contents of the ViewModel will also be directly reflected in the View. This model actually does some work for the application developer, and the developer only needs less code to implement more complex interactions.

Some thoughts

MVP and MVVM completely isolate the Model and View, but in some cases, the copying of data from the Model to the ViewModel or Presenter is very expensive, and it may also be combined with the MVC method, where the Model directly notifies the View to make changes. In actual applications, it is very likely that you have merged several modes together without realizing it, but for the scalability and testability of the code, the modules must be decoupled and unrelated codes should not be put together. There is a story on the Internet that when a person was making a new product in a company, a new employee of an outsourcing company directly performed database persistence operations in the View, and after a hibernate code was expanded, it was found that there were hundreds of lines of SQL statements, which surprised them and became a joke for a while.

In my opinion, when we talk about MVC architecture in a broad sense, we are not referring to the strict definition of MVC in this article, but to MV*, that is, the separation of view and model. As long as a framework provides the function of separating view and model, we can consider it to be an MVC framework. After further development, we can experience whether the framework we use is MVC, MVP or MVVM.

5. AOP-based framework design

AOP (Aspect-Oriented Programming), born in the 1990s, is a supplement and improvement to OOP (Object-Oriented Programming). OOP introduces concepts such as encapsulation, inheritance, and polymorphism to establish an object hierarchy to simulate a set of common behaviors. When we need to introduce common behaviors for scattered objects, OOP seems powerless. In other words, OOP allows you to define relationships from top to bottom, but is not suitable for defining relationships from left to right. For example, the logging function. The logging code is often horizontally scattered in all object hierarchies and has nothing to do with the core functions of the objects it is scattered to. The same is true for other types of code, such as security, exception handling, and transparent persistence. This kind of irrelevant code scattered everywhere is called cross-cutting code. In OOP design, it leads to a lot of code duplication, which is not conducive to the reuse of various modules. AOP technology is just the opposite. It uses a technology called "crosscutting" to dissect the internals of encapsulated objects and encapsulate those common behaviors that affect multiple classes into a reusable module, which is named "Aspect". The so-called "aspect" is simply to encapsulate those logics or responsibilities that are not related to the business but are commonly called by business modules, so as to reduce the duplication of system code, reduce the coupling between modules, and facilitate future operability and maintainability.

5.1 Use of AOP in Android

AOP divides the software system into two parts: core concerns and cross-cutting concerns. The main process of business processing is the core concern, and the part that is not closely related to it is the cross-cutting concern. A characteristic of cross-cutting concerns is that they often occur in multiple places of the core concern, and each place is basically similar. The role of AOP is to separate various concerns in the system and separate the core concerns from the cross-cutting concerns. In Android App, what are the cross-cutting concerns we need? I think they mainly include the following aspects: Http, SharedPreferences, Json, Xml, File, Device, System, Log, format conversion, etc. The requirements of Android App vary greatly, and the cross-cutting concerns of different requirements must be different. In general App projects, there should be a Util Package to store related aspect operations. After there are more projects, the Utils that are used more frequently can be encapsulated into a Jar package for project calls.

After using MVP and AOP to divide the App vertically and horizontally, the overall structure of the App can be made clearer and more reasonable, avoiding local code bloat, and facilitating development, testing, and subsequent maintenance.

6. Practical experience: Android App architecture design experience

First, here is the author’s favorite sentence, which is particularly applicable to startups and is also an interpretation of not over-designing:

  • Implement first, then refactor. If I just consider not making the code bloated, I don't know when I can finish it.
  • Implement first, then refactor. If I just consider not making the code bloated, I don't know when I can finish it.
  • Implement first, then refactor. If I just consider not making the code bloated, I don't know when I can finish it.

(Important things should be said three times)

6.1 Overall Architecture

Code and document specifications, module division according to requirements, determining interaction methods, and forming interface documents. These more common contents will not be elaborated. When making an Android App, the App is generally divided vertically and horizontally. The vertical App consists of the UI layer, the logic layer, and the model layer. The overall structure is based on the MVP concept (picture from the Internet).

The UI layer uses many template methods. For example, there is a BaseActivity in Activity, which provides some basic styles, Dialog, ActionBar and other content. The displayed Activity will inherit BaseActivity and implement the reserved interface. The inheritance between Activities does not exceed 3 times. To avoid too much code in Activity, the overall control of App is moved back. IOC practices are also used. A large number of logical operations are placed in the logic layer. The logic layer and UI layer communicate through interfaces or Broadcast, and only transmit results. Generally, the amount of code in an Activity is very large. Through these two methods, the amount of code in a single Activity I write does not exceed 400 lines.

The logic layer implements most of the logic operations, which are initiated by the UI layer. It calls the methods of the model layer through the interface internally, and uses a lot of agents in the logic layer. For example, the UI layer tells the logic layer what I need to do, and the logic layer finds the corresponding person (model layer) to do it, and finally only tells the UI the result of this thing.

There is not much to say about the model layer. This part is generally composed of a large number of packages. The amount of code is the largest among the three layers and needs to be layered internally.

Horizontal segmentation is based on the aspect-oriented concept of AOP, which mainly extracts common methods as a separate Util, which will be used in the entire App. Many people's Apps will introduce their own encapsulated Jar packages, which encapsulate common operations including files, JSON, SharedPreference, etc., which are easy to use and greatly reduce repetitive work.

This vertical and horizontal division of the App code can prevent the program from being piled up too much in one Java file, but it is difficult to write high-quality code in one development process. It is necessary to refactor the code during the project's intermission period.

6.2 Use of Class Library

There are many class libraries that help with rapid development. Making use of these class libraries is also a good way to avoid code bloat and confusion. Here are some commonly used class libraries recommended to the questioner.

ButterKnife, a dependency injection framework that reduces the amount of Activity code:

  • https://github.com/JakeWharton/butterknife

OrmLite, an object-relational mapping framework that simplifies SQLite operations:

  • https://github.com/j256/ormlite-android

Image caching library Fresco (by facebook):

  • https://github.com/facebook/fresco

Use third-party libraries if you can. Don't worry about whether they are stable or maintained, because any third-party library author can crush a beginner, and you will never be able to write better code than them.

<<:  Apple and Samsung fined heavily for deliberately slowing down their phones

>>:  The second half of Android developers

Recommend

4 Steps to Create a User Activation Closed Loop

The Internet’s demographic dividend is slowly dis...

The free lunch is over: Tesla Superchargers start charging

Tesla Motors announced on Monday that it will end ...

Can multi-screen interaction on smart TVs really improve user experience?

Multi-screen interaction centered on TV has gradu...

Analysis | Why is it becoming increasingly difficult to make Internet products?

Recently, Andrew Chen, head of user growth at Ube...

Can I use a photocopier to print money? (What a punishment!)

Easter egg: I found a young man who spoke out the...

Common content misunderstandings of low-follow Douyin sales accounts

Recently, many friends have been asking questions...

Liu Rongjun, "3M: How to build an innovative enterprise"

Liu Rongjun's "3M: How to Build an Innov...