Android框架之路——OKHttp的使用

来源:互联网 发布:秦夕妍少女时捏脸数据 编辑:程序博客网 时间:2024/06/04 08:31

一、简介

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;        }    }}

四、栗子效果

       演示视频

五、栗子下载

       下载地址



个人公众号:每日推荐一篇技术博客,坚持每日进步一丢丢…欢迎关注,想建个微信群,主要讨论安卓和Java语言,一起打基础、用框架、学设计模式,菜鸡变菜鸟,菜鸟再起飞,愿意一起努力的话可以公众号留言,谢谢…

0 1
原创粉丝点击