Android项目中okhttp3的简易封装和使用

1、所有文件:

2、OkHttpUtil类

这个类主要用于初始化okhttp和发送http请求。

public class OkHttpUtil{
    private static OkHttpClient mOkHttpClient = null;

    //Call this method in the Application class. ---> onCreate() method.
    //Thus we can get only one instance of httpClient in the whole app.
    public static void init(){
        if (mOkHttpClient == null) {
            OkHttpClient.Builder builder = new OkHttpClient().newBuilder()
                    .connectTimeout(5000, TimeUnit.MILLISECONDS)
                    .readTimeout(5000, TimeUnit.MILLISECONDS)
                    .writeTimeout(5000, TimeUnit.MILLISECONDS)
                    .sslSocketFactory(RxUtils.createSSLSocketFactory(),new RxUtils.TrustAllManager())
                    .hostnameVerifier(new RxUtils.TrustAllHostnameVerifier());
            mOkHttpClient = builder.build();
        }
    }


    //If GET method needs some other params, just need to add a HaspMap. Refer to:https://www.imooc.com/video/18685
    public static void get(String url, OkHttpCallBack okHttpCallback){
        Call call = null;

        try{
            Request request = new Request.Builder().url(url).build();
            call = mOkHttpClient.newCall(request);
            call.enqueue(okHttpCallback);

        }catch(Exception ex){
            ex.printStackTrace();
        }
    }

    public static void post(String url, OkHttpCallBack okHttpCallback, HashMap<String, String> bodyMap){
        Call call = null;
        try{
            FormBody.Builder builder = new FormBody.Builder();
            for (HashMap.Entry<String, String> entry : bodyMap.entrySet()) {
                builder.add(entry.getKey(), entry.getValue());
            }
            RequestBody body = builder.build();
            Request.Builder builderRequest = new Request.Builder();
//            builderRequest.headers(new Headers())
            Request request = builderRequest.post(body).url(url).build();
            call = mOkHttpClient.newCall(request);
            call.enqueue(okHttpCallback);

        }catch(Exception ex){
            ex.printStackTrace();
        }
    }
    public static void postHasFile(String url, OkHttpCallBack okHttpCallback, HashMap<String, String> bodyMap, String filesKey, List<File> files){
        Call call = null;
        try{

            MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder();
            multipartBodyBuilder.setType(MultipartBody.FORM);
            for (HashMap.Entry<String, String> entry : bodyMap.entrySet()) {
                multipartBodyBuilder.addFormDataPart(entry.getKey(), entry.getValue());
            }
            //遍历paths中所有图片绝对路径到builder,并约定key如“upload”作为后台接受多张图片的key
            if (files != null){
                for (File file : files) {
                    multipartBodyBuilder.addFormDataPart(filesKey, file.getName(), RequestBody.create(MediaType.parse("image/png"), file));
                }
            }
            RequestBody body = multipartBodyBuilder.build();
            Request.Builder builderRequest = new Request.Builder();
//            builderRequest.headers(new Headers())
            Request request = builderRequest.post(body).url(url).build();
            call = mOkHttpClient.newCall(request);
            call.enqueue(okHttpCallback);

        }catch(Exception ex){
            ex.printStackTrace();
        }
    }

}

1、在application中调用init方法初始化okhttp。

2、使用post方法:

(1)第一个(post)是不上传图片的请求,只需传入请求url、map形式的上传参数,一个请求监听。

(2)第二个(postHasFile)为上传文件请求,本人项目中只需上传一个图片列表,所以只增加了

String filesKey, List<File> files

两个参数。如果有其他需求,可以修改此处代码:

MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder();
multipartBodyBuilder.setType(MultipartBody.FORM);
for (HashMap.Entry<String, String> entry : bodyMap.entrySet()) {
    multipartBodyBuilder.addFormDataPart(entry.getKey(), entry.getValue());
}
//遍历paths中所有图片绝对路径到builder,并约定key如“upload”作为后台接受多张图片的key
if (files != null){
    for (File file : files) {
        multipartBodyBuilder.addFormDataPart(filesKey, file.getName(), RequestBody.create(MediaType.parse("image/png"), file));
    }
}

2、OkHttpCallBack

这个类简单封装了Okhttp的callback方法并以jsonObject回调给请求。

import android.util.Log;

import com.google.gson.Gson;

import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import java.io.IOException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

//The class to deal with the OkHttpCallback
public abstract class OkHttpCallBack implements Callback {

    public abstract void onSuccess(final Call call, JSONObject jsonObject);

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        Log.d("OkHttpCallBackResponse:",call.toString()+"\r\n//reponse"+response.toString()+"\r\nresponse.headers:"+response.headers()
                +"\r\nreponse.message:"+response.message());
        if (response != null) {
            String str = response.body().string().trim();
            Log.d("OkHttpCallBackResponse","//body::"+str);
            if (response.isSuccessful()) {
                try{
                    JSONObject object = (JSONObject)new JSONTokener(str).nextValue();
                    if (object != null) {
                        onSuccess(call, object);
                    }else{
                        onFailure(call, null);
                    }
                }catch(JSONException e) {
                    e.printStackTrace();
                    onFailure(call, null);
                }

            }else{
                onFailure(call, null);
            }
        }
    }


    @Override
    public void onFailure(Call call, IOException e){
        Log.d("OkHttpCallBackFail",call.toString()+"//"+e.toString());
    }
}

3、RxUtils 

这个类是为了配置请求证书 (https需要)。

import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

//在okhttp中设置信任所有证书
public class RxUtils {

    @SuppressLint("TrulyRandom")
    public static SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory sSLSocketFactory = null;
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{new TrustAllManager()},
                    new SecureRandom());
            sSLSocketFactory = sc.getSocketFactory();
        } catch (Exception ignored) {
        }
        return sSLSocketFactory;
    }

    public static class TrustAllManager implements X509TrustManager {
        @SuppressLint("TrustAllX509TrustManager")
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }

        @SuppressLint("TrustAllX509TrustManager")
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }

    public static class TrustAllHostnameVerifier implements HostnameVerifier {
        @SuppressLint("BadHostnameVerifier")
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }
}

4、 NetConfig

此类主要写了baseurl和各个请求接口url。

public class NetConfig {

    
    public static String BASE_URL = "http://111.111.1.111:8081/";

    //登录
    public static String LOGIN = BASE_URL+"mobileApi/user/login";
}

5、ApiUtil

这个类为每个请求的基类

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import androidx.annotation.NonNull;

import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;

import okhttp3.Call;

public  abstract class ApiUtil {
    private ApiListener mApiListener = null;
    private static final int SUCCESS = 1;
    private static final int FAIRURE = 2;
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case SUCCESS:
                    mApiListener.success(ApiUtil.this);
                    break;
                case FAIRURE:
                    mApiListener.failrure(ApiUtil.this);
                    break;
            }
        }
    };
    public boolean mStatus = false;
    public String msg = "请求失败";
    public String TAG = this.getClass().toString();
    private OkHttpCallBack mSendListener = new OkHttpCallBack(){

        @Override
        public void onSuccess(Call call, JSONObject jsonObject) {
            ApiUtil.this.mStatus = jsonObject.optBoolean("status");
            ApiUtil.this.msg = jsonObject.optString("msg");
            if (mStatus) {
                try{
                    parseData(jsonObject);
                    handler.sendEmptyMessage(SUCCESS);

                }catch(IOException e){
                    handler.sendEmptyMessage(FAIRURE);
                    e.printStackTrace();
                } catch (Exception e) {
                    handler.sendEmptyMessage(FAIRURE);
                    e.printStackTrace();
                }

            }else{
                handler.sendEmptyMessage(FAIRURE);
            }
        }

        @Override
        public void onFailure(Call call, IOException e){
            ApiUtil.this.msg = "链接失败";
            ApiUtil.this.mStatus = false;
            handler.sendEmptyMessage(FAIRURE);
        }
    };

//    public boolean isSuccess(){
//        return "0".equals(mStatus) || "200".equals(mStatus);
//    }

    protected abstract void parseData(JSONObject jsonObject) throws Exception;

    protected abstract String getUrl();

    //Send GET request
    //Listener: Tell the app whether the GET reqeust is success.
    public void get(ApiListener listener){
        mApiListener = listener;
        OkHttpUtil.get(getUrl(), mSendListener);
    }


    private HashMap<String, String> mBodyMap = new HashMap<>();
    public void addParams(String key, String value){
        mBodyMap.put(key, value);
    }
    public void clearParams(){
        mBodyMap.clear();
    }

    //Send POST request
    //Listener: Tell the app whether the POST reqeust is success.
    public void post(ApiListener listener){
        mApiListener = listener;
        OkHttpUtil.post(getUrl(), mSendListener, mBodyMap);
    }
    public void postFiles(ApiListener listener, String fileKey, List<File> fileList){
        mApiListener = listener;

        OkHttpUtil.postHasFile(getUrl(),mSendListener,mBodyMap,fileKey,fileList);
    }
    @Override
    public String toString() {
        return "ApiUtil{" +
                "mApiListener=" + mApiListener +
                ", mStatus=" + mStatus +
                ", msg='" + msg + '\'' +
                ", TAG='" + TAG + '\'' +
                ", mSendListener=" + mSendListener +
                ",\r\n mBodyMap=" + mBodyMap +
                '}';
    }
}

1、设置参数请求

public void addParams(String key, String value){
    mBodyMap.put(key, value);
}

2、发送请求

public void post(ApiListener listener){
    mApiListener = listener;
    OkHttpUtil.post(getUrl(), mSendListener, mBodyMap);
}
public void postFiles(ApiListener listener, String fileKey, List<File> fileList){
    mApiListener = listener;

    OkHttpUtil.postHasFile(getUrl(),mSendListener,mBodyMap,fileKey,fileList);
}

以登陆接口为例

public class PostLogin extends ApiUtil {

    public UserBeans mResponse;
    public PostLogin(String userName, String passWord){
        addParams("userCode", userName);
        addParams("userPassword", passWord);
    }
    @Override
    protected void parseData(JSONObject jsonObject) throws Exception {
        mResponse = new Gson().fromJson(jsonObject.optString("data"),UserBeans.class);
    }

    @Override
    protected String getUrl() {
        return NetConfig.LOGIN;
    }
}

1、可以在初始化时添加参数,或者生成postLogin实例后传参。

2、在getUrl()方法中回调给父类请求URL。 

3、可以在parseData(JSONObject jsonObject)中解析返回的数据,然后定义实体类作为接收:

public UserBeans mResponse;
@Override
protected void parseData(JSONObject jsonObject) throws Exception {
    mResponse = new Gson().fromJson(jsonObject.optString("data"),UserBeans.class);
}

在LoginActivity中调用

private void login() {
        if (TextUtils.isEmpty(edtUserName.getText().toString())) {
            toShortToast("请输入用户名");
            return;
        }
        if (TextUtils.isEmpty(edtPassword.getText().toString())) {
            toShortToast("请输入密码");
            return;
        }
        showLoadingDialog("登录中...");
        new PostLogin(edtUserName.getText().toString(), edtPassword.getText().toString()).post(new ApiListener() {
            @Override
            public void success(ApiUtil apiUtil) {
                toShortToast(apiUtil.msg);
                PostLogin postLogin = (PostLogin) apiUtil;
                SPUtil.put(context, SpKeys.KEY_LOGIN_USER_NAME, edtUserName.getText().toString());
                SPUtil.put(context, SpKeys.KEY_USER_ID, postLogin.mResponse.getUserId());
                SPUtil.put(context, SpKeys.KEY_USER_TYPE, postLogin.mResponse.getUserType());
                if (isRememberPw) {
                    SPUtil.put(context, SpKeys.KEY_LOGIN_PASSWORD, edtPassword.getText().toString());
                } else {
                    SPUtil.put(context, SpKeys.KEY_LOGIN_PASSWORD, "");
                }
                Intent intent = new Intent();
                intent.setClass(context, MainActivity.class);
                context.startActivity(intent);
                stopLoadingDialog();
                finish();
            }

            @Override
            public void failrure(ApiUtil apiUtil) {
                stopLoadingDialog();
                toShortToast(apiUtil.msg);
            }
        });

    }

请求监听接口中 success(ApiUtil apiUtil)方法回调 接收的数据

PostLogin postLogin = (PostLogin) apiUtil;

postLogin.mResponse为已经解析好的实体类。

后补:ApiListener 

public interface ApiListener {

    //Request success
    void success(ApiUtil apiUtil);

    //Request failed
    void failrure(ApiUtil apiUtil);


}

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 25
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值