OKhttp network request support (raw, from-data) submission actual combat (request form, upload pictures, upload multiple pictures)

Today, I will share with you a practical case of okhttp network request. Novice students are welcome, and you are welcome to give advice. If you don’t have much to say, you will directly go to dry goods.

I added the rack package manually and imported it manually. Remember to import it. It’s okay to add dependencies, depending on personal hobbies (private messages or messages for the package, leave the mailbox, or what I will send to you)

Then add dependency: (Allow me to install x and use rxjava2, I use glide to load pictures, and support multiple upload pictures)

implementation 'io.reactivex.rxjava2:rxjava:2.2.19'
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
    implementation 'com.github.bumptech.glide:glide:4.11.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
    implementation 'com.google.code.gson:gson:2.8.5'

Here comes the most important step, remember to add network permissions:

!--相机权限-->
    <uses-permission android:name="android.permission.CAMERA" />
    <!--读文件权限-->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <!--使用特性-->
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-permission android:name="android.permission.INTERNET" />

The configuration is almost finished and ready to start to dry the code: use the rxjava interface to have:

public interface MyNetWorkCallback<T> {

    void onSuccess(T t);
    void onError(int errorCode, String errorMsg);

}

Continue on:

public interface IHttp {
    <T> void get(String url, MyNetWorkCallback<T> callback);
    <T> void get(String url, Map<String, String> params, MyNetWorkCallback<T> callback);
    <T> void get(String url, Map<String, String> params, Map<String, String> headers, MyNetWorkCallback<T> callback);
    <T> void post(String url, Map<String, String> params, MyNetWorkCallback<T> callback);
<T> void postraw(String url, String params, MyNetWorkCallback<T> callback);
    <T> void postrawfile(String url, File file, MyNetWorkCallback<T> callback);
    void upload(String url, String path, Map<String, String> params, String fileType, MediaType MEDIA_TYPE, final MyNetWorkCallback<String> callback);
    void download();
    void loadImage(String url, ImageView imageView);

}

I have forgotten what this class is doing. I don’t use the field time, but I also write about the mountain. You don’t need to

public class HttpFactroy {
    public static IHttp create(){
        return OkHttpUtils.getInstance();
    }
}

The main class is here, and the singleton is here:

/**
 * 基于OKhttp发送网络请求
 * Created by 2018/1/10.
 *
 * @Author King
 * @Email [email protected]
 */

public class OkHttpUtils implements IHttp {

    private OkHttpClient okHttpClient;
    //构造函数私有化
    private OkHttpUtils(){
        okHttpClient = new OkHttpClient.Builder().build();
    }

    private static OkHttpUtils okHttpUtils;

    //提供一个公共的、静态的、返回值类型是当前本类的对象
    public static OkHttpUtils getInstance(){
        if(okHttpUtils == null){
            synchronized (OkHttpUtils.class){
                if(okHttpUtils == null) {
                    okHttpUtils = new OkHttpUtils();
                }
            }
        }
        return okHttpUtils;
    }

    @Override
    public <T> void get(String url, MyNetWorkCallback<T> callback) {

    }
    /**
     * 上传多张图片及参数
     * @param reqUrl URL地址
     * @param paramssa 参数
     * @param pic_key 上传图片的关键字
     */
    public Observable<String> sendMultipart(final String reqUrl, final Map<String, String> paramssa, final String pic_key, final List<File> filessa){
        return Observable.create(new ObservableOnSubscribe<String>(){
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Exception {
                MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder();
                multipartBodyBuilder.setType(MultipartBody.FORM);
                //遍历map中所有参数到builder
                if (paramssa != null){
                    for (String key : paramssa.keySet()) {
                        multipartBodyBuilder.addFormDataPart(key, paramssa.get(key));
                    }
                }
                //遍历paths中所有图片绝对路径到builder,并约定key如“upload”作为后台接受多张图片的key
                if (filessa != null){
                    for (File file : filessa) {
                        multipartBodyBuilder.addFormDataPart(pic_key, file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file));
                    }
                }
                //构建请求体
                RequestBody requestBody = multipartBodyBuilder.build();
                Request.Builder RequestBuilder = new Request.Builder();
                RequestBuilder.url(reqUrl);// 添加URL地址
                RequestBuilder.post(requestBody);
                Request request = RequestBuilder.build();
                okHttpClient.newCall(request).enqueue(new Callback() {
                    @Override
                    public void onFailure(okhttp3.Call call, IOException e) {
                        emitter.onError(e);
                        emitter.onComplete();
                        call.cancel();
                    }

                    @Override
                    public void onResponse(okhttp3.Call call, Response response) throws IOException {
                        String str = response.body().string();
                        emitter.onNext(str);
                        emitter.onComplete();
                        call.cancel();
                    }
                });
            }
        });
    }
    /**
     * 发送get请求
     * @param url 请求地址
     * @param params 请求参数
     * @param callback 回调
     * @param <T> 请求回来的数据对应的JavaBean
     */
    @Override
    public <T> void get(String url, Map<String, String> params, final MyNetWorkCallback<T> callback) {
        StringBuffer sb = new StringBuffer(url);
        if(params != null && params.size() > 0){
            sb.append("?");
            Set<String> keys = params.keySet();
            for (String key : keys) {
                String value = params.get(key);
                sb.append(key).append("=").append(value).append("&");
            }
            url = sb.deleteCharAt(sb.length()-1).toString();
        }
        Request request = new Request.Builder().url(url).build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(okhttp3.Call call, IOException e) {
                App.context.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //执行在主线程
                        callback.onError(404,e.getMessage().toString());
                    }
                });
            }

            @Override
            public void onResponse(okhttp3.Call call, Response response) throws IOException {
                final String jsonData = response.body().string();
                //执行在子线程中
                App.context.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //执行在主线程
                        callback.onSuccess(getGeneric(jsonData,callback));
                    }
                });
            }
        });
    }

    @Override
    public <T> void get(String url, Map<String, String> params, Map<String, String> headers, final MyNetWorkCallback<T> callback) {

        StringBuffer sb = new StringBuffer(url);
        if(params != null && params.size() > 0){
            sb.append("?");
            Set<String> keys = params.keySet();
            for (String key : keys) {
                String value = params.get(key);
                sb.append(key).append("=").append(value).append("&");
            }
            url = sb.deleteCharAt(sb.length()-1).toString();
        }
        Request.Builder builder = new Request.Builder();
        if(headers != null && headers.size() > 0){
            Set<String> keys = headers.keySet();
            for (String key : keys){
                String value = headers.get(key);
                builder.addHeader(key,value);
            }
        }
        Request request = builder.url(url).build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(okhttp3.Call call, IOException e) {
                App.context.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //执行在主线程
                        callback.onError(404,e.getMessage().toString());
                    }
                });
            }

            @Override
            public void onResponse(okhttp3.Call call, Response response) throws IOException {
                final String jsonData = response.body().string();
                //执行在子线程中
                App.context.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //执行在主线程
                        callback.onSuccess(getGeneric(jsonData,callback));
                    }
                });
            }
        });
    }

    /**
     * post方法上传表单
     * @param url
     * @param params
     * @param callback
     * @param <T>
     */
    @Override
    public <T> void post(String url, Map<String, String> params, final MyNetWorkCallback<T> callback) {

        FormBody.Builder builder = new FormBody.Builder();
        if(params !=null && params.size() > 0){
            Set<String> keys = params.keySet();
            for (String key : keys) {
                String value = params.get(key);
                builder.add(key,value);
            }
        }
        Request request = new Request.Builder().url(url).post(builder.build()).build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(okhttp3.Call call, IOException e) {
                App.context.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //执行在主线程
                        callback.onError(404,e.getMessage().toString());
                    }
                });
            }

            @Override
            public void onResponse(okhttp3.Call call, Response response) throws IOException {
                final String jsonData = response.body().string();
                //执行在子线程中
                App.context.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //执行在主线程
                        callback.onSuccess(getGeneric(jsonData,callback));
                    }
                });
            }
        });
    }

/**
     * post方法上传raw表单
     * @param url
     * @param postBody
     * @param callback
     * @param <T>
     */
    @Override
    public <T> void postraw(String url, String postBody, MyNetWorkCallback<T> callback) {
        MediaType MEDIA_TYPE_TEXT = MediaType.parse("application/json; charset=utf-8");
        Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(MEDIA_TYPE_TEXT, postBody))
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                App.context.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //执行在主线程
                        callback.onError(404,e.getMessage().toString());
                    }
                });

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String jsonData = response.body().string();
                App.context.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //执行在主线程
                        callback.onSuccess((T) jsonData);
                    }
                });
            }
        });
    }
    /**
     * post方法上传raw文件
     * @param url
     * @param file
     * @param callback
     * @param <T>
     */
    @Override
    public <T> void postrawfile(String url, File file, MyNetWorkCallback<T> callback) { 
        final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
        Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))
                .build();

        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                App.context.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //执行在主线程
                        callback.onError(404,e.getMessage().toString());
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String jsonData = response.body().string();
                App.context.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //执行在主线程
                        callback.onSuccess((T) jsonData);
                    }
                });
            }
        });
    }
    @Override
    public void upload(String url, String path, Map<String, String> params, String fileType, MediaType MEDIA_TYPE, final MyNetWorkCallback<String> callback) {
        File file = new File(path);
        MultipartBody.Builder  multiRequestBody = new MultipartBody.Builder();
        if(params !=null && params.size() > 0){
            Set<String> keys = params.keySet();
            for (String key : keys) {
                String value = params.get(key);
                multiRequestBody.setType(MultipartBody.FORM)
                        .addFormDataPart(key, value);// 提交普通字段
            }
        }
        // 上传文件使用MultipartBody.Builder
        RequestBody requestBody = multiRequestBody
                .setType(MultipartBody.FORM)
                .addFormDataPart(fileType, file.getName(), RequestBody.create(MEDIA_TYPE, file)) // 提交图片,第一个参数是键(name="第一个参数"),第二个参数是文件名,第三个是一个RequestBody
                .build();
        // POST请求
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(okhttp3.Call call, IOException e) {
                App.context.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //执行在主线程
                        callback.onError(404,e.getMessage().toString());
                    }
                });
            }

            @Override
            public void onResponse(okhttp3.Call call, Response response) throws IOException {
                final String upLoadResult=response.body().string();
                //执行在子线程中
                App.context.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //执行在主线程
                        callback.onSuccess(upLoadResult);
                    }
                });
            }
        });
    }

    @Override
    public void download() {

    }

    @Override
    public void loadImage(String url, ImageView imageView) {
        Glide.with(App.context).load(url).into(imageView);
    }
    /**
     * 自动解析json至回调中的JavaBean
     * @param jsonData
     * @param callBack
     * @param <T>
     * @return
     */
    private <T> T getGeneric(String jsonData, MyNetWorkCallback<T> callBack){
        Gson gson = new Gson();
        //通过反射获取泛型的实例
        Type[] types = callBack.getClass().getGenericInterfaces();
        Type[] actualTypeArguments = ((ParameterizedType) types[0]).getActualTypeArguments();
        Type type = actualTypeArguments[0];
        T t = gson.fromJson(jsonData,type);
        return t;
    }
    //取消
    public void cancel(String url, Map<String, String> params){
        FormBody.Builder builder = new FormBody.Builder();
        if(params !=null && params.size() > 0){
            Set<String> keys = params.keySet();
            for (String key : keys) {
                String value = params.get(key);
                builder.add(key,value);
            }
        }
        Request request = new Request.Builder().url(url).post(builder.build()).build();
        okHttpClient.newCall(request).cancel();
    }
}

You will find a lot of problems. What kind of APP must have it () How to check for updates:

public  class App extends Application {
    public static MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
    public static MainActivity context = null;

}

The preparation work is complete, don't delay everyone's time and start using: form request:

private Map<String, String> map = new HashMap<>();
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//很重要的一行,要不然你就空指针去吧
        App.context = this;

    }

Feel free to write a method to see your mood:

map.put("currentLang", "2");
                OkHttpUtils.getInstance().post(ApiUrl.HTTP_LOG, map, new MyNetWorkCallback<写自己的Bean>() {
                    @Override
                    public void onSuccess(写自己的Bean s) {
//解析
                        Gson gson = new Gson();
//变成实体类了自己用吧,随便用已经在子线程了随便吐司。
                        写自己的Bean logBean = gson.fromJson(s, 写自己的Bean.class);
                        Toast.makeText(MainActivity.this, "登入成功", Toast.LENGTH_SHORT).show();

                    }

                    @Override
                    public void onError(int errorCode, String errorMsg) {
                        Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show();
                    }
                });

 

Want pictures? coming:

Map<String, String> map = new HashMap<>();
        map.put("accessToken", toKen);
OkHttpUtils.getInstance().sendMultipart(path, map, "imgData", 存放图片的集合listfiles)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.newThread())
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable throwable) {
                        dialog.dismiss();
                        Toast.makeText(ComputerRoomPatrolavtivity.this, "上传失败了", Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onNext(String s) {
                        s = s.trim();
                        s = s.substring(1, s.length() - 1);//去除首尾双引号。
                        String str = s.replace("\\", "");//去除所有的\
                        Gson gson = new Gson();
                        Log.e("TAG", "str=" + str);
                            ToastShow.show(ComputerRoomPatrolavtivity.this, "上传成功");
                        } else {
                            dialog.dismiss();
                            ToastShow.show(ComputerRoomPatrolavtivity.this, "失败" + bean.getErrorMessage());
                        }
                    }
                });

 

Friendly reminder, my photos are compressed before uploading, so uploading is more enjoyable. I am using Luban compression. Maybe it's very old. Let's see.

implementation 'top.zibin:Luban:1.1.3'
Luban.get(this)
                .load(file)                     //传人要压缩的图片
                .putGear(Luban.THIRD_GEAR)      //设定压缩档次,默认三挡
                .setCompressListener(new OnCompressListener() { //设置回调

                    @Override
                    public void onStart() {
                        // TODO 压缩开始前调用,可以在方法内启动 loading UI
                    }

                    @Override
                    public void onSuccess(File file) {
                        // TODO 压缩成功后调用,返回压缩后的图片文件
                        listFileImages.add(file);
                            //网络请求
                            httpssa(listFileImages,toKen,dataId);
                    }

                    @Override
                    public void onError(Throwable e) {
                        // TODO 当压缩过去出现问题时调用
                    }
                }).launch(); 

 

The current project has not involved long-transfer pictures, and when it comes to my own use, I am improving,

In the friendly reminder, the long-pass picture observer mode in rxjava may have some changes. Check the latest one for yourself, and then call it. It should be the old one. If you don’t use it, wait for me to update it.

Thanks to novices for learning, big guys for guidance.

Guess you like

Origin blog.csdn.net/q992767879/article/details/112874535