Retrofit實現圖文上傳至服務器


Retrofit實現圖文上傳至服務器

 

前言:現在大多數的項目中都涉及圖片+文字上傳了,下面請詳見實現原理:

 

開發環境:AndroidStudio

 

1.引入依賴

compile 'com.squareup.retrofit2:retrofit:2.1.0'  

 

2.網絡權限

<uses-permission android:name="android.permission.INTERNET" />  

 

3.創建上傳對象OkHttpClient :

private static final OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request = chain
                            .request()
                            .newBuilder()
                            .build();
                    return chain.proceed(request);
                }
            })
            .readTimeout(10, TimeUnit.SECONDS)//設置讀取超時時間
            .writeTimeout(10, TimeUnit.SECONDS)//設置寫的超時時間
            .connectTimeout(15, TimeUnit.SECONDS)//設置連接超時時間
            .build();

 

4.上傳圖片的公有方法

    private synchronized final static void uploadImgAndParameter(Map<String, Object> map, String url,
                                                                 final UIDataListener listener) {

        // mImgUrls為存放圖片的url集合
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);

        if (null != map) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                if (entry.getValue() != null) {
                    if (entry.getValue() instanceof File) {
                        File f = (File) entry.getValue();
                        builder.addFormDataPart(entry.getKey(), f.getName(), RequestBody.create(MEDIA_TYPE_PNG, f));
                    } else {
                        builder.addFormDataPart(entry.getKey(), entry.getValue().toString());
                    }
                }

            }
        }
        //創建RequestBody
        RequestBody body = builder.build();

//        MultipartBody requestBody = builder.build();
        //構建Request請求
        final Request request = new Request.Builder()
                .url(url)//地址
                .post(body)//添加請求體
//                .post(requestBody)//添加請求體
                .build();
        client.newCall(request).enqueue(new okhttp3.Callback() {

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                if (response.isSuccessful()) {//判斷是否成功
                    final String data = response.body().string();//string()僅可調用一次。否則報IllegalStateException: closed異常
                    Log.i("file1", "上傳照片成功-->" + data);
                    onSuccess(listener, data);
                    call.cancel();//上傳成功取消請求釋放內存
                }
            }
            @Override
            public void onFailure(Call call, final IOException e) {

                Log.i("file2", "上傳失敗-->" + e.getMessage());
                String msg = e.getMessage();
                if (msg == null || msg.equals("timeout")) {
                    onError(listener, "網絡不穩定請求超時!");
                } else {
                    onError(listener, e.getMessage());
                }
                call.cancel();//上傳失敗取消請求釋放內存
            }
        });
    }

//注意:添加手機圖片,別忘了添加SD卡權限

5.全部代碼:

public class HttpUtil {

    private static final Handler handler = new Handler(Looper.getMainLooper());

    private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/*");

    private static final OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request = chain
                            .request()
                            .newBuilder()
                            .build();
                    return chain.proceed(request);
                }
            })
            .readTimeout(10, TimeUnit.SECONDS)//設置讀取超時時間
            .writeTimeout(10, TimeUnit.SECONDS)//設置寫的超時時間
            .connectTimeout(15, TimeUnit.SECONDS)//設置連接超時時間
            .build();


    /**
     * 實例--》添加商品
     */
    public static void addCoupon( int shopperId,String shopperName,
                                 File file, final UIDataListener listener) {
        String url = "shopappajx/shopAppCouponAction_saveCoupon.htm";
        Map<String, Object> map = new HashMap<>();
        map.put("shopperId", shopperId);
        map.put("shopperName", shopperName);
        map.put("couponImage", file);//商品圖片
        uploadImgAndParameter(map, url, listener);
    }

    //上傳圖片共有方法
    private synchronized final static void uploadImgAndParameter(Map<String, Object> map, String url,
                                                                 final UIDataListener listener) {

        // mImgUrls為存放圖片的url集合
        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);

        if (null != map) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                if (entry.getValue() != null) {
                    if (entry.getValue() instanceof File) {
                        File f = (File) entry.getValue();
                        builder.addFormDataPart(entry.getKey(), f.getName(), RequestBody.create(MEDIA_TYPE_PNG, f));
                    } else {
                        builder.addFormDataPart(entry.getKey(), entry.getValue().toString());
                    }
                }

            }
        }
        //創建RequestBody
        RequestBody body = builder.build();

//        MultipartBody requestBody = builder.build();
        //構建Request請求
        final Request request = new Request.Builder()
                .url(url)//地址
                .post(body)//添加請求體
//                .post(requestBody)//添加請求體
                .build();
        client.newCall(request).enqueue(new okhttp3.Callback() {

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                if (response.isSuccessful()) {//判斷是否成功
                    final String data = response.body().string();//string()僅可調用一次。否則報IllegalStateException: closed異常
                    Log.i("file1", "上傳照片成功-->" + data);
                    onSuccess(listener, data);
                    call.cancel();//上傳成功取消請求釋放內存
                }
            }
            @Override
            public void onFailure(Call call, final IOException e) {

                Log.i("file2", "上傳失敗-->" + e.getMessage());
                String msg = e.getMessage();
                if (msg == null || msg.equals("timeout")) {
                    onError(listener, "網絡不穩定請求超時!");
                } else {
                    onError(listener, e.getMessage());
                }
                call.cancel();//上傳失敗取消請求釋放內存
            }
        });
    }

    private final static void onSuccess(final UIDataListener listener, final String data) {
        handler.post(new Runnable() {
            public void run() {
                // 需要在主線程的操作。
                listener.onSuccess(data);
            }
        });
    }

    private final static void onError(final UIDataListener listener, final String msg) {
        if (null != listener) {
            handler.post(new Runnable() {
                public void run() {
                    // 需要在主線程的操作。
                    listener.onFailure(msg);
                }
            });
        }
    }

    public interface UIDataListener {
     //網絡請求成功
        void onSuccess(String data);

      //網絡請求失敗
        void onFailure(String errorMassage);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM