当前位置: 首页 > 工具软件 > easy-okhttp > 使用案例 >

安卓OKhttp的二次封装

越欣怡
2023-12-01

这篇文章实现了OKhttp的二次封装,在封装里实现了请求Json数据,表单的提交,下载图片.

封装的好处:

1.节约内存,使所有的网络请求都用一个OKhttpclient和handler对象
2.解决OKhttp,网络请求成功,代码在子线程的问题,把请求成功后的逻辑代码放到主线程中执行
3.简化代码
OKhttp的中级封装,实现两个功能,从服务端下载数据;从客户端提交数据
封装优秀的OKhttp:OKhttpUtils,OKGO(更深入的封装,研究OKGO)

这次封装用到了那些知识点:

1.单例模式

2.handler

3.接口

4.OKhttp

我们在使用单例模式时,构造方法一般权限私有,这样保证了对象的唯一性(EventBus,如果看源码的话,他的构造方法是public,所以一方面可以通过单例方法拿到对象,一方面可以通过new方式拿到)
首先,导依赖

compile 'com.squareup.okhttp3:okhttp-ws:3.4.2'
添加网络权限

<uses-permission android:name="android.permission.INTERNET"/>
添加布局

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:onClick="okhttp_json"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获取Json数据"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/button2"/>

    <Button
        android:onClick="okhttp_table"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="表单提交"
        android:id="@+id/button3"
        android:layout_below="@+id/button2"
        android:layout_centerHorizontal="true"/>

    <Button
        android:onClick="okhttp_picture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="下载图片"
        android:id="@+id/button4"
        android:layout_below="@+id/button3"
        android:layout_centerHorizontal="true"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/text"
        android:layout_below="@id/button4"
        android:layout_centerHorizontal="true"
        />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageView"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"/>


</RelativeLayout>
创建一个工具类OKhttpManager
public class OkhttpManager {
    定义成员变量//
    private OkHttpClient mClient;
    private static Handler mHandler;
    private volatile static OkhttpManager sManager;//防止多个线程同时访问,volatile

    使用构造方法,完成初始化//
    private OkhttpManager() {
        mClient = new OkHttpClient();
        mHandler = new Handler();
    }

    使用单例模式,通过获取的方式拿到对象//
    public static OkhttpManager getInstance() {
        OkhttpManager instance = null;
        if (sManager == null) {
            synchronized (OkhttpManager.class) {
                if (instance == null) {
                    instance = new OkhttpManager();
                    sManager = instance;
                }
            }
        }
        return instance;
    }

    定义接口//
    interface Func1 {
        void onResponse(String result);
    }

    interface Func2 {
        void onResponse(byte[] result);
    }

    interface Func3 {
        void onResponse(JSONObject jsonObject);
    }

    使用handler,接口,保证处理数据的逻辑在主线程//
    //处理请求网络成功的方法,返回的结果是json字符串
    private static void onSuccessJsonStringMethod(final String jsonValue, final Func1 callBack) {
        //这里我用的是mHandler.post方法,把数据放到主线程中,你们以后可以用EvenBus或RXJava的线程调度器去完成
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    try {
                        callBack.onResponse(jsonValue);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }
    //请求网络成功的方法,返回的结果是byte数组
    private static void  onSuccessJsonByteMethod(final byte[] json,final Func2 callBack){
        //把数据放到主线程,以后可以用EventBus或RxJava的线程调度器去完成
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack!=null){
                    try {
                        callBack.onResponse(json);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
        });
    }


    暴露提供给外界调用的方法//

    /**
     * 请求指定的URL返回的结果是json字符串
     */
    public void asyncJsonStringByURL(String url, final Func1 callBack) {
        Request request = new Request.Builder().url(url).build();
        mClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //判断response是否有对象,成功
                if (response!=null&&response.isSuccessful()){
                    onSuccessJsonStringMethod(response.body().string(),callBack);
                }
            }
        });
    }
    /**
     * 提交表单
     */
    public void sendComplexForm(String url, Map<String,String> params,final Func1 callBack){
        //表单对象
        FormBody.Builder form_builder = new FormBody.Builder();
        //健值非空判断
        if (params!=null&&!params.isEmpty()){
            for (Map.Entry<String,String> entry :params.entrySet()){
                form_builder.add(entry.getKey(),entry.getValue());
            }
        }
        FormBody request_body = form_builder.build();
        Request request = new Request.Builder().url(url).post(request_body).build();
        mClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response!=null&&response.isSuccessful()){
                    onSuccessJsonStringMethod(response.body().string(),callBack);
                }
            }
        });
    }
    //下载图片
    public void asyncJsonByteByUrl(String url,final Func2 callBack){
        Call call = mClient.newCall(new Request.Builder().url(url).build());
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if(response!=null){
                    byte[] bytes = response.body().bytes();
                    onSuccessJsonByteMethod(bytes,callBack);
                }
            }

        });
    }


}
最后再MainActivity中实现效果

 
public class MainActivity extends AppCompatActivity {

    private String json_path = "http://publicobject.com/helloworld.txt";
    private String Login_path = "http://169.254.53.96:8080/web/LoginServlet";
    private String Picture_path = "https://10.url.cn/eth/ajNVdqHZLLAxibwnrOxXSzIxA76ichutwMCcOpA45xjiapneMZsib7eY4wUxF6XDmL2FmZEVYsf86iaw/";
    private ImageView mImageView;
    private OkhttpManager mOkhttpManager;
    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mImageView = (ImageView) findViewById(imageView);
        mTextView= (TextView) findViewById(R.id.text);
        mOkhttpManager = OkhttpManager.getInstance();
    }

    /**
     * 通过点击事件执行okhttp里封装的根据网址,获取字符串的逻辑操作.
     *
     * @param view
     */
    public void okhttp_json(View view) {
        mOkhttpManager.asyncJsonStringByURL(json_path,new OkhttpManager.Func1(){
            @Override
            public void onResponse(String result) {
                mTextView.setText(result);
            }
        });
    }

    //像服务器提交账号及密码
    public void okhttp_table(View view) {
        HashMap<String, String> map = new HashMap<>();
        map.put("qq","10000");
        map.put("pwd","abcde");
        mOkhttpManager.sendComplexForm(Login_path, map, new OkhttpManager.Func1() {
            @Override
            public void onResponse(String result) {
                mTextView.setText(result);
            }
        });
    }

    //下载图片
    public void okhttp_picture(View view) {
        mOkhttpManager.asyncJsonByteByUrl(Picture_path, new OkhttpManager.Func2() {
            @Override
            public void onResponse(byte[] result) {
                Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0, result.length);
                mImageView.setImageBitmap(bitmap);
            }
        });

    }

}

好了,这就简单的实现OKhttp的二次封装.


 类似资料: