Android中OkHttp使用(包括上传与下载)


OkHttp介绍

OkHttp是Square公司的出品,一个Http请求库,Google官方文档不推荐人们使用HttpClient,可是HttpURLConnection 实在是太难用了,因此很多人使用了OkHttp 来解决这问题, Android4.4 的源码中HttpURLConnection 已经替换成OkHttp 实现。

使用OkHttp的好处

1、OkHttp 处理了很多网络疑难杂症:会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,OkHttp会自动尝试下一个IP。OkHttp还处理了代理服务器问题和SSL握手失败问题。

2、使用 OkHttp 无需重写您程序中的网络代码。OkHttp实现了几乎和java.net.HttpURLConnection一样的API。如果你用了 Apache HttpClient,则OkHttp也提供了一个对应的okhttp-apache 模块。

OkHttp使用方法

1、环境配置

APPbuild.gradle配置依赖包,okHttp依赖okIo所以需要导入okIo 

compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okio:okio:1.10.0'


AndroidManifest.xml 加入网络权限

<uses-permission android:name="android.permission.INTERNET" />

2基本使用

2.1、HTTP GET 请求

/**
 * Http Get 请求
 */
private void httpGet() {
    ///创建okHttpClient对象
    OkHttpClient mOkHttpClient = new OkHttpClient();
    //创建一个Request Request是OkHttp中访问的请求,Builder是辅助类。Response即OkHttp中的响应。
    final Request request = new Request.Builder()
            .url("http://ip.taobao.com/service/getIpInfo.php?ip=63.223.108.42")
            .build();
    //得到一个call对象
    Call call = mOkHttpClient.newCall(request);
    //请求加入调度
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            //请求失败
            Log.e("TAG", "请求失败");
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            //不是UI线程,请不要在此更新界面
            String htmlStr = response.body().string();
            Log.e("TAG", "htmlStr ==" + htmlStr);
        }
    });
}

   
   
  1. 以上就是发送一个get请求的步骤,首先构造一个Request对象,参数最起码有个url,当然你可以通过Request.Builder设置更多的参数比如:headermethod等。

  2. 然后通过request的对象去构造得到一个Call对象,类似于将你的请求封装成了任务,既然是任务,就会有execute()cancel()等方法。

  3. 最后,以异步的方式去执行请求,所以我们调用的是call.enqueue,将call加入调度队列,然后等待任务执行完成,我们在Callback中即可得到结果。

3、Http中POST请求

/**
 * Http Post请求
 */
private void httpPost() {
    OkHttpClient mOkHttpClient = new OkHttpClient();
    RequestBody requestBody = new FormBody.Builder()
            .add("ip", "63.223.108.42")
            .build();
    okhttp3.Request request = new okhttp3.Request.Builder()
            .url("http://ip.taobao.com/service/getIpInfo.php?")
            .post(requestBody)
            .build();
    mOkHttpClient.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            //请求失败
            Log.e("TAG", "请求失败");
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            String htmlStr = response.body().string();
            Log.e("TAG", "htmlStr ==" + htmlStr);
        }
    });
}

使用Request的post方法来提交请求体RequestBody

RequestBody类为绑定请求参数如果有多个参数绑定方法如下:

RequestBody requestBody = new FormBody.Builder()
        .add("ip", "63.223.108.42")
        .add("ip1", "63.223.108.43")
        .add("ip2", "63.223.108.44")
        .build();

2.3、上传文件


在AndroidManifest.xml加入读取设备外部存储空间和sdcard权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

首先需要定义上传文件的类型:
public static final MediaType MEDIA_TYPE_MARKDOWN
        = MediaType.parse("text/x-markdown; charset=utf-8");
 
属性: 
text/html : HTML格式
text/plain :纯文本格式      
text/xml :  XML格式
image/gif :gif图片格式    
image/jpeg :jpg图片格式 
image/png:png图片格式
以application开头的媒体格式类型:

application/xhtml+xml :XHTML格式
application/xml     : XML数据格式
application/atom+xml  :Atom XML聚合格式    
application/json    : JSON数据格式
application/pdf       :pdf格式  
application/msword  : Word文档格式
application/octet-stream : 二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)

另外一种常见的媒体格式是上传文件之时使用的:
multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式
注意:MediaType.parse("image/png")里的"image/png"不知道该填什么,可以参考---》http://www.w3school.com.cn/media/media_mimeref.asp
如何使用呢?(在请求体里面写入类型和需要写入的数据,通过post请求)
String body = "hdsoifhjoihdsfh";
RequestBody body = RequestBody.create(MEDIA_TYPE_MARKDOWN, body);
sdcard 根目录的test.txt文件上传到服务器
/**
 * 上传文件
 */
private void postAsynFile() {
    OkHttpClient mOkHttpClient = new OkHttpClient();
    File file = new File("/sdcard/test.txt");
    Request request = new Request.Builder()
            .url("https://api.github.com/markdown/raw")
            .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))
            .build();

    mOkHttpClient.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Log.e("TAG", "上传失败!");
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            Log.e("TAG", response.body().string());
        }
    });
}
注:测试时在test.txt文件中是什么文字,服务器将会把里面的文字返回表示成功。

2.4、下载文件

下载文件实现起来比较简单,在这里下载一张图片,我们得到Response后将流写进我们指定的图片文件中就可以了。
/**
 * 下载文件
 */
private void downAsynFile() {
    OkHttpClient mOkHttpClient = new OkHttpClient();
    String url = "https://www.baidu.com/img/bd_logo1.png";
    Request request = new Request.Builder().url(url).build();
    mOkHttpClient.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {

        }

        @Override
        public void onResponse(Call call, Response response) {
            InputStream inputStream = response.body().byteStream();
            FileOutputStream fileOutputStream = null;
            try {
                fileOutputStream = new FileOutputStream(new File("/sdcard/baidu.png"));
                byte[] buffer = new byte[2048];
                int len = 0;
                while ((len = inputStream.read(buffer)) != -1) {
                    fileOutputStream.write(buffer, 0, len);
                }
                fileOutputStream.flush();
            } catch (IOException e) {
                Log.e("TAG", "IOException");
                e.printStackTrace();
            }

            Log.d("TAG", "文件下载成功");
        }
    });
}

OkHttp方法封装


根据上面代码写多个请求肯定包含大量的重复代码,所以需要进行封装,在GitHub上有个封装非常好的工具类名为OkHttpUtils,地址:https://github.com/hongyangAndroid/okhttputils

1、OkHttpUtils使用Get请求

 OkHttpClientManager.getAsyn("https://www.baidu.com", new OkHttpClientManager.ResultCallback<String>()
        {
            @Override
            public void onError(Request request, Exception e)
            {
                e.printStackTrace();
            }

            @Override
            public void onResponse(String u)
            {
                mTv.setText(u);//注意这里是UI线程
            }
        });
对于一般的请求,我们希望给个url,然后CallBack里面直接操作控件。

2、OkHttpUtils文件上传且携带参数

 OkHttpClientManager.postAsyn("http://192.168.1.103:8080/okHttpServer/fileUpload",//
    new OkHttpClientManager.ResultCallback<String>()
    {
        @Override
        public void onError(Request request, IOException e)
        {
            e.printStackTrace();
        }

        @Override
        public void onResponse(String result)
        {

        }
    },//
    file,//第三个参数 文件
    "mFile",//文件名 对应于http中的<input type="file" name="mFile" >
    new OkHttpClientManager.Param[]{
            new OkHttpClientManager.Param("username", "zhy"),
            new OkHttpClientManager.Param("password", "123")}
        );

3、OkHttpUtils文件下载 

对于文件下载,提供url,目标dir,callback即可。
OkHttpClientManager.downloadAsyn(
    "http://192.168.1.103:8080/okHttpServer/files/messenger_01.png",    
    Environment.getExternalStorageDirectory().getAbsolutePath(), 
new OkHttpClientManager.ResultCallback<String>()
    {
        @Override
        public void onError(Request request, IOException e)
        {

        }

        @Override
        public void onResponse(String response)
        {
            //文件下载成功,这里回调的reponse为文件的absolutePath
        }
});



在Github上有有个封装好的okhttputils类,使用起来非常方便
https://github.com/hongyangAndroid/okhttputils
该封装类是鸿洋大神编写,博客地址
http://blog.csdn.net/lmj623565791/article/details/47911083












  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值