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

Posted liujichangdeboke

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);


以上是关于Android项目中okhttp3的简易封装和使用的主要内容,如果未能解决你的问题,请参考以下文章

Java封装OkHttp3工具类

网络框架封装(retrofit2+rxjava2+okhttp3)

网络框架封装(retrofit2+rxjava2+okhttp3)

Android OkHttp3 :最简单&粗暴(使用与原理)讲解

Android OkHttp3简介和使用详解

Java封装OkHttp3工具类