美文网首页探索Android常用框架
Android框架之路——OKHttp的使用

Android框架之路——OKHttp的使用

作者: Mr丶sorrow | 来源:发表于2017-05-10 11:22 被阅读0次

    一、简介

    OKHttp是一款高效的HTTP客户端,支持连接同一地址的链接共享同一个socket,通过连接池来减小响应延迟,还有透明的GZIP压缩,请求缓存等优势,其核心主要有路由、连接协议、拦截器、代理、安全性认证、连接池以及网络适配,拦截器主要是指添加,移除或者转换请求或者回应的头部信息。

    这个库也是square开源的一个网络请求库(okhttp内部依赖okio),现在已被Google使用在Android源码上。

    官网地址:http://square.github.io/okhttp/
    Github Wiki:https://github.com/square/okhttp/wiki
    Wiki 翻译:http://blog.csdn.net/jackingzheng/article/details/51778793

    OKHttp的功能:

    • 联网请求文本数据
    • 大文件下载
    • 大文件上传
    • 请求图片

    二、添加依赖

    compile 'com.squareup.okhttp3:okhttp:3.7.0'
    

    三、解锁技能

    <1> 使用原生OKHttp的Get请求

    1. 添加网络权限;

       <uses-permission android:name="android.permission.INTERNET"/>
      
    2. 使用http://square.github.io/okhttp/中示例get方法,该方法请求url地址只能在子线程中运行;

       /**
        * get请求,要求在子线程运行
        * @param url
        * @return
        * @throws IOException
        */
       private String get(String url) throws IOException {
           Request request = new Request.Builder()
                   .url(url)
                   .build();
      
           Response response = client.newCall(request).execute();
           return response.body().string();
       }
      
    3. 开辟子线程get方式请求数据;

       case R.id.button:
              new Thread(){
                  @Override
                  public void run() {
                      super.run();
                      try {
                          String result = get("http://gank.io/api/data/Android/2/1");
                          Message msg = Message.obtain();
                          msg.what = GET;
                          msg.obj = result;
                          mHandler.sendMessage(msg);
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  }
              }.start();
              break;
      
    4. 通过handler更新ui,显示请求结果。

       case GET:
          mTextView2.setText((String) msg.obj);
          break;
      

    <2> 使用原生OKHttp的Post请求

    1. 官网示例post方法,也需要在子线程中运行;

       /**
        * post请求
        * @param url
        * @param json 上传时需要json
        * @return
        * @throws IOException
        */
       private String post(String url, String json) throws IOException {
           RequestBody body = RequestBody.create(JSON, json);
           Request request = new Request.Builder()
                   .url(url)
                   .post(body)
                   .build();
           Response response = client.newCall(request).execute();
           return response.body().string();
       }
      
    2. 开辟子线程psot请求数据;

       new Thread(){
           @Override
           public void run() {
               super.run();
               try {
                   String result = post("http://api.m.mtime.cn/PageSubArea/TrailerList.api", null);
                   Message msg = Message.obtain();
                   msg.what = POST;
                   msg.obj = result;
                   mHandler.sendMessage(msg);
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }.start();
      

    <3> 使用第三方封装的OKHttp库okhttp-utils(鸿洋大神出品)

    我们使用原生的OKHttp时,需要自己去开辟子线程请求网络数据,然后通过Handler去更新UI,很麻烦,需要我们想法设法可以再次封装,方便我们的使用。

    1. 鸿洋博客地址:http://blog.csdn.net/lmj623565791/article/details/49734867/

    2. 添加依赖:compile 'com.zhy:okhttputils:2.6.2';

    3. 使用OkhttpUtils进行get请求;

      /**
       * 使用OkhttpUtils进行get请求
       * @param url url地址
       * @param id 请求ID号
       */
      private void getByOkhttpUtils(String url, int id) {
          OkHttpUtils.get().url(url).id(id).build().execute(new StringCallback() {
              @Override
              public void onError(Call call, Exception e, int id) {
                  e.printStackTrace();
                  mTextView2.setText(e.getMessage());
              }
      
              @Override
              public void onResponse(String response, int id) {
                  mTextView2.setText(response);
                  switch (id){
                      case 100:
                          Toast.makeText(getApplicationContext(), "100请求成功", Toast.LENGTH_SHORT).show();
                          break;
                  }
              }
          });
      }    
      
    4. 使用OkhttpUtils进行post请求;

       /**
        * 使用OkhttpUtils进行post请求
        * @param url
        * @param id
        */
       private void postByOkhttpUtils(String url, int id) {
           OkHttpUtils.post().url(url).id(id).build().execute(mStringCallback);
       }
      
       ........
      
       //封装回调
       private StringCallback mStringCallback = new StringCallback() {
           @Override
           public void onError(Call call, Exception e, int id) {
               e.printStackTrace();
               mTextView2.setText(e.getMessage());
           }
      
           @Override
           public void onResponse(String response, int id) {
               mTextView2.setText(response);
               switch (id) {
                   case 100:
                       Toast.makeText(getApplicationContext(), "100get请求成功", Toast.LENGTH_SHORT).show();
                       break;
                   case 101:
                       Toast.makeText(getApplicationContext(), "101post请求成功", Toast.LENGTH_SHORT).show();
                       break;
               }
           }
       };   
      
    5. 下载文件,添加WRITE_EXTERNAL_STORAGE权限,设置回调并进行下载;

       //参数包含保存路径和保存文件名
       private FileCallBack mFileCallBack = new FileCallBack(Environment.getExternalStorageDirectory().getAbsolutePath(), "test.mp4") {
               @Override
               public void onError(Call call, Exception e, int id) {
                   e.printStackTrace();
                   mTextView2.setText(e.getMessage());
               }
      
           @Override
           public void inProgress(float progress, long total, int id) {
               super.inProgress(progress, total, id);
               mProgressBar.setProgress((int) (100 * progress));
               mTextView2.setText("下载进度:" + (int) (100 * progress) + "/%");
           }
      
           @Override
           public void onResponse(File response, int id) {
           }
       };
      
       ......
      
       /**
        * 使用OkhttpUtils进行下载大文件
        * @param url
        */
       private void downloadFileByOkhttpUtils(String url){
           OkHttpUtils.get().url(url).build().execute(mFileCallBack);
       }
      
    6. 文件上传;
      文件服务器搭建:下载链接,我的测试链接: http://192.168.1.102/FileUpload/index.jsp

       /**
        * 单文件或多文件上传
        * @param url url地址
        * @param id 请求id
        * @param username 用户名参数
        * @param files 文件集合
        */
       private void uploadFilesByOkhttpUtils(String url, int id, String username, List<File> files) {
           for (File file : files) {
               if (!file.exists()) {
                   Toast.makeText(getApplicationContext(), "文件" + file.getName() + "不存在", Toast.LENGTH_SHORT).show();
                   return;
               }
           }
           Map<String, String> params = new HashMap<>();
           params.put("username", username);
      
           PostFormBuilder builder = OkHttpUtils.post();
           for (File file : files) {
               builder = builder.addFile(username, "server" + file.getName(), file);
           }
           builder.url(url).id(id).params(params).build().execute(mStringCallback);
      
       }
      
       ......
      
       @OnClick(R.id.button3)
       public void onViewClicked() {
           List<File> files = new ArrayList<>();
           files.add(new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "QQ_8.9.2.20760_setup.exe"));
           files.add(new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "test.mp4"));
           uploadFilesByOkhttpUtils("http://192.168.1.102/FileUpload/FileUploadServlet", 102, "Mr.sorrow", files);
       }
      
    7. 请求图片;

       private BitmapCallback mBitmapCallback = new BitmapCallback() {
           @Override
           public void onError(Call call, Exception e, int id) {
               e.printStackTrace();
               mTextView2.setText(e.getMessage());
           }
      
           @Override
           public void onResponse(Bitmap response, int id) {
               mImageView.setImageBitmap(response);
           }
       };      
      
       .......
      
       /**
        * 请求单张图片
        * @param url
        * @param id
        */
       private void getPicByOkhttpUtils(String url, int id) {
           OkHttpUtils
                   .get()
                   .url(url)
                   .tag(this)
                   .id(id)
                   .build()
                   .connTimeOut(20000)    //设置连接超时、读取超时、写入超时
                   .readTimeOut(20000)
                   .writeTimeOut(20000)
                   .execute(mBitmapCallback);
       }
      

    <4> 加载图片集合(并不是okhttp-utils的强项)

    1. Activity:

       public class ThirdActivity extends AppCompatActivity {
       
           private List<String> picsUrl;
       
           @BindView(R.id.listview)
           ListView mListview;
           @BindView(R.id.progressBar)
           ProgressBar mProgressBar;
           @BindView(R.id.textView)
           TextView mTextView;
       
           private StringCallback mStringCallback = new StringCallback() {
               @Override
               public void onError(Call call, Exception e, int id) {
                   e.printStackTrace();
                   mTextView.setVisibility(View.VISIBLE);
                   mProgressBar.setVisibility(View.GONE);
               }
       
               @Override
               public void onResponse(String response, int id) {
                   mTextView.setVisibility(View.GONE);
                   switch (id) {
                       case 100:
                           Toast.makeText(getApplicationContext(), "请求成功", Toast.LENGTH_SHORT).show();
                           break;
                   }
                   if (response != null) {
                       Meizi meizi1 = processData(response);
                       if (meizi1 != null) {
                           List<Meizi.ResultsBean> beanList = meizi1.getResults();
                           if (!beanList.isEmpty()) {
                               for (Meizi.ResultsBean resultsBean : beanList) {
                                   picsUrl.add(resultsBean.getUrl());
                                   Log.i("xxxxx", resultsBean.getUrl());
                               }
                           }
                       }
                   }
       
                   mListview.setAdapter(new MyAdapter(picsUrl, ThirdActivity.this));
       
                   mProgressBar.setVisibility(View.GONE);
               }
       
               @Override
               public void inProgress(float progress, long total, int id) {
                   super.inProgress(progress, total, id);
               }
           };
       
           /**
            * 解析json数据
            *
            * @param json
            */
           private Meizi processData(String json) {
               Gson gson = new Gson();
               return gson.fromJson(json, Meizi.class);
           }
       
           @Override
           protected void onCreate(@Nullable Bundle savedInstanceState) {
               super.onCreate(savedInstanceState);
               setContentView(R.layout.activity_third);
               ButterKnife.bind(this);
               picsUrl = new ArrayList<>();
               getDataByOkhttpUtils("http://gank.io/api/data/%E7%A6%8F%E5%88%A9/20/1", 100);
           }
       
           /**
            * get请求json数据
            *
            * @param url
            * @param id
            */
           private void getDataByOkhttpUtils(String url, int id) {
               OkHttpUtils.get().url(url).id(id).build().execute(mStringCallback);
           }
       }
      
    2. Adapter:

       public class MyAdapter extends BaseAdapter {
       
           private List<String> data;
           private Context mContext;
       
           public MyAdapter(List<String> data, Context context) {
               this.data = data;
               mContext = context;
           }
       
           @Override
           public int getCount() {
               return data.size();
           }
       
           @Override
           public String getItem(int position) {
               return data.get(position);
           }
       
           @Override
           public long getItemId(int position) {
               return position;
           }
       
           @Override
           public View getView(int position, View convertView, ViewGroup parent) {
               ViewHolder holder = null;
               if (convertView == null) {
                   convertView = View.inflate(mContext, R.layout.items, null);
                   holder = new ViewHolder(convertView);
                   convertView.setTag(holder);
               } else {
                   holder = (ViewHolder) convertView.getTag();
               }
       
               holder.mTvName.setText(getItem(position));
               holder.mTvDesc.setText(getItem(position));
       
               final ViewHolder finalHolder = holder;
               OkHttpUtils
                       .get()
                       .url(getItem(position))
                       .tag(this)
                       .build()
                       .connTimeOut(20000)    //设置连接超时、读取超时、写入超时
                       .readTimeOut(20000)
                       .writeTimeOut(20000)
                       .execute(new BitmapCallback() {
                           @Override
                           public void onError(Call call, Exception e, int id) {
       
                           }
       
                           @Override
                           public void onResponse(Bitmap response, int id) {
                               finalHolder.mIvIcon.setImageBitmap(response);
                           }
                       });
               return convertView;
           }
       
           static class ViewHolder {
               @BindView(R.id.iv_icon)
               ImageView mIvIcon;
               @BindView(R.id.tv_name)
               TextView mTvName;
               @BindView(R.id.tv_desc)
               TextView mTvDesc;
       
               ViewHolder(View view) {
                   ButterKnife.bind(this, view);
               }
           }
       }
      
    3. GsonFormat生成的实体Bean:

       public class Meizi {
           private boolean error;
           private List<ResultsBean> results;
       
           public boolean isError() {
               return error;
           }
       
           public void setError(boolean error) {
               this.error = error;
           }
       
           public List<ResultsBean> getResults() {
               return results;
           }
       
           public void setResults(List<ResultsBean> results) {
               this.results = results;
           }
       
           public static class ResultsBean {
               private String _id;
               private String createdAt;
               private String desc;
               private String publishedAt;
               private String source;
               private String type;
               private String url;
               private boolean used;
               private String who;
       
               public String get_id() {
                   return _id;
               }
       
               public void set_id(String _id) {
                   this._id = _id;
               }
       
               public String getCreatedAt() {
                   return createdAt;
               }
       
               public void setCreatedAt(String createdAt) {
                   this.createdAt = createdAt;
               }
       
               public String getDesc() {
                   return desc;
               }
       
               public void setDesc(String desc) {
                   this.desc = desc;
               }
       
               public String getPublishedAt() {
                   return publishedAt;
               }
       
               public void setPublishedAt(String publishedAt) {
                   this.publishedAt = publishedAt;
               }
       
               public String getSource() {
                   return source;
               }
       
               public void setSource(String source) {
                   this.source = source;
               }
       
               public String getType() {
                   return type;
               }
       
               public void setType(String type) {
                   this.type = type;
               }
       
               public String getUrl() {
                   return url;
               }
       
               public void setUrl(String url) {
                   this.url = url;
               }
       
               public boolean isUsed() {
                   return used;
               }
       
               public void setUsed(boolean used) {
                   this.used = used;
               }
       
               public String getWho() {
                   return who;
               }
       
               public void setWho(String who) {
                   this.who = who;
               }
           }
       }
      

    四、栗子效果

           演示视频

    五、栗子下载

           下载地址

    相关文章

      网友评论

        本文标题:Android框架之路——OKHttp的使用

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