Android Architecture Chapter Mvp+rxjava+retrofit+eventbus
High-level should not know the details of the lower levels, should be oriented to abstract programming. The implementation of the business is given to the class of the implemented interface. The upper level is only responsible for invocation.
First, let's look at the benefits of a good architecture in a project: Good software design must help developers develop and augment solutions, keep code clear and robust, extensible, and maintainable, without having to rewrite the code for everything. In the face of software problems, we must abide by the solid principle (object-oriented Five principles), not over-engineering, to minimize the dependencies of the module in the framework.
A while ago, learned some new technology, and the technology to integrate their attention, yes, similar techniques have many, their own choice, their ideas and technology to apply their own construction project framework.
Limit oneself ability level Limited, oneself build project may still have some insufficiency, welcome everybody to criticize, let own idea and design thought go on track. O (∩_∩) o Thank you ~
In the framework
1. overall framework of the project: use Google-clean-architecture's ideas to be responsible for the overall MVP architecture of the project.
The MVP is the abbreviation for the model, view, host (Presenter), representing 3 different modules in the project, respectively. I use the login as an example to illustrate.
Here each business first has a management interface contract, in which there are three interfaces for interface programming, (Model), (View), (Presenter). Put three interfaces together for ease of management.
/** * Login Association Interface class * * Created by CCJ on 2016/7/7. * * Public interface logincontract {Interface View extends Baseview {voidShowProgress ();voidHideprogress ();voidShowError (String error);voidNavigatetomain ();voidNavigatetoregister (); } interface Presenter extends Basepresenter {voidLogin (string username, string password);voidOnDestroy (); } Interface model{voidSaveuserinfo (user user);voidSaveloginstate (Boolean islogin);voidSaverememberpass (user user); }}
Model: The implementation of implements Logincontract.model is responsible for processing the loading or storage of data, such as from the network or local database to obtain data, etc. here login involves less business logic request Network The Rxjava +retroft+gsons is equivalent to the model layer. If the processing of the issuance of more, the use of this model, like the picture saved display and so on.
View: In the way of the interface, let the activity implement the interface, the interface has a view of the method, such as "Initview ()", "ShowDialog ()", "Hidedialog ()" And so on, responsible for the interface data display, interaction with the user;
Public class loginactivity extends baseactivity implements Logincontract. View {//Omit Bufferknife annotationsPrivateLoginpresenter presenter;@Override Public void onCreate(Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate); Setcontentview (R.layout.activity_login); Butterknife.bind ( This); Presenter=NewLoginpresenter ( This); Presenter.start ();//Initialize the control layer}//How to implement the View@Override Public void Navigatetomain() {Intent Intent =NewIntent (Getbasecontext (), mainactivity.class); Intent.setflags (Intent.flag_activity_new_task | Intent.flag_activity_clear_task); StartActivity (intent);}
- Moderator (Presenter): A method that holds the object of view and model, and how to manipulate both. The equivalent of a coordinator is a bridge between the model and the view, separating the model from the view and dispatching 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 { PrivateLogincontract.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 ()). Subs Cribe (NewSubscriber<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 objects, structure clear, easy to use.
- Initialize the retrofit in Apiservice
/** * Call the Backend interface, the architecture network layer uses Retroft+rxjava+gson * Created by CCJ on 2016/7/1. * */ Public class apiservice { Private Static FinalString TAG ="Apiservice"; Public Static FinalString Url_host ="http://123.234.82.23";//Server Port /** * Base Address * Initialization Retroft */ Private Static FinalRetrofit Sretrofit =NewRetrofit.builder (). BASEURL (Url_host). Addconverterfactory (Gsonconverterfactory.create ()) . Addcalladapterfactory (Rxjavacalladapterfactory.create ())//Use Rxjava as callback adapter. build ();Private Static FinalRetrofitrequest Apimanager = sretrofit.create (Retrofitrequest.class);/** * Login, return, I use the JSON format of post, you can choose * @param City * @return * * Public StaticObservable<user>Userlogin(string format, String city) {Hashmap<string,string> HashMap =NewHashmap<> (); Hashmap.put ("Userphone", format); Hashmap.put ("UserPassword", city); TLog.log (Hashmap.tostring ()); observable<user> ss = Apimanager.userlogin (HASHMAP);returnss }/********************** the request data in the above method ****************************/
- use retrofit to access objects returning observable
Public interface retrofitrequest { Booleanistest=true;//Whether in the test environment //change before postingString base_url_test ="/flyapptest/";//test ServerString base_url_offical ="/flyapp/";//Official ServerString Base_url = istest? base_url_test:base_url_offical;//Publishing Server /** * Login back (JSON post) * @param body * @return */ @Headers("Content-type:application/json")@POST(base_url+"login.ashx/") observable<user> Userlogin (@BodyHashmap<string, string> body);
3. Asynchronous processing: Elegant asynchronous processing with the Rxjava response framework simplifies code logic and resolves memory leak issues well. (related modules in Takephoto business)
/** * Rxjava Asynchronous Operation Eventbus Time pass * @param Data * * @Override Public void Savephoto(FinalIntent data) {TLog.log ("Savephoto","Data-->"+ Data.getdata (). toString ()); LOG.E ("Tlog-->","Data-->"+ Data.getdata (). toString ()); Saveobservable = Observable.fromcallable (NewCallable<string> () {@Override PublicStringPager()throwsException {//Notify Call and return string returnSavepic (data);//This method is called in the IO thread and returns} }); Savesubscription = saveobservable. Subscribeon (Schedulers.io ())//observable is scheduled in the IO thread in the dispatch. Observeon (Androidschedulers.mainthread ())//Observe in the main thread. Subscribe (NewObserver<string> () {//Subscribe to observers @Override Public void oncompleted() {LOG.E ("Tlog-->","Oncompleted-->"); }@Override Public void OnError(Throwable e) {LOG.E ("Tlog-->","Throwable-->"+ E.getmessage (). toString ()); Eventbus.getdefault (). Post (NewEventutils.objectevent (E.getmessage (). toString ())); }@Override Public void OnNext(String s) {//With parameter Next, here is whenLOG.E ("Tlog-->","S-->", T); Eventbus.getdefault (). Post (NewEventutils.objectevent (bitmap)); } }); }
4. Event Subscription: Use Eventbus as the event bus to communicate between threads and components.
/** * Event bus is used for component or thread communication, alternative callbacks, broadcasts, etc. * Created by CCJ on 2016/4/14. * * Public class eventutils { /** * Object Type (that is, all traditional types can be strongly forwarded for transitive events) */ Public Static class objectevent{ PrivateObject object; Public objectevent(Object object) {//TODO auto-generated constructor stub This. Object = object; } PublicObjectgetmsg(){returnObject } }}
5. Code subcontracting: Subcontracting based on business differentiation for easy management of code.
6. Tool class: Tdeviceutils Device Status Tool class, Seriliazebleutils serialization Tool class, sharepreferenceutils Save Tool class,
Please refer to the code for related
7.app Stack Management: Based on baseactivity, it's good to free up memory and manage memory.
Please refer to the code for related
To finish later
exception capture (to be perfected)
test Framework espresso/junit/mockito/robolectric (to be perfected)
Gradle related Build compilation
Summarize
1. Clear hierarchy, regardless of how the other party to achieve, only focus on the results;
2. Using the MVP architecture at the View layer (Presentation layer) makes the original bloated activity (or fragment) simple, and its handling 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 low-coupling code, simply add the interface to the business logic and then implement it separately at the appropriate level, without compromising other functionality.
Code-link
--[GitHub Open the code address, welcome everyone star~,follow, I will continue to improve, your concern is my motivation to move forward]
[Android Architecture article]mvp+rxjava+retrofit+eventbus