OkHttp3全面解析&注解工具butterknife
来源:互联网 发布:桌面控制软件 编辑:程序博客网 时间:2024/06/14 11:18
前言:Okhttp3是一个强大的网络请求下载开源框架,本文将会对OkHttp3进行全面解析以及在代码中穿插butterknife的使用。
我将对OkHttp3进行下面六种用途的讲解:
- GET请求
- POST请求(Form表单形式)
- POST请求(JSON格式)
- 文件下载(简单方式)
- 文件下载(拦截器方式)
OkHttp3的简单封装
1.GET请求
对于网络加载库,那么最常见的肯定就是http get请求了,比如获取一个网页的内容。
//我们想像为生成一个客户端 OkHttpClient client = new OkHttpClient(); String url = "http://192.168.1.189:5000/user/info?id=1"; Request request = new Request.Builder() .url(url) .build(); //请求加入调度 client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.d("MainActivity","失败------"+e.getLocalizedMessage()); } @Override public void onResponse(Call call, Response response) throws IOException { String result = response.body().string(); Log.d("MainActivity","成功:"+result); if(response.body() !=null){ response.body().close(); } } });
我们得注意几点:
- 上传下载功能必须得用异步的方式进行,所以调用call.enqueue,将call加入调度队列,然后等待任务执行完成,我们在Callback中即可得到结果。
- onResponse回调的参数是response,我们希望获得返回的字符串,可以通过response.body().string()获取;这里我们要注意,把流形式转化为字符串用.string(),把Object形式的对象转化为字符串用.toString().
- 以流形式操作我们就可以通过IO的方式写文件。不过也说明一个问题,这个onResponse执行的线程并不是UI线程。的确是的,如果你希望操作控件,还是需要使用handler等。
@Overridepublic void onResponse(final Response response) throws IOException{ final String res = response.body().string(); runOnUiThread(new Runnable() { @Override public void run() { mTv.setText(res); } });}
在平时的学习中,我以及碰到好几次开源框架,如Fresco,OkHttp的代码用如下形式:
Request request = new Request.Builder() .url(url) .build();
我们对Request的源码进行分析,看看内部如何设计:
public final class Request {//静态内部类,所以可以用类访问,以及类直接调用构造器:new Request.Builder()来得到一个builder对象。 public static class Builder{//方法返回一个Builder对象 public Builder url(String url) { if (url == null) throw new IllegalArgumentException("url == null"); // Silently replace websocket URLs with HTTP URLs. if (url.regionMatches(true, 0, "ws:", 0, 3)) { url = "http:" + url.substring(3); } else if (url.regionMatches(true, 0, "wss:", 0, 4)) { url = "https:" + url.substring(4); } HttpUrl parsed = HttpUrl.parse(url); if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url); return url(parsed); } //最后面调用build()方法,返回Request实例 public Request build() { if (url == null) throw new IllegalStateException("url == null"); return new Request(this); }}}
通过对上面源码的分析,我们可以在以后对自己的工具类的封装中使用其思路,达到顺畅舒服的代码语法。
2.POST请求(Form形式)
下面的代码中将会穿插butterknife知识的讲解,butterknife把我们从繁琐的findViewById()以及事件的监听中解放出来,这里是它的官网butterknife。
POST请求和GET请求不一样的是:POST请求将要上传几个key-value键值对。这几个key-value键值对处于请求报文最后面的body中。其实在GET请求中也有一些key-value键值对,但其处于URL后面,以?key1=value&key2&value2的结构出现。下面是POST方法的使用实例:
public class LoginActivity extends AppCompatActivity { //直接把组建绑定给id @BindView(R.id.etxt_username) EditText mEtxtUsername; @BindView(R.id.etxt_password) EditText mEtxtPassword; @BindView(R.id.btn_login) Button mBtnLogin; private OkHttpClient httpClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); //将activity与组建绑定,而上一句把布局activity与布局绑定 ButterKnife.bind(this); httpClient= new OkHttpClient(); } //直接在id上设置点击事件 @OnClick(R.id.btn_login) public void onClick() { String username = mEtxtUsername.getText().toString().trim(); String password = mEtxtPassword.getText().toString().trim(); loginWithForm(username,password); }private void loginWithForm(String username, String password) { String url = Config.API.BASE_URL+"login"; //比GET方法多了一个RequestBody类,该类将提交参数加入 RequestBody body = new FormBody.Builder() .add("username",username) .add("password",password) .build(); Request request = new Request.Builder() .url(url) .post(body) .build(); httpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.d("LoginActivity","请求服务器出差"); } @Override public void onResponse(Call call, Response response) throws IOException { if(response.isSuccessful()){ String json = response.body().string(); try { //将json字符串转换为JSONObject对象,从中取出value JSONObject jsonObj = new JSONObject(json); final String message = jsonObj.optString("message"); final int success = jsonObj.optInt("success"); //如果需要实现对UI的操作,则需要使用runOnUiThread方法 runOnUiThread(new Runnable() { @Override public void run() { if(success==1) Toast.makeText(LoginActivity.this,"登录成功",Toast.LENGTH_LONG).show(); else Toast.makeText(LoginActivity.this,message,Toast.LENGTH_LONG).show(); } }); } catch (JSONException e) { e.printStackTrace(); } } } }); }}
3.POST请求(JSON形式)
JSONObject jsonObj = new JSONObject(); try { jsonObj.put("username",username); jsonObj.put("password",password); } catch (JSONException e) { e.printStackTrace(); } String jsonParams =jsonObj.toString(); Log.d("LoginActivity","json params = "+jsonParams); RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),jsonParams); Request request = new Request.Builder() .url(url) .post(body) .build();
- JSON形式提交是指先把提交的key-value对转换为JSONObject对象,将转换为字符串的JSONObject对象传入RequestBody中,请求调用request。
4.文件下载(简单方式)
- 我们将下载一个apk为例对文件下载进行讲解。
public class FileDownloadActivity extends AppCompatActivity { public String url ="http://112.124.22.238:8081/course_api/css/net_music.apk"; //定义下载后的文件名 public String fileName = "net_music.apk"; @BindView(R.id.btn_download) Button mBtnDownload; @BindView(R.id.progressBar) ProgressBar mProgressBar; private OkHttpClient httpClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_file_download); ButterKnife.bind(this); requestPermission(); initOKhttp(); } private void initOKhttp() { httpClient = new OkHttpClient();} //当点击download时调用downloadAPK()方法 @OnClick(R.id.btn_download) public void onClick() { downloadAPK(); } private void downloadAPK() { Request request = new Request.Builder() .url(url) .build(); httpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.d("LoginActivity","请求文件出差"); } @Override public void onResponse(Call call, Response response) throws IOException { //与前面俩种案例比较,区别在于对输入流的处理 writeFile(response); } }); } //在Handler类中调用handleMessage方法来对UI进行处理 Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { if(msg.what==1){ int progress = msg.arg1; mProgressBar.setProgress(progress); } } }; private void writeFile(Response response) { //输入流和输出流之间共接一个内存 InputStream is =null; FileOutputStream fos = null; //从response中得到输入流,inputStream is = response.body().byteStream(); //对文件的处理,得到文件路径,创建文件 String path = Environment.getExternalStorageDirectory().getAbsolutePath(); Log.d("FileDownloadActivity","path:"+path); //创建文件 File file = new File(path,fileName); try { fos = new FileOutputStream(file); byte[] bytes = new byte[1024]; int len =0; //提前的到文件的大小 long totalSize = response.body().contentLength(); long sum =0; while ((len =is.read(bytes)) !=-1){ fos.write(bytes); sum +=len; int progress = (int) ((sum * 1.0f / totalSize) * 100); //把message标示为1,上文中msg.what ==1来区分信息 Message msg = mHandler.obtainMessage(1); msg.arg1 = progress; //对UI的处理只能在UI线程中执行,所以把msg传给Handler处理 mHandler.sendMessage(msg); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { //文件流打开时,必须关闭! inputstream,outputStream try { if(is !=null){ is.close(); } if(fos !=null){ fos.close(); } } catch (IOException e) { e.printStackTrace(); } } }}
- 这段代码中将
response.body().byteStream
转换为输入流,接下来就是我们常写的读取输入流,写入文件的操作。这里注意Handler的使用,在Handler类中调用handleMessage方法,在方法内部对UI进行操作。在文件操作处,mHandler.sendMessage(msg);
将msg传到UI线程处。 - 还得注意在配置文件中配置权限
5.文件下载(拦截方式)
6.OkHttp3的封装(采用链式封装)
5,6俩点我尚未全部理解和实现,先放着,等我全部实现了再回来编辑,不好意思了,读者们。
4 0
- OkHttp3全面解析&注解工具butterknife
- butterknife注解框架源码解析
- 全面解析Java注解
- 全面解析Java注解
- 全面解析Java注解
- 全面解析 Java 注解
- 全面解析Java注解
- 全面解析Java注解
- Java注解全面解析
- 全面解析Java注解
- Java注解全面解析
- Java 注解全面解析
- 全面解析注解
- 全面解析java注解
- 全面解析Java注解
- 全面解析Java注解
- hibernate注解全面解析
- 全面解析Java注解
- Android 常用的adb命令
- android gridview 设置高度的方法和一些疑惑
- 数据结构和内存中堆和栈的区别
- 使用博客作为笔记的地方吧!
- MySQL 主从复制的原理和配置
- OkHttp3全面解析&注解工具butterknife
- Struts2 中实现将后台查询到的list传到前台页面的方法
- GoLang 捕获命令行参数
- DOS命令diskpart格式化磁盘
- PHP中多重循环以及thinkphp多重循环需要注意的地方
- Flex 布局教程:语法篇
- CentOS 安装docker
- Good Bye 2014 题解
- caffe程序运行流程