Okhttp的用法

来自慕课网

使用okhttp的第一步就是应该在自己工程的module/build.gradle中引入支持库,如下所示:

implementation 'com.squareup.okhttp3:okhttp:3.9.1'
okhttp的使用分为同步和异步,同步需要在子线程中使用,而异步不需要;okhttp一般的使用请求方式有get请求和post请求,get请求一般用来向服务器获取数据,pos请求用来向服务器提交数据。post请求方式用来postString,postFile,upload,get请求方式用来download,downloadImage等操作,下面是具体的操作实现栗子

一 、 get方式用来进行模拟登录,将服务器返回的结果设置到textview上

public class SecondActivity extends AppCompatActivity {
    private static final String TAG = "SecondActivity";
    private Button doGetButton;
    private TextView mResultTextView;
    private String mBaseUrl = "http://169.254.66.218:8080/okhttp/";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        doGetButton = (Button) findViewById(R.id.btu_doGet);
        mResultTextView = (TextView) findViewById(R.id.tv_result);
        doGetButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                doGet();
            }

        });
    }
    private void doGet(){
        OkHttpClient okHttpClient = new OkHttpClient();
        //1、拿到OkHttpClient对象
        //2.构造Request
        Request.Builder builder = new Request.Builder();
        Request request = builder
                .get()
                .url(mBaseUrl + "login?username=hyman&password=1234")
                .build();
        //3.将Request封装为call
        Call call = okHttpClient.newCall(request);
        //4.执行call
        // 同步方式  Response reaponse = call.execute();
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "onFailure: " + e.getMessage());
                e.printStackTrace();
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.e(TAG, "onResponse: " + response);
                final String res = response.body().string();
                Log.e(TAG, "onResponse: " + res);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mResultTextView.setText(res);
                    }
                });
            }
        });
    }
}
二、 post方式用来进行模拟登录,将服务器返回的结果设置到textview上

public class SecondActivity extends AppCompatActivity {
    private static final String TAG = "SecondActivity";
    private Button doPostButton;
    private TextView mResultTextView;
    private String mBaseUrl = "http://169.254.66.218:8080/okhttp/";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        doPostButton = (Button) findViewById(R.id.btu_doPost);
        mResultTextView = (TextView) findViewById(R.id.tv_result);
        doPostButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                doGet();
            }

        });
    }
    private void doGet(){
        //1、拿到OkHttpClient对象
        OkHttpClient okHttpClient = new OkHttpClient();
        //2.构造RequestBody
        RequestBody requestBody = new FormBody.Builder()
                .add("username", "admin")
                .add("password", "123")
                .build();
        //2.1构造Request
        Request request = new Request.Builder()
                .url(mBaseUrl + "login")
                .post(requestBody)
                .build();
        //3.将Request封装为call
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "onFailure: " + e.getMessage());
                e.printStackTrace();
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.e(TAG, "onResponse: " + response);
                final String res = response.body().string();
                Log.e(TAG, "onResponse: " + res);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mResultTextView.setText(res);
                    }
                });
            }
        });
    }
}
三、 post方式向服务器提交字符串

private void doPostString() {
    //1、拿到OkHttpClient对象
    //2.构造RequestBody
    RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain;charset=utf-8"), "{username:hyman,password:123}");
    //2.1构造Request
    Request request = new Request.Builder()
            .url(mBaseUrl + "postString")
            .post(requestBody)
            .build();
    //3.将Request封装为call
    Call call = okHttpClient.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.e(TAG, "onFailure: " + e.getMessage());
            e.printStackTrace();
        }
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            Log.e(TAG, "onResponse: " + response);
            final String res = response.body().string();
            Log.e(TAG, "onResponse: " + res);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mResultTextView.setText(res);
                }
            });
        }
    });
}
四、 post方式向服务器提交文件,其中image.jpg是在sd卡存储目录中放置好的一张图片

private void doPostFile() {
    //1、拿到OkHttpClient对象
    //File sdCard = Environment.getExternalStorageDirectory();
    File file = new File(Environment.getExternalStorageDirectory(), "image.jpg");
    if (!file.exists()) {
        Log.e(TAG, "run: " + file.getAbsolutePath() + "not exists!");
    }
    //2.构造RequestBody
    //mime type
    RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
    //2.1构造Request
    Request request = new Request.Builder()
            .url(mBaseUrl + "postFile")
            .post(requestBody)
            .build();
    //3.将Request封装为call
    Call call = okHttpClient.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {

            Log.e(TAG, "onFailure: " + e.getMessage());
            e.printStackTrace();
        }
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            Log.e(TAG, "onResponse: " + response);
            final String res = response.body().string();
            Log.e(TAG, "onResponse: " + res);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mResultTextView.setText(res);
                }
            });
        }
    });
}
五、post方式上传文件,上传文件涉及一个客户端文件上传的进度问题,通过继承RequestBody自己实现方法回调

//上传文件
private void doUpload() {
    //1、拿到OkHttpClient对象
    //File sdCard = Environment.getExternalStorageDirectory();
    File file = new File(Environment.getExternalStorageDirectory(), "image.jpg");
    if (!file.exists()) {
        Log.e(TAG, "run: " + file.getAbsolutePath() + "not exists!");
    }
    RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
            .addFormDataPart("username", "hyman")
            .addFormDataPart("password", "12345")
            .addFormDataPart("mPhoto", "hyman.jpg", RequestBody.create(MediaType.parse("application/octet-stream"), file)).build();
    //上传文件的进度条问题
    CountingRequestBody countingRequestBody = new CountingRequestBody(body, new CountingRequestBody.Listener() {
        @Override
        public void onRequestProgress(long bytesWritten, long contentLength) {

            Log.e(TAG, bytesWritten + " / " + contentLength);
        }
    });
    //2.构造RequestBody
    //mime type
    // RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
    //2.1构造Request
    Request request = new Request.Builder()
            .url(mBaseUrl + "uploadInfo")
            .post(countingRequestBody)
            .build();

    //3.将Request封装为call
    Call call = okHttpClient.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {

            Log.e(TAG, "onFailure: " + e.getMessage());
            e.printStackTrace();
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {

            Log.e(TAG, "onResponse: " + response);
            final String res = response.body().string();
            Log.e(TAG, "onResponse: " + res);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mResultTextView.setText(res);
                }
            });
        }
    });
}
CountingRequestBody的内容为

public class CountingRequestBody extends RequestBody {
    protected RequestBody delegate;
    private Listener listener;
    private CountingSink mCountingSink;


    public CountingRequestBody(RequestBody delegate, Listener listener){
        this.delegate = delegate;
        this.listener = listener;
    }

    @Nullable
    @Override
    public MediaType contentType() {
        return delegate.contentType();
    }
    @Override
    public long contentLength() throws IOException {
        return delegate.contentLength();
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        mCountingSink = new CountingSink(sink);
        BufferedSink bufferedSink = Okio.buffer(mCountingSink);
        delegate.writeTo(bufferedSink);
        bufferedSink.flush();//刷新
    }

    protected final class CountingSink extends ForwardingSink{
        private long bytesWritten;

        public CountingSink(Sink delegate){
            super(delegate);
        }

        @Override
        public void write(Buffer source, long byteCount) throws IOException {
            super.write(source, byteCount);
            bytesWritten += byteCount;
            listener.onRequestProgress(bytesWritten,contentLength());
        }
    }

    public static interface Listener{
        //已写入的字节数---总共的字节数
        void onRequestProgress(long bytesWritten,long contentLength);
    }
}
六、get方式下载文件,其中files/hyman.jpg是在服务器端存在的一张图片文件,是在tomcat/webapps/okhttp/新建的files文件夹下的hyman.jpg,即第五种情况下上传好的图片文件

//下载文件
private void doDownload() {
    //1、拿到OkHttpClient对象
    //2.构造Request
    Request.Builder builder = new Request.Builder();
    Request request = builder
            .get()
            .url(mBaseUrl + "files/hyman.jpg")
            .build();
    //3.将Request封装为call
    Call call = okHttpClient.newCall(request);
    //4.执行call
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.e(TAG, "onFailure: " + e.getMessage());
            e.printStackTrace();
        }
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            Log.e(TAG, "onResponse: ");
            //下载进度问题
            final long total = response.body().contentLength();
            long sum = 0L;
            InputStream is = response.body().byteStream();

            int len = 0;
            File file = new File(Environment.getExternalStorageDirectory(), "hyman_xiazai.jpg");
            FileOutputStream fos = new FileOutputStream(file);
            byte[] buf = new byte[128];
            while ((len = is.read(buf)) != -1) {
                fos.write(buf, 0, len);
                sum += len;
                Log.e(TAG, sum + " / " + total);
                final long finalSum = sum;
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mResultTextView.setText(finalSum + " / " + total);
                    }
                });
            }
            fos.flush();
            fos.close();
            is.close();
            Log.e(TAG, "onResponse: download success");
        }
    });

}
七、get方式下载图片   下载图片涉及图片的一个大小尺寸适配问题,应该根据合适的方式进行缩放等

//下载图片
public void doDownloadImage(View view) {
    //1、拿到OkHttpClient对象
    //2.构造Request
    Request.Builder builder = new Request.Builder();
    Request request = builder
            .get()
            .url(mBaseUrl + "files/hyman.jpg")
            .build();
    //3.将Request封装为call
    Call call = okHttpClient.newCall(request);
    //4.执行call
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {

            Log.e(TAG, "onFailure: " + e.getMessage());
            e.printStackTrace();
        }
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            Log.e(TAG, "onResponse: ");
            InputStream is = response.body().byteStream();
            final Bitmap bitmap = BitmapFactory.decodeStream(is);
            Log.e(TAG, "onResponse: bitmap is width:" + bitmap.getWidth() + " bitmap is height:" + bitmap.getHeight());
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mResultImageView.setImageBitmap(bitmap);
                }
            });
        }
    });
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值