• Android OkHttp3(完美封装)Get异步获取数据、Post异步获取数据、Form表单提交、文件下载


    说明:

    (1)本项目需要一个:MainActivity.java 类和 activity_main.xml 布局页面。

    (2)下载文件需要一个拦截器共2个类:ProgressListener 接口 ProgressResponsBody 封装类。

    (3)封装OkHttp3需要4个类:BaseCallBack、BaseOkHttpClient、OkHttpManage、RequestParameter。

    1.MainActivity 类:

    package com.xxxx.example.activity;
    
    import android.os.Environment;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.text.TextUtils;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.tcrj.example.intercept.ProgressListener;
    import com.tcrj.example.intercept.ProgressResponsBody;
    import com.tcrj.example.okhttp.BaseCallBack;
    import com.tcrj.example.okhttp.BaseOkHttpClient;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    import okhttp3.Call;
    import okhttp3.Callback;
    import okhttp3.Interceptor;
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.Response;
    
    /**
     * 首页界面
     */
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
        private Button btnGetdata;
        private Button btnPostdata;
        private Button btnFormdata;
        private TextView txtState;
        private TextView txtContent;
        private EditText edtAccount;
        private EditText edtPassword;
        private EditText edtFormname;
        private EditText edtFormpwd;
        private Button btnDownload;
        private ProgressBar progress;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
        }
    
        /**
         * 获取页面控件
         */
        private void initView() {
            btnGetdata = (Button) findViewById(R.id.btn_getdata);
            btnPostdata = (Button) findViewById(R.id.btn_postdata);
            btnFormdata = (Button) findViewById(R.id.btn_formdata);
            btnDownload = (Button) findViewById(R.id.btn_download);
            txtState = (TextView) findViewById(R.id.txtState);
            txtContent = (TextView) findViewById(R.id.txtContent);
            edtAccount = (EditText) findViewById(R.id.edt_account);
            edtPassword = (EditText) findViewById(R.id.edt_password);
            edtFormname = (EditText) findViewById(R.id.edt_formname);
            edtFormpwd = (EditText) findViewById(R.id.edt_formpwd);
            progress = (ProgressBar) findViewById(R.id.progressBar);
            btnGetdata.setOnClickListener(this);
            btnPostdata.setOnClickListener(this);
            btnFormdata.setOnClickListener(this);
            btnDownload.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn_getdata:
                    getData();
                    break;
                case R.id.btn_postdata:
                    String account = edtAccount.getText().toString().trim();
                    String password = edtPassword.getText().toString().trim();
                    if (TextUtils.isEmpty(account)) {
                        Toast.makeText(this, "请输入账号", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    if (TextUtils.isEmpty(password)) {
                        Toast.makeText(this, "请输入密码", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    postSubmit(account, password);
                    break;
                case R.id.btn_formdata:
                    String name = edtFormname.getText().toString().trim();
                    String pwd = edtFormpwd.getText().toString().trim();
                    if (TextUtils.isEmpty(name)) {
                        Toast.makeText(this, "请输入账号", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    if (TextUtils.isEmpty(pwd)) {
                        Toast.makeText(this, "请输入密码", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    postFormSubmit(name, pwd);
                    break;
                case R.id.btn_download:
                    downLoadFile();
                    break;
            }
        }
    
        /**
         * Post异步提交:登录
         *
         * @param account
         * @param password
         */
        private void postSubmit(String account, String password) {
            String url = "http://192.168.10.24:8881/Api/GetLoginInfo.ashx?";
            BaseOkHttpClient.newBuilder()
                    .addParam("AccountName", account)
                    .addParam("LoaPwd", password)
                    .post()
                    .url(url)
                    .build()
                    .enqueue(new BaseCallBack() {
                        @Override
                        public void onSuccess(Object o) {
                            txtState.setText("登录成功");
                            Toast.makeText(MainActivity.this, "成功:" + o.toString(), Toast.LENGTH_SHORT).show();
                        }
    
                        @Override
                        public void onError(int code) {
                            Toast.makeText(MainActivity.this, "错误编码:" + code, Toast.LENGTH_SHORT).show();
                        }
    
                        @Override
                        public void onFailure(Call call, IOException e) {
                            Toast.makeText(MainActivity.this, "失败:" + e.toString(), Toast.LENGTH_SHORT).show();
                        }
                    });
        }
    
        /**
         * GET异步请求数据
         */
        private void getData() {
            String url = "http://www.xxxxx.xxx.cn/jsp/brow/infoList.jsp?";
            BaseOkHttpClient.newBuilder()
                    .addParam("cat_id", 14137)
                    .addParam("cur_page", 1)
                    .addParam("size", 10)
                    .get()
                    .url(url)
                    .build()
                    .enqueue(new BaseCallBack() {
                        @Override
                        public void onSuccess(Object o) {
                            Toast.makeText(MainActivity.this, "成功:" + o.toString(), Toast.LENGTH_SHORT).show();
                            txtContent.setText(o.toString());
                        }
    
                        @Override
                        public void onError(int code) {
                            Toast.makeText(MainActivity.this, "错误编码:" + code, Toast.LENGTH_SHORT).show();
                        }
    
                        @Override
                        public void onFailure(Call call, IOException e) {
                            Toast.makeText(MainActivity.this, "失败:" + e.toString(), Toast.LENGTH_SHORT).show();
                        }
                    });
        }
    
        /**
         * Form 表单提交
         */
        private void postFormSubmit(String name, String pwd) {
            String url = "http://192.168.20.101:8080/webProject/servlet/TestServlet";
            BaseOkHttpClient.newBuilder()
                    .addParam("username", name)
                    .addParam("password", pwd)
                    .form()
                    .url(url)
                    .build()
                    .enqueue(new BaseCallBack() {
                        @Override
                        public void onSuccess(Object o) {
                            Toast.makeText(MainActivity.this, "成功:" + o.toString(), Toast.LENGTH_SHORT).show();
                        }
    
                        @Override
                        public void onError(int code) {
                            Toast.makeText(MainActivity.this, "错误编码:" + code, Toast.LENGTH_SHORT).show();
                        }
    
                        @Override
                        public void onFailure(Call call, IOException e) {
                            Toast.makeText(MainActivity.this, "失败:" + e.toString(), Toast.LENGTH_SHORT).show();
                        }
                    });
        }
    
        String fileName = "book.txt";
    
        /**
         * 文件下载
         */
        private void downLoadFile() {
            OkHttpClient client = new OkHttpClient.Builder()
                    .addNetworkInterceptor(new InterNetInterceptor())
                    .build();
            //String urlx = "http://sw.bos.baidu.com/sw-search-sp/software/e73a3ba452ef5/BaiduNetdisk_5.6.0.17.exe";
            //String urlx = "http://gdown.baidu.com/data/wisegame/9db3f36158334e25/baiduwangpan_517.apk";
            String urlx = "https://publicobject.com/helloworld.txt";
            Request request = new Request.Builder()
                    .url(urlx)
                    .build();
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    Log.d("MainActivity", e.toString());
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    writeFile(response);
                }
            });
        }
    
        /**
         * Interceptor拦截器方法实现
         */
        public class InterNetInterceptor implements Interceptor {
    
            @Override
            public Response intercept(Chain chain) throws IOException {
                Response response = chain.proceed(chain.request());
                return response.newBuilder().body(new ProgressResponsBody(response.body(), new ProgBar())).build();
            }
        }
    
        /**
         * 进度条监听
         */
        private class ProgBar implements ProgressListener {
    
            @Override
            public void onProgress(final int mProgress, final long contentSize) {
                Log.i("**************下载进度:", String.valueOf(mProgress));
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        progress.setProgress(mProgress);
                    }
                });
            }
    
            @Override
            public void onDone(long totalSize) {
                Log.i("下载完成********文件大小为:", String.valueOf(totalSize));
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "下载完成", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        }
    
        /**
         * 读取文件
         *
         * @param response
         */
        private void writeFile(Response response) {
            InputStream is = null;
            FileOutputStream fos = null;
            is = response.body().byteStream();
            String path = Environment.getExternalStorageDirectory().getAbsolutePath();
            File file = new File(path, fileName);
            try {
                fos = new FileOutputStream(file);
                byte[] bytes = new byte[2048];
                int len = 0;
                while ((len = is.read(bytes)) != -1) {
                    fos.write(bytes, 0, len);
                }
                is.close();
                fos.flush();
                fos.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (is != null) {
                        is.close();
                    }
                    if (fos != null) {
                        fos.flush();
                        fos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    2.布局文件 activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="@dimen/activity_horizontal_margin"
        android:orientation="vertical">
    
    
        <Button
            android:id="@+id/btn_getdata"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="OkHttp  GET异步获取数据" />
    
        <EditText
            android:id="@+id/edt_account"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入账号"
            android:textColor="@color/colorAccent"
            android:textSize="16sp" />
    
        <EditText
            android:id="@+id/edt_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入密码"
            android:inputType="textPassword"
            android:textColor="@color/colorAccent"
            android:textSize="16sp" />
    
        <Button
            android:id="@+id/btn_postdata"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="OkHttp  POST异步获取数据" />
    
        <EditText
            android:id="@+id/edt_formname"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入账号"
            android:textColor="@color/colorAccent"
            android:textSize="16sp" />
    
        <EditText
            android:id="@+id/edt_formpwd"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入密码"
            android:inputType="textPassword"
            android:textColor="@color/colorAccent"
            android:textSize="16sp" />
    
        <Button
            android:id="@+id/btn_formdata"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="OkHttp  FORM表单提交" />
    
        <ProgressBar
            android:id="@+id/progressBar"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <Button
            android:id="@+id/btn_download"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="OkHttp  文件下载" />
    
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scrollbars="none">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
    
                <TextView
                    android:id="@+id/txtState"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@color/colorAccent"
                    android:textSize="16sp" />
    
                <TextView
                    android:id="@+id/txtContent"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@color/colorPrimary"
                    android:textSize="16sp" />
            </LinearLayout>
        </ScrollView>
    </LinearLayout>

    3.拦截器接口:ProgressListener

    package com.xxxx.example.intercept;
    
    /**
     * 进度条监听器
     * Created by leict on 2017/6/9.
     */
    
    public interface ProgressListener {
        /**
         * 显示进度
         *
         * @param mProgress
         */
        public void onProgress(int mProgress,long contentSize);
    
        /**
         * 完成状态
         *
         * @param totalSize
         */
        public void onDone(long totalSize);
    }

    4.拦截器类

    package com.xxxx.example.intercept;
    
    import android.util.Log;
    
    import java.io.IOException;
    
    import okhttp3.MediaType;
    import okhttp3.ResponseBody;
    import okio.Buffer;
    import okio.BufferedSource;
    import okio.ForwardingSource;
    import okio.Okio;
    import okio.Source;
    
    /**
     * 继承ResponsBody 并重写改方法
     * Created by leict on 2017/6/9.
     */
    
    public class ProgressResponsBody extends ResponseBody {
        private ResponseBody responseBody;
        private BufferedSource bufferedSource;
        private ProgressListener listener;
    
        public ProgressResponsBody(ResponseBody responseBody, ProgressListener listener) {
            this.responseBody = responseBody;
            this.listener = listener;
        }
    
        @Override
        public MediaType contentType() {
            return responseBody.contentType();
        }
    
        @Override
        public long contentLength() {
            return responseBody.contentLength();
        }
    
        @Override
        public BufferedSource source() {
            if (bufferedSource == null) {
                bufferedSource = Okio.buffer(getSource(responseBody.source()));
            }
            return bufferedSource;
        }
    
        private Source getSource(Source source) {
    
            return new ForwardingSource(source) {
                long totalSize = 0;
                long sum = 0;
    
                @Override
                public long read(Buffer sink, long byteCount) throws IOException {
                    if (totalSize == 0) {
                        totalSize = contentLength();
                    }
                    long len = super.read(sink, byteCount);
                    sum += (len == -1 ? 0 : len);
                    int press = (int) ((sum * 1.0f / totalSize) * 100);
                    Log.i("///////////", String.valueOf(totalSize));
                    if (len == -1) {
                        listener.onDone(totalSize);
                    } else {
                        listener.onProgress(press, totalSize);
                    }
                    return len;
                }
            };
        }
    }

    5.回调类封装:BaseCallBack

    package com.xxxx.example.okhttp;
    
    import com.google.gson.internal.$Gson$Types;
    
    import java.io.IOException;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    
    import okhttp3.Call;
    
    /**
     * 回调函数
     * Created by leict on 2017/6/6.
     */
    
    public abstract class BaseCallBack<T> {
        public Type mType;
    
        static Type getSuperclassTypeParameter(Class<?> subclass) {
            Type superclass = subclass.getGenericSuperclass();
            if (superclass instanceof Class) {
                return null;
            }
            ParameterizedType parameterized = (ParameterizedType) superclass;
            return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
        }
    
        public BaseCallBack() {
            mType = getSuperclassTypeParameter(this.getClass());
        }
    
        /**
         * 成功
         *
         * @param t
         */
        public abstract void onSuccess(T t);
    
        /**
         * 错误代码
         *
         * @param code
         */
        public abstract void onError(int code);
    
        /**
         * 失败
         *
         * @param call
         * @param e
         */
        public abstract void onFailure(Call call, IOException e);
    }

    6.监听类:BaseOkHttpClient

    package com.xxxx.example.okhttp;
    
    import android.net.Uri;
    
    import org.json.JSONException;
    import org.json.JSONObject;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import okhttp3.FormBody;
    import okhttp3.MediaType;
    import okhttp3.Request;
    import okhttp3.RequestBody;
    
    /**
     * 封装OkHttp
     * Created by leict on 2017/6/8.
     */
    
    public class BaseOkHttpClient {
        private Builder mBuilder;
    
        private BaseOkHttpClient(Builder builder) {
            this.mBuilder = builder;
        }
    
        public Request buildRequest() {
            Request.Builder builder = new Request.Builder();
            if (mBuilder.method == "GET") {
                builder.url(buildGetRequestParam());
                builder.get();
            } else if (mBuilder.method == "POST") {
                builder.url(mBuilder.url);
                try {
                    builder.post(buildPostRequestParam());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            return builder.build();
        }
    
        /**
         * GET拼接参数
         *
         * @return
         */
        private String buildGetRequestParam() {
            if (mBuilder.params.size() <= 0) {
                return this.mBuilder.url;
            }
            Uri.Builder builder = Uri.parse(mBuilder.url).buildUpon();
            for (RequestParameter p : mBuilder.params) {
                builder.appendQueryParameter(p.getKey(), p.getObj() == null ? "" : p.getObj().toString());
            }
            String url = builder.build().toString();
            return url;
        }
    
        /**
         * POST拼接参数
         *
         * @return
         */
        private RequestBody buildPostRequestParam() throws JSONException {
            if (mBuilder.isJsonParam) {
                JSONObject jsonObj = new JSONObject();
                for (RequestParameter p : mBuilder.params) {
                    jsonObj.put(p.getKey(), p.getObj());
                }
                String json = jsonObj.toString();
                return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);
            }
            FormBody.Builder builder = new FormBody.Builder();
            for (RequestParameter p : mBuilder.params) {
                builder.add(p.getKey(), p.getObj() == null ? "" : p.getObj().toString());
            }
            return builder.build();
        }
    
        /**
         * 回调调用
         *
         * @param callBack
         */
        public void enqueue(BaseCallBack callBack) {
            OkHttpManage.getInstance().request(this, callBack);
        }
    
        public static Builder newBuilder() {
            return new Builder();
        }
    
        public static class Builder {
            private String url;
            private String method;
            private List<RequestParameter> params;
            private boolean isJsonParam;
    
            public BaseOkHttpClient build() {
                return new BaseOkHttpClient(this);
            }
    
            private Builder() {
                method = "GET";
                params = new ArrayList<>();
            }
    
            public Builder url(String url) {
                this.url = url;
                return this;
            }
    
            /**
             * GET请求
             *
             * @return
             */
            public Builder get() {
                method = "GET";
                return this;
            }
    
            /**
             * POST请求
             *
             * @return
             */
            public Builder post() {
                method = "POST";
                isJsonParam = true;
                return this;
            }
    
            /**
             * JSON参数
             *
             * @return
             */
            public Builder json() {
                isJsonParam = true;
                return post();
            }
    
            /**
             * Form请求
             *
             * @return
             */
            public Builder form() {
                return this;
            }
    
            /**
             * 添加参数
             *
             * @param key
             * @param value
             * @return
             */
            public Builder addParam(String key, Object value) {
                if (params == null) {
                    params = new ArrayList<>();
                }
                params.add(new RequestParameter(key, value));
                return this;
            }
        }
    }

    7.管理类:OkHttpManage

    package com.xxxx.example.okhttp;
    
    import android.os.Handler;
    import android.os.Looper;
    
    import com.google.gson.Gson;
    
    import java.io.IOException;
    import java.util.concurrent.TimeUnit;
    
    import okhttp3.Call;
    import okhttp3.Callback;
    import okhttp3.OkHttpClient;
    import okhttp3.Response;
    
    /**
     * OkHttpMange管理类
     * Created by leict on 2017/6/6.
     */
    
    public class OkHttpManage {
        private static OkHttpManage mInstance;
        private OkHttpClient mClient;
        private Handler mHnadler;
        private Gson mGson;
    
        /**
         * 单例
         *
         * @return
         */
        public static synchronized OkHttpManage getInstance() {
            if (mInstance == null) {
                mInstance = new OkHttpManage();
            }
            return mInstance;
        }
    
        /**
         * 构造函数
         */
        private OkHttpManage() {
            initOkHttp();
            mHnadler = new Handler(Looper.getMainLooper());
            mGson = new Gson();
        }
    
        /**
         * 初始化OkHttpClient
         */
        private void initOkHttp() {
            mClient = new OkHttpClient().newBuilder()
                    .readTimeout(30000, TimeUnit.SECONDS)
                    .connectTimeout(30000, TimeUnit.SECONDS)
                    .writeTimeout(30000, TimeUnit.SECONDS)
                    .build();
        }
    
        /**
         * 请求
         *
         * @param client
         * @param callBack
         */
        public void request(BaseOkHttpClient client, final BaseCallBack callBack) {
            if (callBack == null) {
                throw new NullPointerException(" callback is null");
            }
            mClient.newCall(client.buildRequest()).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    sendonFailureMessage(callBack, call, e);
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    if (response.isSuccessful()) {
                        String result = response.body().string();
                        if (callBack.mType == null || callBack.mType == String.class) {
                            sendonSuccessMessage(callBack, result);
                        } else {
                            sendonSuccessMessage(callBack, mGson.fromJson(result, callBack.mType));
                        }
                        if (response.body() != null) {
                            response.body().close();
                        }
                    } else {
                        sendonErrorMessage(callBack, response.code());
                    }
                }
            });
        }
    
        /**
         * 成功信息
         *
         * @param callBack
         * @param result
         */
        private void sendonSuccessMessage(final BaseCallBack callBack, final Object result) {
            mHnadler.post(new Runnable() {
                @Override
                public void run() {
                    callBack.onSuccess(result);
                }
            });
        }
    
        /**
         * 失败信息
         *
         * @param callBack
         * @param call
         * @param e
         */
        private void sendonFailureMessage(final BaseCallBack callBack, final Call call, final IOException e) {
            mHnadler.post(new Runnable() {
                @Override
                public void run() {
                    callBack.onFailure(call, e);
                }
            });
        }
    
        /**
         * 错误信息
         *
         * @param callBack
         * @param code
         */
        private void sendonErrorMessage(final BaseCallBack callBack, final int code) {
            mHnadler.post(new Runnable() {
                @Override
                public void run() {
                    callBack.onError(code);
                }
            });
        }
    }

    8. 参数类:RequestParameter

    package com.xxxx.example.okhttp;
    
    /**
     * 参数
     * Created by leict on 2017/6/8.
     */
    
    public class RequestParameter {
        private String key;
        private Object obj;
    
        public RequestParameter(String key, Object obj) {
            this.key = key;
            this.obj = obj;
        }
    
        public String getKey() {
            return key;
        }
    
        public void setKey(String key) {
            this.key = key;
        }
    
        public Object getObj() {
            return obj;
        }
    
        public void setObj(Object obj) {
            this.obj = obj;
        }
    }

    如图:

  • 相关阅读:
    Search Insert Position
    lintcode: 最长连续序列
    lintcode:颜色分类
    lintcode: 堆化
    lintcode: 旋转图像
    lintcode: 寻找旋转排序数组中的最小值
    lintcode: 跳跃游戏 II
    lintcode:最小差
    华为:数独填充
    华为:字符集合
  • 原文地址:https://www.cnblogs.com/xiaoyao095/p/6991761.html
Copyright © 2020-2023  润新知