Android Architecture Chapter
Mvp+rxjava+retrofit+eventbus
The high-level should not know the low-level details, should be oriented to abstract programming. The implementation of the business is entrusted to the class of the implemented interface. The top level is only responsible for calling.
First, let's take a look at the benefits of a good architecture in a project: Good software design must help developers develop and expand solutions, keep code robust, scalable, and easy to maintain without rewriting the code for everything. Faced with the problems of software, we must abide by the solid principle (object-oriented Five principles), do not over engineering, as far as possible, reduce the dependence of modules in the framework.
Some time ago, learned some new technology, and put their own attention to the technology, yes, there are many similar technology, their choice to choose, their ideas and technology applied to their own built project framework.
Limited to their own ability to build the project may still have some deficiencies, you are welcome to correct the criticism, so that their ideas and design ideas on the right track. O (∩_∩) o Thank you ~ in the frame
1. The overall framework of the project: using Google-clean-architecture's ideas to be responsible for the overall MVP architecture of the project.
The MVP is the abbreviation for model, view, moderator (presenter), representing 3 different modules in the project. I use the login as an example to illustrate.
Here each business must first have a management interface contract, in which there are three interfaces to interface programming, (Model), (View), (presenter). Put three interfaces together for easy management.
/**
* Login Associated interface class
*
* Created by CCJ on 2016/7/7.
* * Public
interface Logincontract {
interface View extends Baseview {
void showprogress ();
void Hideprogress ();
void ShowError (String error);
void Navigatetomain ();
void Navigatetoregister ();
}
Interface Presenter extends Basepresenter {
void Login (string username, string password);
void OnDestroy ();
}
Interface model{
void saveuserinfo (user user);
void Saveloginstate (Boolean islogin);
void Saverememberpass (user user);
}
Model: Implement implements Logincontract.model responsible for processing data loading or storage, such as accessing data from a network or local database; Login here The business logic involved is less request network using the Rxjava +retroft+gsons equivalent to the model layer. If the processing of the issue of more, the use of this model, like the picture save display and so on.
view: The interface in the way, let the activity implementation of the interface, the interface has a view of the method, such as "Initview ()", "ShowDialog ()", "Hidedialog ()" And so on, responsible for the interface data display, interact with the user;
public class Loginactivity extends Baseactivity implements Logincontract.view {
//omit bufferknife annotation
private Loginpresenter presenter;
@Override public
void OnCreate (Bundle savedinstancestate) {
super.oncreate (savedinstancestate);
Setcontentview (r.layout.activity_login);
Butterknife.bind (this);
Presenter=new Loginpresenter (this);
Presenter.start ()///Initialize control layer
}
//View-implemented method
@Override public
void Navigatetomain () {
Intent Intent =new Intent (Getbasecontext (), mainactivity.class);
Intent.setflags (Intent.flag_activity_new_task | Intent.flag_activity_clear_task);
StartActivity (intent);
}
Moderator (Presenter): An object that holds view and model, a method of manipulating both. The equivalent of the coordinator is the bridge between the model and the view, separating the model from the view, and scheduling the view and model.
/** * Login's presenter layer controls the view and model, * Created by CCJ on 2016/7/7.
* * Public class Loginpresenter implements Logincontract.presenter {private Logincontract.view loginView;
Public Loginpresenter (Logincontract.view loginView) {this.loginview = LoginView;
@Override public void Login (string username, string password) {loginview.showprogress ();
observable<user> userobservable = apiservice.userlogin (username, password); Userobservable.subscribeon (Schedulers.io ()). Observeon (Androidschedulers.mainthread ()). Su
Bscribe (New subscriber<user> () {@Override public void oncompleted () {
Loginview.hideprogress (); @Override public void OnError (Throwable e) {TLog.log (E)
. GetMessage (). toString ()); Loginview.hideprogress ();
Loginview.showerror (E.getmessage (). toString ());
@Override public void OnNext (User getipinforesponse) {
TLog.log (Getipinforesponse.tostring ());
Loginview.navigatetomain ();
}
});
@Override public void Start () {}
2. Network access: Use Rxjava+retrofit+gson for network access, and easily convert JSON to object, structure clear, easy to use. Initialize retrofit in Apiservice
/** * Calls the backend interface, and the architecture network layer uses Retroft+rxjava+gson * Created by the CCJ on 2016/7/1.
* */public class Apiservice {private static final String TAG = "Apiservice"; public static final String url_host = "http://123.234.82.23";/server port/** * Base Address * Initialize Retroft/PR Ivate static final Retrofit Sretrofit = new Retrofit.builder (). BaseURL (url_host). Addconverterfac Tory (Gsonconverterfactory.create ()). Addcalladapterfactory (Rxjavacalladapterfactory.create ())//use Rxjava as callback
Orchestration. Build ();
private static final Retrofitrequest Apimanager = sretrofit.create (Retrofitrequest.class); /** * Login, return, my side is a JSON-formatted post, you can choose * @param city * @return/public static Observable<user
> Userlogin (string Format, String city) {hashmap<string,string> HashMap =new hashmap<> ();
Hashmap.put ("Userphone", format);
Hashmap.put ("UserPassword", city); TLog.log (HashMap.ToString ());
observable<user> ss = Apimanager.userlogin (HASHMAP);
return SS;
/********************** the above method to make the request data ****************************/
use retrofit to access objects returned observable
Public interface Retrofitrequest {
Boolean istest=true//whether to
change the
String base_url_test = "before the test environment//Publish flyapptest/"//test server
string base_url_offical ="/flyapp/";//Official server
string base_url = Istest? base_url_test:base_url_offical;//Publisher
/**
* Login back (JSON post)
* @param body
* @return
* Headers ("Content-type:application/json")
@POST (base_url+ "login.ashx/")
observable<user> Userlogin (@Body hashmap<string, string> body);
3. Asynchronous processing: Using the Rxjava response framework for elegant asynchronous processing, simplifying the code logic, and a good solution to the memory leak problem. (related modules in the Takephoto business)
/** * Rxjava Asynchronous Operation Eventbus for time delivery * @param data */@Override public void Savephoto (final Intent
Data) {TLog.log ("Savephoto", "data-->" + data.getdata (). toString ());
LOG.E ("tlog-->", "data-->" + data.getdata (). toString ()); saveobservable = observable.fromcallable (new callable<string> () {@Override public String CA
LL () throws Exception {//Notification call and returns string return Savepic (data);//This method calls in IO thread and returns}});
Savesubscription = saveobservable. Subscribeon (Schedulers.io ())//observable scheduling in IO threads in scheduling . Observeon (Androidschedulers.mainthread ())//is observed in the main thread. Subscribe (new observer<string> () { Subscribe observer @Override public void oncompleted () {LOG.E ("tlog-
-> "," oncompleted--> "); } @Override Public void OnError (Throwable e) {log.e ("tlog-->", "throwable-->" + e.getmessage (). toString ());
Eventbus.getdefault (). Post (New Eventutils.objectevent (E.getmessage (). toString ()));
@Override public void OnNext (String s) {//The next step with parameters, this is when
LOG.E ("tlog-->", "s-->" + s);
Eventbus.getdefault (). Post (new Eventutils.objectevent (bitmap));
}
}); }
4. Event Subscriptions: Use Eventbus as the event bus for communication between threads and components .
the/** * Event bus is used for component or thread communication and can be substituted for callbacks, broadcasts, etc.
* Created by CCJ on 2016/4/14.
*
/public class Eventutils {
/**
* Object Type (that is, all traditional types can be strongly transferred to the delivery event)/public
static class objectevent{
Private Object object;
Public ObjectEvent (Object object) {
//TODO auto-generated constructor stub
this.object = Object;
}
Public Object getmsg () {return
Object;
}
}
}
5. Code subcontracting: Subcontracting according to business distinction for easy management of code.
6. Tool class: Tdeviceutils device state Tool class, seriliazebleutils serialization Tool class, Sharepreferenceutils save tool class,
Related please refer to the code
7.app Stack Management: Based on baseactivity, good release of memory, management of memory.
Related please refer to the code to be completed later
exception capture (to be perfected)
test Framework espresso/junit/mockito/robolectric (to be perfected)
Gradle related build compilation Summary
1. The level is distinct, each level regardless of each other how realizes, only concerns the result;
2. The MVP architecture is used in the view layer (presentation Layer) to make the original bloated activity (or fragment) simple, and the processing method is given to presenter.
3. Easy to test, as long as the unit test based on each module alone to ensure the overall stability.
4. Easy to quickly iterate, based on the low coupling of code, simply add the interface to the business logic, and then implemented at the corresponding level, without affecting other functions. Code-link
--[GitHub open stream code address, welcome everyone star~,follow, I will continue to improve, your concern is my driving force to move forward.