First, worship again the next retrofit
Retrofit both the performance and the ease of use are very cock!!! , this article does not introduce its operating principle (although very want to understand), the following will be a feature article analysis of the internal principles of retrofit; This article is only from the use of the analysis retrofit implementation of multi-image/file, text upload function.
Second, the concept of introduction
1) Note @multipart
The literal understanding is related to the multimedia file, yes, the upload of pictures, files and so on must use this annotation, each part needs to use @part to annotate. See its notes
/** * denotes that's the request body is multi-part. Parts should is declared as parameters and * Annotated with {@link part @Part}. */
2) Note @partmap
Of course it can be understood to use @partmap annotations to pass multiple part to achieve multiple file uploads. Comments
/** * denotes name and value parts of a multi-part request. * <p> * Values of the map on which this annotation exists'll be processed in one of the ways: * <ul> * <l I>if the type is {@link okhttp3. Requestbody Requestbody} The value would be used * directly with its content type.</li> * <li>other Object type s'll be converted to an appropriate representation by using * {@linkplain Converter a converter}.</li> * </UL&G T * <p> * <pre><code> * @Multipart * @POST ("/upload") * call<responsebody> upload (* @Part ("fil E ") requestbody file, * @PartMap map<string, requestbody> params); * </code></pre> * <p> * a {@code null} value for the map, as a key, or as a value are not allowed. * * @see Multipart * @see Part */
3) Requestbody
As you can see from the comments above, the parameter type is Requestbody, which is the request body. File upload requires a parameter of requestbody. The official usage instructions are as follows http://square.github.io/retrofit/
Multipart parts Use one of the Retrofit ' s converters or they can implement requestbody to handle their own serialization.
Iv. Basic Realization
Understanding the above concepts, the following will be implemented
1) Interface Definition
Public interface Ihttpservice {@Multipart @POST ("nocheck/file/agree.do") call<basebean> Uploadagree ( @PartMap map<string, requestbody>params);}
The Basebean is defined based on the service-side return data, which can be defined according to its own server.
2) Retrofit Implementation
/** * Created by DELL on 2017/3/16. * Upload file with (include picture) */public class Retrofithttpupload {/** * Timeout time 60s */private static final long default_timeout = 60; Private volatile static retrofithttpupload minstance; Public Retrofit Mretrofit; Public Ihttpservice Mhttpservice; Private map<string, requestbody> params = new hashmap<string, requestbody> (); Private Retrofithttpupload () {mretrofit = new Retrofit.builder (). BASEURL (Urlconfig.root_url) . Client (Genericclient ()). Addconverterfactory (Gsonconverterfactory.create ()). Buil D (); Mhttpservice = Mretrofit.create (Ihttpservice.class); } public static Retrofithttpupload getinstance () {if (minstance = = null) {synchronized (retrofithtt Pupload.class) {if (minstance = = null) Minstance = new Retrofithttpupload (); }} return minstance; }/** * Add unifiedTime-out, HTTP log print * * @return */public static okhttpclient Genericclient () {httplogginginterceptor log Ging = new Httplogginginterceptor (); Logging.setlevel (HttpLoggingInterceptor.Level.BODY); Okhttpclient httpClient = new Okhttpclient.builder (). Addinterceptor (logging). Connecttimeou T (Default_timeout, Timeunit.seconds). WriteTimeout (Default_timeout, timeunit.seconds). Readt Imeout (Default_timeout, Timeunit.seconds). Build (); return httpClient; }/** * joins the call queue and implements the callback * * @param call calls to call * @param retrofitcallback callback * @param me Thod Call method Flag, call back * @param <T> generic parameter */public static <T> void Addtoenqueue (Cal L<t> call, Final retrofitcallback retrofitcallback, Final int method) {Final context context = MyApplication . GetContext (); Call.enqueue (New callback<t> () { @Override public void Onresponse (call<t> call, response<t> Response) {LOGUTIL.D ("Retrofit back code = = =" + Response.code ()); if (null! = Response.body ()) {if (response.code () = =) {LOGUTIL.D ("retrofit Back BODY = = "+ new Gson (). ToJson (Response.body ())); Retrofitcallback.onresponse (response, method); } else {LOGUTIL.D ("Toenqueue, Onresponse Fail:" + response.code ()); Toastutil.makeshorttext (Context, "Network connection Error" + Response.code ()); Retrofitcallback.onfailure (response, method); }} else {LOGUTIL.D ("Toenqueue, Onresponse Fail m:" + response.message ()); Toastutil.makeshorttext (Context, "Network connection Error" + response.message ()); Retrofitcallback.onfailure (response, method); } } @Override public void OnFailure (call<t> call, Throwable T) {LOGUTIL.D ("to Enqueue, Onresponse Fail unKnown: "+ t.getmessage ()); T.printstacktrace (); Toastutil.makeshorttext (Context, "Network connection Error" + t.getmessage ()); Retrofitcallback.onfailure (null, method); } }); /** * Add parameter * To determine whether a parameter is a string or a file type according to the incoming Object object */Public retrofithttpupload Addparameter (string key, Object o) {if (o instanceof String) {Requestbody BODY = requestbody.create (Mediatype.parse ("Text/plai N;charset=utf-8 "), (String) o); Params.put (key, body); } else if (o instanceof File) {Requestbody BODY = requestbody.create (Mediatype.parse ("Multipart/form-data;char Set=utf-8 "), (File) o); Params.put (key + "\"; filename=\ "" + ((File) O). GetName () + "", body); } return this; }/** * Build Requestbody */Public MAP< String, requestbody> Bulider () {return params; }}
The retrofit instance is defined, the unified timeout time and the log print are defined with the interceptor, the call is queued and the callback is implemented. The most important thing is to add parameters:
/** * Add parameter * To determine whether a parameter is a String or a file type according to the incoming object object * /Public retrofithttpupload Addparameter (string Key, Object o) { if (o instanceof String) { Requestbody BODY = requestbody.create (Mediatype.parse ("Text/plain; Charset=utf-8 "), (String) o); Params.put (key, body); } else if (o instanceof File) { Requestbody BODY = requestbody.create (Mediatype.parse ("multipart/form-data;charset= UTF-8 "), (File) o); Params.put (key + "\"; filename=\ "" + ((File) O). GetName () + "", body); } return this; }
This is to return the different requestbody according to the parameters passed in.
3) Use
private void Uploadagree () {showwaitdialog (); Retrofithttpupload retrofithttpupload = Retrofithttpupload.getinstance (); if (! Stringutil.isempty (Pathimage[0])) {retrofithttpupload = Retrofithttpupload.addparameter ("Pic1", New File (PathIma Ge[0])); } if (! Stringutil.isempty (Pathimage[1])) {retrofithttpupload = Retrofithttpupload.addparameter ("Pic2", New File (pathIm AGE[1])); } if (! Stringutil.isempty (Pathimage[2])) {retrofithttpupload = Retrofithttpupload.addparameter ("Zip", new File (PathIma GE[2])); } map<string, requestbody> params = retrofithttpupload. Addparameter ("Status", "4") . Addparameter ("Pickupid", Tv_orderquality_pid.gettext (). toString ()). Addparameter ("cause", reason) . Addparameter ("Connectname", Et_orderquality_lxrname.gettext (). toString ()). Addparameter ("Conne Ctphone ", Et_orderquality_lxrphone.gettext (). ToString ()). Addparameter ("Details", Et_orderquality_xqms.gettext (). ToString ()). Bulider (); Retrofithttpupload.addtoenqueue (Retrofithttpupload.getinstance (). Mhttpservice.uploadagree (params), this, httpstaticapi.http_uploadagree); }
Note that the image and file path to the empty operation, responsible for the report exception w/system.err:java.io.filenotfoundexception:/: Open Failed:eisdir (is a directory)
??
"Android Combat"----based on retrofit implementation of multi-image/file, text upload