Android OkHttp 框架学习(应用篇)

官方介绍:http://square.github.io/okhttp/
http://square.github.io/retrofit/
引用:
AndroidStudio:
compile 'com.squareup.okhttp3:okhttp:3.6.0'
compile 'com.squareup.okio:okio:1.5.0'

Eclipse:
LastedOkHttpJar
okioJar

注意:最新版本的okhttp已经内置了okio包)

一:服务的初始化
官方不建议我们创建多个HttpClient,对系统资源消耗较大,如果实在有需求可以clone。关于一些常用的初始化设置如下:

        client = new OkHttpClient();
        OkHttpClient.Builder b = client.newBuilder();
        b.connectTimeout(MAX_TIMEOUT, TimeUnit.SECONDS);
        b.writeTimeout(MAX_TIMEOUT, TimeUnit.SECONDS);
        b.readTimeout(MAX_TIMEOUT, TimeUnit.SECONDS);
        b.hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String s, SSLSession sslSession) {
                return true;
            }
        });
        client = b.build();

二:Get请求

import java.io.IOException;

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class Example{
    public class GetExample {

        OkHttpClient client = new OkHttpClient();

        String run(String url) throws IOException {
            Request request = new Request.Builder()
                    .url(url)
                    .build();

            try (Response response = client.newCall(request).execute()){
                return response.body().string();
            }
        }

    }

    public static void test() throws IOException {
        GetExample example = new GetExample();
        String response = example.run("https://raw.github.com/square/okhttp/master/README.md");
        System.out.println(response);
    }

}

OkHttp的Response实现了lang.AutoCloseable接口(Java7新特性try-with-resources)

  1. 发送一个请求的步骤,首先构造一个Request对象,参数最起码有个url,当然你可以通过Request.Builder设置更多的参数比如:header、method等。
  2. 通过request的对象去构造得到一个Call对象,类似于将你的请求封装成了任务,既然是任务,就会有execute()和cancel()等方法。
  3. 我们这里是阻塞的方式去执行,当然也支持异步的方式,你也可以直接调用call.enqueue()。将call加入调度队列,然后等待任务执行完成,我们在Callback中即可得到结果Response。

三:Post请求

public class PostExample {
//可以定义多种多媒体传输类型
        public static final MediaType JSON
                = MediaType.parse("application/json; charset=utf-8");

        String run(String url, String json) throws IOException {
            RequestBody body = RequestBody.create(JSON, json);
            //构造form表单数据请求方式
            //FormBody.Builder body = new //FormBody.Builder();
            //body.add(key, val);
            Request request = new Request.Builder()
                    .url(url)
                    .tag(tag);
                    .post(body)//.post(body.build())
                    .build();

            Response response = client.newCall(request).execute();

            //或者采用异步方式请求
            //请求加入调度
        client.newCall(request).enqueue(new Callback()
        {
            @Override
            public void onFailure(Request request, IOException e)
            {
            }

            @Override
            public void onResponse(final Response response) throws IOException
            {
                    //String htmlStr =  response.body().string();
            }
        });

            return response.body().string();
        }
    }
    public static void test() throws IOException {
        PostExample example = new PostExample();

        String json = "{}";
        String response = example.run("http://www.roundsapp.com/post", json);
        System.out.println(response);
    }

注意:

  • onResponse回调的参数是response,一般情况下,比如我们希望获得返回的字符串,可以通过response.body().string()获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()。
    看到这,你可能会奇怪,竟然还能拿到返回的inputStream,看到这个最起码能意识到一点,这里支持大文件下载,有inputStream我们就可以通过IO的方式写文件。不过也说明一个问题,这个onResponse执行的线程并不是UI线程。的确是的,如果你希望操作控件,还是需要使用handler等,我更喜欢用RxAndroid来封装请求和回调过程。或者可以结合Retrofit来封装网络请求更快捷。
@Override
public void onResponse(final Response response) throws IOException
{
      final String res = response.body().string();
      runOnUiThread(new Runnable()
      {
          @Override
          public void run()
          {
            mTv.setText(res);
          }

      });
}
Observable<Result> obs = Observable.create(new Observable.OnSubscribe<Result>()
        {
            @Override
            public void call(Subscriber<? super Result> subscriber)
            {
               try(Response response = http.syncExcute(url, p, tag))
                {

                    if (response == null)
                        return;
                    if (response.isSuccessful())
                    {
                        String str = response.body().string();
                        L.i("HTTP", "RESPONSE>" + str+"   url==="+url);
                        Result r = analyze(str, response.request().url().toString(), null);
                        subscriber.onNext(r);
                    } else
                        throw new Exception(" (" + response.code() + ")");
                } catch (Exception e)
                {
                    subscriber.onError(e);
                }
            }
        });
        obs = obs.subscribeOn(Schedulers.io());
        obs = obs.observeOn(AndroidSchedulers.mainThread());
        obs.subscribe(new Observer<Result>()
        {
            @Override
            public void onCompleted()
            {

            }

            @Override
            public void onError(Throwable e)
            {
                if (callback == null)
                    return;
                Result r = getErrorInfo(e, url.toString(), null);
                callback.onHttpResp(r);
            }

            @Override
            public void onNext(Result r)
            {
                if (callback == null)
                    return;
                callback.onHttpResp(r);
            }
        });

//登录服务
public interface LoginService {
        @FormUrlEncoded
        @POST("login_user")
        Call< LoginResult> doLogin(@Field("UserName") String userName, @Field("Password") String password);
    }
    /**
     * 用户登录
     *
     * @param userName
     * @param password
     * @param callback
     */
    public static void doLogin(String userName, String password, Callback<LoginResult> callback) {
        ServiceManager.LoginService service = getRetrofit().create(ServiceManager.LoginService.class);

        Call<LoginResult> result = service.doLogin(userName, CacheHelper.md5(password));
        result.enqueue(callback);
    }

public static synchronized Retrofit getRetrofit() {
        return new Retrofit.Builder().baseUrl(ConstantParams.BASE_URL).client(getClientInstance())
                .addConverterFactory(GsonConverterFactory.create()).build();
    }

四.基于Http的文件上传

File file = new File(Environment.getExternalStorageDirectory(), "a.mp4");

RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
    RequestBody requestBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addPart(Headers.of(
                            "Content-Disposition",
                            "form-data; name=\"username\""),
                    RequestBody.create(null, "william"))
            .addPart(Headers.of(
                    "Content-Disposition",
                    "form-data; name=\"mFile\";filename =\"wjd.mp4\""), fileBody)
            .build();


Request request = new Request.Builder().url("hostUrl/fileUpload")
            .post(requestBody)
            .build();

关于拼接上传文件的表单拼接模拟浏览器行为的方式。深度解析java http上传文件
图片下载,文件下载;这两个一个是通过回调的Response拿到byte[]然后decode成图片;文件下载,就是拿到inputStream做写文件操作,这里就不赘述了。
注意:对于添加了retrofit之后想打印请求和返回数据的日志可以参考(评论也很重要,我项目最后采取的方法就是评论中的开源工具LoggingInterceptor)。

参考文档:http://blog.csdn.net/lmj623565791/article/details/47911083
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html
http://blog.csdn.net/lmj623565791/article/details/51304204#comments

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值