OkhttpApi.java 7.61 KB
package com.polysoft.nafmii.net;

import android.util.Log;

import androidx.annotation.NonNull;

import com.polysoft.nafmii.utils.IOUtils;
import com.whaty.nafmii.BuildConfig;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.Okio;
import okio.Sink;

public class OkhttpApi {

    private static OkHttpClient client = null;

    private OkhttpApi() {
    }

    public static OkHttpClient getInstance() {
        if (client == null) {
            synchronized (OkhttpApi.class) {
                if (client == null) {
                    client = new OkHttpClient.Builder()
                            .addInterceptor(new RequestInterceptor())
                            .build();
                }
            }
        }
        return client;
    }

    public static void doGet(String url, RequestBack callback) {
        doGet(url, null, callback);
    }

    public static void doGet(String url, Map<String, String> param, RequestBack callback) {
        String newUrl = BuildConfig.API_HOST + url;
        HttpUrl.Builder builder = HttpUrl.parse(newUrl).newBuilder();
        if (null != param && !param.isEmpty()) {
            for (Map.Entry<String, String> entry : param.entrySet()) {
                builder.addQueryParameter(entry.getKey(), entry.getValue());
            }
        }
        Request.Builder request = buildRequest(1);
        request.url(builder.build()).get();
        getInstance().newCall(request.build()).enqueue(new CallbackImpl(callback));
    }


    public static void doPost(String url, String param, RequestBack callback) {
        String newUrl = BuildConfig.API_HOST + url;
        MediaType mediaType = MediaType.parse("application/json;charset=UTF-8");
        RequestBody body = RequestBody.create(param, mediaType);

        Request.Builder request = buildRequest(1);
        request.url(newUrl).post(body);
        getInstance().newCall(request.build()).enqueue(new CallbackImpl(callback));
    }

    public static void doUpload(String url, File file, RequestBack callback) {
        doUpload(url, file, null, callback);
    }

    public static void doUpload(String url, File file, Map<String, String> param, RequestBack callback) {

    }

    public static void doDownload(String url, final File file, IDownListener downListener) {
        if (null == downListener) {
            downListener = new IDownListener() {
                @Override
                public void onProgress(int progress) {

                }

                @Override
                public void onFail() {

                }
            };
        }
        Request request = new Request.Builder().url(url).build();
        IDownListener finalDownListener = downListener;
        getInstance().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                finalDownListener.onFail();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if (!response.isSuccessful()) {
                    finalDownListener.onFail();
                    return;
                }

                ResponseBody body = response.body();
                long total = body.contentLength();
                if (file.exists()) {
                    file.delete();
                }
                FileOutputStream fos = new FileOutputStream(file);
                InputStream stream = body.byteStream();
                if (total < 0) {
                    total = stream.available();
                }
                try {
                    int len = 0;
                    long sum = 0;
                    byte[] buffer = new byte[1024 * 4];
                    int oldProgress = 0;
                    while ((len = stream.read(buffer)) != -1) {
                        fos.write(buffer, 0, len);
                        sum += len;
                        int progress = (int) (sum * 100 / total );
                        if (oldProgress != progress) {
                            finalDownListener.onProgress(progress);
                            oldProgress = progress;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    finalDownListener.onFail();
                    IOUtils.close(fos);
                    IOUtils.close(stream);
                }
            }
        });
    }


    private static Request.Builder buildRequest(int type) {
        Request.Builder request = new Request.Builder();
        request.addHeader("X-Requested-With", "XMLHttpRequest");
        if (type == 1) { // post / get
            request.addHeader("Content-Type", "application/json");
        } else if (type == 2) {
            request.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        } else if (type == 3) { // 文件上传下载
            request.addHeader("Content-Type", "multipart/form-data");
        }
        return request;
    }

    private static class CallbackImpl implements Callback {

        private final RequestBack callback;

        public CallbackImpl(RequestBack callback) {
            this.callback = callback;
        }

        @Override
        public void onFailure(@NotNull Call call, @NotNull IOException e) {
            if (null != this.callback) {
                this.callback.onParseResponse(call, null, e);
            }
        }

        @Override
        public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
            if (null != this.callback) {
                this.callback.onParseResponse(call, response, null);
            }
        }
    }

    public interface IDownListener {
        void onProgress(int progress);
        void onFail();
    }

    private static class RequestInterceptor implements Interceptor {
        private final String TAG = "okhttp3";

        @NonNull
        @Override
        public Response intercept(@NonNull Chain chain) throws IOException {
            if (!BuildConfig.DEBUG) {
                return chain.proceed(chain.request());
            }
            long startTime = System.nanoTime();
            Request request = chain.request();

            Buffer buffer = new Buffer();
            if (null != request.body()) {
                request.body().writeTo(buffer);
            }
            buffer.close();

            Response response = chain.proceed(request);
            if ("application/json".equals(request.header("Content-Type"))) {
                ResponseBody resBody = response.body();
                String bodyStr = resBody.string();
                long endTime = System.nanoTime();
                Log.d(TAG, String.format("response:{%n url:%s,%n time:%.1fms,%n req:%s,%n res:%s%n ",
                        response.request().url(), (endTime - startTime) / 1e6d, buffer.readUtf8(), bodyStr));

                return response.newBuilder().body(ResponseBody.Companion.create(bodyStr, resBody.contentType())).build();
            }

            long endTime = System.nanoTime();
            Log.d(TAG, String.format("response:{%n url:%s,%n time:%.1fms %n ",
                    response.request().url(), (endTime - startTime) / 1e6d));
            return response;
        }

    }
}