APP-component/Modular approach-how to encapsulate the network request framework
In APP development, network requests are a must-have for every developer, and many excellent open-source network request libraries appear. For example
- Okhttp
- Retrofit
- Android-async-http
These network request libraries greatly improve the coding efficiency of the program ape. But as the business grows, apps are getting bigger, and we're adding these network request libraries to the project for direct use, and the intrusion on our business class is strong. These network request codes would be a stumbling block to our further work if we were to do business separation . is very painful for the developer.
Therefore, the network request framework we are building can address the following issues:
- Separating business and network request codes
- The network library can be easily replaced
- Network library can be easily reused
So in the context of APP component/Modular development architecture, we use network requests as a component of the kernel layer .
Encapsulating a third-party network request interface
In general, most applications currently use the HTTP protocol for data requests, whereas the protocol for data Exchange uses the JSON format. Therefore, a common request interface can be encapsulated. (There are, of course, other protocols, such as Mars, but the encapsulation idea is consistent, this article for the sake of simple explanation, temporarily use the General Network request framework, do not rule out the future of the Mars package)
Preview the frame structure first
Irequest
This class encapsulates the common interface for network requests, defines the request interface, doRequest()
gets the request connection getUrl()
, gets the request method, getHttpMethod()
and so on.
Public InterfaceIrequest {enumHttpMethod {GET, POST, PUT, DELETE}//... To reduce the length of the code, omit some fragments that are not important to this article, this code can be//https://github.com/wecodexyz/Componentizationget to voidAddparams (map<string, string>params); String GetUrl (); Pair<integer, string>dorequest (); BooleanIssupportcache (); voidAddHeader (string key, String value); HttpMethod Gethttpmethod (); //... To reduce the length of the code, omit some fragments that are not important to this article, this code can be//https://github.com/wecodexyz/Componentizationget to}
Request
This class is an abstract class, a pair IRequest
of implementations. is currently a simple package implementation.
Requestwrapper
This class is a generic class that inherits from Request
and encapsulates a third-party request library. For example, this article is about okhttp
encapsulation, and generic T objects are the specific data types that are requested. If you want to encapsulate other request libraries, you can refer to the implementation of this class.
Note that this class encapsulation is purely a network request and should not contain code related to the business class. Otherwise, there is no solution to the three questions raised above.
Public Abstract classRequestwrapperextendsRequest {//... To reduce the length of the code, omit some fragments that are not important to this article, this code can be//https://github.com/wecodexyz/Componentizationget to@Override PublicPair<integer, string>dorequest () {Pair<integer, string> result =NewPair<> (Error_network, ""); OKHTTP3. Request Request=NULL; if(Gethttpmethod () = =httpmethod.post) {Request=requestbuilder (). URL (GetUrl ()). Post (Requestbody ()). build (); } Else{Request=requestbuilder (). URL (Geturlwithparams ()). build (); } Try{Response Response=Mclient.newcall (Request). Execute (); if(Response.issuccessful ()) {result=NewPair<>(Response.code (), Response.body (). String ()); } Else{result=NewPair<>(Response.code (), Response.message ()); } } Catch(IOException e) {log.e (TAG, E.getmessage ()); } returnresult; } //... To reduce the length of the code, omit some fragments that are not important to this article, this code can be//https://github.com/wecodexyz/Componentizationget to}
The key code is in the doRequest()
method, which implements the code for the network request and returns an Pair<Integer,String>
object that first
is a request code
that identifies the network request code (that is, 200,404,301 of the network request returned). And second
that is the data requested by the network.
Basetextrequest
This class is the interface that the network request framework provides to the business class. In the beginning of this article, JSON was proposed as a protocol for interactive data requests. This type of encapsulation facilitates access to business data.
Public Abstract classBasetextrequest<t>extendsRequestwrapper { PublicBasetextrequest (Context context) {Super(context); } PublicFlowable<t>request () {returnFlowable.fromcallable (NewCallable<pair<integer, string>>() {@Override PublicPair<integer, string> call ()throwsException {Pair<integer, string> result =dorequest (); returnresult; }}). FlatMap (NewFunction<pair<integer, String>, publisher<t>>() {@Override PublicPublisher<t> Apply (@NonNull Pair<integer, string> Pair)throwsException {if(Issuccessful (Pair.first)) {returnFlowable.just (Onrequestfinish (Pair.second)); } returnFlowable.just (Onrequesterror (Pair.first, Pair.second)); } }); } @Override Public BooleanIssupportcache () {return true; } protected AbstractT onrequestfinish (String result); protected AbstractT Onrequesterror (intcode, String message);}
Because the request network is a time-consuming operation, RXJAVA2 to implement the network request asynchronous operation. request
is the encapsulation of the Requestwrapper.dorequest () method and gets an Flowable
object. At the same time, onRequestFinish()
onRequestError()
two methods are defined.
These two methods are the logic to be handled by the specific business class.
Simpletextrequest
Suppose there is a request for a business data interface, and the return data is a string. So that's how we use our framework. This example is a request for README.MD content in our project. It is very simple to use, as long as it inherits from the Basetextrequest, and implements getUrl()
, and onRequestFinish()
onRequestError()
getHttpMethod()
these several methods.
Note This is strictly a business class, so it should not be placed in the core directory.
Public classSimpletextrequestextendsBasetextrequest<string> { PublicSimpletextrequest (context context, map<string, string>params) { Super(context); Addparams (params); } @Override PublicString GetUrl () {return"Https://raw.githubusercontent.com/wecodexyz/Componentization/master/README.md"; } @Override PublicHttpMethod Gethttpmethod () {returnHttpmethod.get; } @Overrideprotectedstring Onrequestfinish (string result) {//This enables parsing of JSON data, such as the use of Jsonobject//object resolution for specific business returnresult; } @OverrideprotectedString Onrequesterror (intcode, String message) { returnmessage; }}
Test Request Framework
Request =NewSimpletextrequest ( This,NULL); Request.request (). Subscribeon (Schedulers.computation ()). Observeon (Androidschedulers.mainth Read ()). Subscribe (NewConsumer<string>() {@Override Public voidAccept (@NonNull String s)throwsException {textview.settext (s); //This returns the data requested by the interface. } }, NewConsumer<throwable>() {@Override Public voidAccept (@NonNull throwable throwable)throwsException {textview.settext (Throwable.getmessage ()); } });
Results of this article run
Project Address: Https://github.com/wecodexyz/Componentization
Follow us to get more
APP-component/Modular approach-how to encapsulate the network request framework