美文网首页
王学岗OKHttp从简单到复杂

王学岗OKHttp从简单到复杂

作者: 王学岗 | 来源:发表于2018-11-02 15:36 被阅读0次

    第一部分:快速使用

    如果你对OkHttp比较熟悉了,完全可以跳过第一部分。

    package com.example.okhttptest;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    
    import java.io.IOException;
    
    import okhttp3.Call;
    import okhttp3.Callback;
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.Response;
    
    public class MainActivity extends AppCompatActivity {
        private String testUrl = "http://119.253.81.55/tkheal/";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
        }
    
        public void getRequest(View view) {
            OkHttpClient okHttpClient = new OkHttpClient();
            Request request = new Request.Builder().url(testUrl + "/rungroup/getRankForGroupUser ").build();
            okHttpClient.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                   Log.i("王迪迪",e.getMessage());
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    Log.i("王迪迪","成功");
                    //response即是服务端给我们返回的对象
                    String result = response.body().string();
                    //因为response是一个流,所以我们需要关闭
                    if (response.body() != null) {
                        response.body().close();
                    }
                }
            });
        }
    }
    
    

    看下打印输出结果

    11-01 19:34:23.617 15107-15187/com.example.okhttptest I/王迪迪: 成功
    

    第二部分:Http协议简介

    这一部分只是http相关的一些知识,如果你比较熟悉http协议,建议跳过这一部分。


    1.png 1.png 1.png 1.png

    request介绍


    1.png

    Response介绍


    1.png

    第三部分:Get请求

    
    package com.example.okhttptest;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    
    import java.io.IOException;
    
    import okhttp3.Call;
    import okhttp3.Callback;
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.Response;
    
    public class MainActivity extends AppCompatActivity {
        private String testUrl = "http://119.253.81.55/tkheal/";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
        }
    
        public void getRequest(View view) {
            OkHttpClient okHttpClient = new OkHttpClient();
            Request request = new Request.Builder()
                    .get()
    //拼接请求参数
                    .url(testUrl + "/rungroup/getRankForGroupUser?groupId=5&type=0&userId=3805&page=1&pageSize=5&token=c9e784425cdc9f7091e5980fd7870b5f")
                    .build();
            okHttpClient.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                   Log.i("王迪迪",e.getMessage());
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    Log.i("王迪迪","成功");
                    //response即是服务端给我们返回的对象
                    String result = response.body().string();
                    Log.i("王迪迪","result:"+result);
                    //因为response是一个流,所以我们需要关闭
                    if (response.body() != null) {
                        response.body().close();
                    }
                }
            });
        }
    }
    
    

    get请求我们可以直接在url地址后面添加参数。使用? &。

    第四部分,post请求,使用form表单

    首先我推荐一个post测试工具——postman 1.png

    用户登陆,使用form表单

    
     private void loginWithForm(String name, String password) {
            OkHttpClient okHttpClient=new OkHttpClient.Builder().build();
            //传入参数
            RequestBody body=new FormBody.Builder().add("username",name).add("password",password).build();
            final Request request=new Request.Builder()
                    .url(testUrl)
                    //声明post请求
                    .post(body)
                    .build();
            okHttpClient.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.isSuccessful()){
                        String result=response.body().string();
                    }
                    //操作UI
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
    
                        }
                    });
    
                }
            });
            
        }
    

    这是用phthon写成的服务端


    1.png

    第五部分,post请求,使用json数据

    这是服务端


    1.png
    
     private void loginWithjson(String name, String password) {
            OkHttpClient okHttpClient=new OkHttpClient.Builder().build();
            JSONObject jsonObject=new JSONObject();
            try {
                jsonObject.put("username",name);
                jsonObject.put("password",password);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            String jsonParams=jsonObject.toString();
            RequestBody body=RequestBody.create(MediaType.parse("application/json;charset=utf-8"),jsonParams);
            final Request request=new Request.Builder()
                    .url(testUrl2)
                    //声明post请求
                    .post(body)
                    .build();
            okHttpClient.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.isSuccessful()){
                        String result=response.body().string();
                    }
                    //操作UI
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
    
                        }
                    });
    
                }
            });
            
        }
    
    

    第六部分,读取okhttp流下载文件

    private void downloadFile() {
            Request request = new Request.Builder().url(testUrl).build();
            okHttpClient.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
    
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
    //文件下载要返回的不是一个字符串,而是一个流。我们读取服务器返回的流,然后再写入本地
                    InputStream is = response.body().byteStream();
                    File file = null;
                    if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
                        file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(),"a.apk");
                    } else {
                        file = new File(getCacheDir().getAbsolutePath(), "a.apk");
                    }
                    //获取文件的长度
                    long total=response.body().contentLength();
                    //当前读取的长度
                    long sum=0;
                    FileOutputStream fileOutputStream=new FileOutputStream(file);
                    byte[] bytes=new byte[1024];
                    int len=0;
                    while((len=is.read(bytes))!=-1){
                        fileOutputStream.write(bytes);
                        sum=sum+len;
                        //这里可以使用handler message机制更新进度条,此处我略去,读者自己实现。
                        int progress = (int) ((float)sum / (float) total);
    
                    }
                }
                //关闭流的操作此处略去
            });
        }
    

    第七部分,拦截器下载文件

    第一步:创建一个类继承ResponseBody

    package com.example.okhttptest;
    
    import android.support.annotation.Nullable;
    
    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;
    
    public class ProgressResponseBody extends ResponseBody {
        private ResponseBody responseBody;
        private ProgressListenner progressListenner;
        private BufferedSource bufferedSource;
    
        public ProgressResponseBody(ResponseBody responseBody, ProgressListenner progressListenner) {
            this.responseBody = responseBody;
            this.progressListenner = progressListenner;
        }
    
        @Nullable
        @Override
        public MediaType contentType() {
            return responseBody.contentType();
        }
    
        @Override
        public long contentLength() {
            return responseBody.contentLength();
        }
    
        @Override
        public BufferedSource source() {
            if (bufferedSource == null) {
                bufferedSource = Okio.buffer(getSourse(responseBody.source()));
            }
            return bufferedSource;
        }
    
        //Okio是OkHttp底层IO操作
        //如果我们不实现进度条,那么这里可以什么也不写。
        private Source getSourse(Source source) {
            return new ForwardingSource(source) {
                long totalSize = 0l;
                long sum = 0;
    
                @Override
                public long read(Buffer sink, long byteCount) throws IOException {
                    long len = super.read(sink, byteCount);
                    if (totalSize == 0) {
                        totalSize = contentLength();
                    }
                    sum += (len == -1 ? 0 : len);
                    int progress = (int) ((float) sum / (float) totalSize);
                    if (len == -1) {
                        progressListenner.onDone(totalSize);
                    } else {
                        progressListenner.onProgress(progress);
                    }
                    return len;
                }
            };
        }
    
        public interface ProgressListenner {
            void onProgress(int progress);
    
            void onDone(long totalSize);
        }
    }
    
    
    
    package com.example.okhttptest;
    
    import android.os.Environment;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.ProgressBar;
    import android.widget.Toast;
    
    import org.json.JSONException;
    import org.json.JSONObject;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    import okhttp3.Call;
    import okhttp3.Callback;
    import okhttp3.FormBody;
    import okhttp3.Interceptor;
    import okhttp3.MediaType;
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.RequestBody;
    import okhttp3.Response;
    
    public class MainActivity extends AppCompatActivity {
        private String testUrl = "http://119.253.81.55/tkheal/";
        private ProgressBar progressBar;
        private OkHttpClient okHttpClient;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            progressBar = findViewById(R.id.progressbar);
            okHttpClient = new OkHttpClient();
            initOkHttpClient();
        }
    
        public void callNet(View view) {
            Request request = new Request.Builder().url(testUrl).build();
            okHttpClient.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
    
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
    //文件下载要返回的不是一个字符串,而是一个流。我们读取服务器返回的流,然后再写入本地
                    InputStream is = response.body().byteStream();
                    File file = null;
                    if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
                        file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "a.apk");
                    } else {
                        file = new File(getCacheDir().getAbsolutePath(), "a.apk");
                    }
                    //当前读取的长度
                    FileOutputStream fileOutputStream = new FileOutputStream(file);
                    byte[] bytes = new byte[1024];
                    int len = 0;
                    while ((len = is.read(bytes)) != -1) {
                        fileOutputStream.write(bytes);
                    }
                }
                //关闭流的操作此处略去
            });
        }
    
        private void initOkHttpClient() {
            okHttpClient = new OkHttpClient.Builder().addNetworkInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Response response = chain.proceed(chain.request());
    
                    return response.newBuilder().body(new ProgressResponseBody(response.body(), new Pg())).build();
                }
            }).build();
        }
    
        private class Pg implements ProgressResponseBody.ProgressListenner {
    
            @Override
            public void onProgress(final int progress) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        progressBar.setProgress(progress);
                    }
                });
            }
    
            @Override
            public void onDone(long totalSize) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "下载完成", Toast.LENGTH_LONG).show();
                    }
                });
            }
        }
    }
    
    

    第六部分:上传文件

    private void uploadFele(){
            OkHttpClient okHttpClient=new OkHttpClient.Builder().build();
            //图片数据类型
            // png : image/png
            //jpg : image/jpeg
            //gif : imge/gif
            //其它数据类型
    //        json : application/json
    //        xml : application/xml
            RequestBody requestBody=RequestBody.create(MediaType.parse("image.jpeg"),new File("/scard/a.jpg"));
            Request request=new Request.Builder()
                    .url(testUrl)
                    .post(requestBody)
                    .build();
            okHttpClient.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
    
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
    
                }
            });
        }
    

    第七部分:上传文件和文字

    在OkHttp中实现上传文件是MultipartBuilder,比如我们现在需要更改用户的信息。用户更改了姓名和头像,头像是一个文件,我们这里就需要上传文件。我们上传的信息包括文件和表单。

    
      private void uploadFileAndString() {
            OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
            File file = new File("/scard/a.png");
            //"application/octet-stream":传进去2进制流数据,流数据就包括文件和表单
            RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
            MultipartBody multipartBody = new MultipartBody.Builder()
                    //设置为form表单的类型
                    .setType(MultipartBody.FORM)
                    //name 和值
                    .addFormDataPart("name", "wangdidi")
                    //传入image字段,取名为"test.png"
                    .addFormDataPart("image", "test.png", fileBody).build();
            Request request = new Request.Builder()
                    .post(multipartBody)
                    .url(testUrl).build();
            okHttpClient.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
    
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
    
                }
            });
        }
    

    相关文章

      网友评论

          本文标题:王学岗OKHttp从简单到复杂

          本文链接:https://www.haomeiwen.com/subject/cszxxqtx.html