Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

目录

OkHttp

okhttp

官网

文档

API

You'll also need Okio , which OkHttp uses for fast I/O and resizable调整 buffers。

Okio的API文档

compile 'com.squareup.okhttp3:okhttp:3.8.0'
compile 'com.squareup.okio:okio:1.13.0'

okhttp-3.9.0.jar

okio-1.13.0.jar

简介

Android下的网络框架:

  • 官方集成的网络框架包含:HttpUrlConnection、HttpClient、Volley。
  • Volley是android开发团队在2013年Google I/O大会上推出了一个新的网络通信框架。目前Volley中部分代码仍然借助于HttpClient中部分功能,然而HttpClient在Android 6.0中已经被剔除掉了,如果想要使用Volley还必须使用一个第三方的jai包。
  • Volley是针对数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。
  • 如果使用HttpUrlConnection则要从头开始封装对应的操作。

OkHttp是一个 Java 的 HTTP+SPDY 客户端开发包,同时也支持 Android,需要 Android 2.3 以上,同时还需要一个okio包。

  • OKHttp是Android(Java)版Http客户端,非常高效,支持SPDY、连接池、GZIP和 HTTP 缓存
  • 默认情况下,OKHttp会自动处理常见的网络问题,像二次连接、SSL的握手问题
  • 如果你的应用程序中集成了OKHttp,Retrofit默认会使用OKHttp处理其网络层请求
  • 从Android4.4开始,HttpURLConnection的底层实现采用的是okHttp

PS:

SPDY(读作“SPeeDY”)是Google开发的基于TCP的应用层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。

SPDY并不是一种用于替代HTTP的协议,而是对HTTP协议的增强。

新协议的功能包括数据流的多路复用、请求优先级以及HTTP报头压缩。

谷歌表示,引入SPDY协议后,在实验室测试中页面加载速度比原先快64%。

官方 Overview

HTTP is the way modern applications network. It's how we exchange data & media. Doing HTTP efficiently makes your stuff材料、塞满 load faster and saves bandwidth带宽.

OkHttp is an HTTP client that's efficient by default:

  • HTTP/2 support allows all requests to the same host to share a socket.
  • Connection pooling连接池 reduces使变弱 request latency延迟 (if HTTP/2 isn't available).
  • Transparent GZIP透明的GZIP压缩 shrinks减少 download sizes.
  • Response caching avoids the network completely for repeat重复 requests.

OkHttp perseveres坚忍 when the network is troublesome: it will silently沉默的 recover from common connection problems. If your service has multiple IP addresses, OkHttp will attempt alternate轮流、交替 addresses if the first connect fails. This is necessary for IPv4+IPv6 and for services hosted in redundant冗余的、多余的 data centers. OkHttp initiates开始 new connections with modern TLS features (SNI, ALPN), and falls back to TLS 1.0 if the handshake fails.

Using OkHttp is easy. Its request/response API is designed with fluent流畅的 builders and immutability不变的. It supports both synchronous blocking calls and async calls with callbacks.

OkHttp supports Android 2.3 and above. For Java, the minimum requirement is 1.7.

Works with OkHttp

Here’s some libraries that work nicely with OkHttp.

  • Glide: An image loading and caching library for Android focused on smooth scrolling. 专注于平滑滚动的Android图像加载和缓存库。
  • Okio: A modern I/O API for Java. Java的现代I/O API。
  • Retrofit: Type-safe HTTP client for Android and Java by Square. Square公司出的适用于Android和Java的类型安全的HTTP客户端。
  • Chuck: An in-app HTTP inspector for Android OkHttp clients. 适用于Android OkHttp客户端的应用内HTTP检查器。
  • Communicator: An OkHttp wrapper for Scala built with Android in mind. 安装了Android的Scala的OkHttp包装器。
  • CWAC-NetSecurity: Simplifying Secure Internet Access. 简化安全Internet访问。
  • Fresco: An Android library for managing images and the memory they use. 用于管理图像和他们使用的内存的Android库。
  • GoogleAppEngineOkHttp: An OkHttp Call that works on Google App Engine. 适用于Google App Engine的OkHttp调用。
  • ModernHttpClient: Xamarin HTTP API that uses native implementations. 使用本地实现的Xamarin HTTP API。
  • Moshi: A modern JSON library for Android and Java. Android和Java的现代JSON库。
  • Ok2Curl: Convert OkHttp requests into curl logs. 将OkHttp请求转换为curl日志。
  • okhttp-digest: A digest authenticator for OkHttp. OkHttp的摘要验证器。
  • OkHttp Idling Resource: An Espresso IdlingResource for OkHttp. OkHttp的浓咖啡空转资源。
  • okhttp-signpost: OAuth signing with signpost and OkHttp. OAuth签署路标和OkHttp。
  • okhttp-stats: Get stats like average network speed. 获取平均网络速度的统计信息。
  • OkHttp-Xamarin: Xamarin bindings for OkHttp. 用于OkHttp的Xamarin绑定。
  • OkLog: Response logging interceptor for OkHttp. Logs a URL link with URL-encoded response for every OkHttp call. OkHttp的响应记录拦截器。记录每个OkHttp调用的URL编码响应的URL链接。
  • OkSocial A curl-like client for social networks and other APIs. 社交网络和其他API的curl-like客户端。
  • PersistentCookieJar: A persistent CookieJar. 一个持久的CookieJar。
  • Picasso: A powerful image downloading and caching library for Android. 一个功能强大的Android图像下载和缓存库。
  • Smash: A Volley-inspired networking library. 一个受Volley启发的网络库。
  • Stetho: Stetho is a debug bridge for Android applications. Stetho是Android应用程序的调试桥。
  • Thrifty: An implementation of Apache Thrift for Android. 在Android上Apache Thrift的一个实现。
  • Volley-OkHttp-Android: A fork of Volley with changes to work with OkHttp. 使用OkHttp进行更改的fork自Volley的一个库。

  • Wire: Clean, lightweight protocol buffers for Android and Java. 适用于Android和Java的清洁、轻便的protocol buffers。

示例代码

get和post示例

public class MainActivity extends ListActivity {
private User mUser;
private String mBaseUrl = "http://api.95xiu.com/";
private OkHttpClient client; private TextView mTv; protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] array = {"post方式提交键值对数据", "get方式提交键值对数据",};
mTv = new TextView(this);
getListView().addFooterView(mTv);
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, array)); client=new OkHttpClient.Builder().build();
} @Override
protected void onListItemClick(ListView l, View v, int position, long id) {
switch (position) {
case 0:
postWithParams(); //post方式提交键值对数据
break;
case 1:
getWithParams(); //get方式提交键值对数据
break;
}
} private void postWithParams() {
String url = mBaseUrl + "user/loginv2.php";
FormBody formBody = new FormBody.Builder()
.add("user", "103468")
.add("pass", "103468")
.build();
Request request = new Request.Builder().url(url).post(formBody).build();
client.newCall(request)
.enqueue(new okhttp3.Callback() {
@Override
public void onFailure(Call call, IOException e) {
} @Override
public void onResponse(Call call, Response response) throws IOException {
final String responseString = response.body().string();//响应的内容
Log.i("bqt", "【body】" + decodeUnicodeToString(responseString));//{"result":0,"msg":"用户不存在"} mUser = new Gson().fromJson(responseString, User.class);//类型转换
runOnUiThread(() -> mTv.setText(decodeUnicodeToString(responseString)));//线程切换
}
});
} private void getWithParams() {
String url = mBaseUrl + "app/news/index.php"
+ "?session_id=" + mUser.getMsg().getSession_id()
+ "&uid=" + mUser.getMsg().getId();
Request request = new Request.Builder().url(url).get().build();
client.newCall(request)
.enqueue(new okhttp3.Callback() {
@Override
public void onFailure(Call call, IOException e) {
} @Override
public void onResponse(Call call, Response response) throws IOException {
final String responseString = response.body().string();
runOnUiThread(() -> mTv.setText(decodeUnicodeToString(responseString)));
}
});
} //将Unicode编码解析成字符串形式(如汉字)
public static String decodeUnicodeToString(String uString) {
StringBuilder sb = new StringBuilder();
int i = -1, pos = 0;
while ((i = uString.indexOf("\\u", pos)) != -1) {
sb.append(uString.substring(pos, i));
if (i + 5 < uString.length()) {
pos = i + 6;
sb.append((char) Integer.parseInt(uString.substring(i + 2, i + 6), 16));
}
}
sb.append(uString.substring(pos));
return sb.toString();
}
}

拦截器和证书示例

public class OkHttp_Activity extends ListActivity {

    protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] array = {"应用程序拦截器",
"网络拦截器",
"Rewriting Requests,重写请求",
"Rewriting Responses,重写响应",};
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, array));
} @Override
protected void onListItemClick(ListView l, View v, int position, long id) {
new Thread(() -> {//里面用的都是同步请求,所以必须在一个子线程中调用
try {//线程里面的异常不能在线程外面捕获或throws
switch (position) {
case 0:
loggingInterceptor(true, new LoggingInterceptor());//应用程序拦截器
break;
case 1:
loggingInterceptor(false, new LoggingInterceptor());//网络拦截器
break;
case 2:
loggingInterceptor(new Random().nextBoolean(), new GzipRequestInterceptor());//重写请求
break;
case 3:
loggingInterceptor(new Random().nextBoolean(), new ReWriteCacheControlInterceptor());//重写响应
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
} private void loggingInterceptor(boolean isApplicationInterceptor, Interceptor interceptor) throws IOException {
OkHttpClient client;
if (isApplicationInterceptor) client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
else client = new OkHttpClient.Builder().addNetworkInterceptor(interceptor).build(); Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.header("User-Agent", "OkHttp Example")
.build(); Response response = client.newCall(request).execute(); //同步执行
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); System.out.println("【响应url】" + response.request().url());
response.body().close();
} //使用一个自定义的TLS版本和密码组来构建你自己的连接规范
private void connectionSpecs() {
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
.build(); OkHttpClient client = new OkHttpClient.Builder()
.connectionSpecs(Collections.singletonList(spec))
.build();
} //Certificate Pinning,证书锁定
public void certificatePinner() throws Exception {
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("publicobject.com", "sha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=")
.build(); OkHttpClient client = new OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build(); Request request = new Request.Builder()
.url("https://publicobject.com/robots.txt")
.build(); Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); for (java.security.cert.Certificate certificate : response.handshake().peerCertificates()) {
System.out.println("【】" + CertificatePinner.pin(certificate));
}
} //拦截器
class LoggingInterceptor implements Interceptor {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();//发出的请求
long t1 = System.nanoTime();
System.out.println("【请求】" + String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers())); Response response = chain.proceed(request);//生成与请求对应的响应。这里是所有HTTP工作发生的地方
long t2 = System.nanoTime();
System.out.println("【响应】" + String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers())); return response;
}
} //This interceptor compresses the HTTP request body. Many webservers can't handle this!
class GzipRequestInterceptor implements Interceptor {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request originalRequest = chain.request();
if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
return chain.proceed(originalRequest);//生成与请求对应的响应
} RequestBody compressedRequestBody = new RequestBody() {
@Override
public MediaType contentType() {
return originalRequest.body().contentType();
} @Override
public long contentLength() {
return -1; // We don't know the compressed length in advance(提前)!
} @Override
public void writeTo(BufferedSink sink) throws IOException {
BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
originalRequest.body().writeTo(gzipSink);
gzipSink.close();
}
}; Request compressedRequest = originalRequest.newBuilder()
.header("Content-Encoding", "gzip")//添加、删除或者替换请求头
.method(originalRequest.method(), compressedRequestBody)//改变请求体
.build();
return chain.proceed(compressedRequest);//重新生成与请求对应的响应
}
} //Dangerous interceptor that rewrites the server's cache-control header.
class ReWriteCacheControlInterceptor implements Interceptor {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.header("Cache-Control", "max-age=60")//重写响应头
.build();
}
}
}

retrofit okhttp RxJava 综合示例

依赖

//【retrofit2】
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0' //【okhttp】
compile 'com.squareup.okhttp3:okhttp:3.8.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.8.0'
compile 'com.squareup.okio:okio:1.13.0' //【butterknife】
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' //【rxjava】
compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.6'

网络请求接口定义

public interface GitHubApi {

    @GET("repos/{owner}/{repo}/contributors")
Call<ResponseBody> contributorsBySimpleGetCall(@Path("owner") String owner, @Path("repo") String repo); @GET("repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributorsByAddConverterGetCall(@Path("owner") String owner, @Path("repo") String repo); @Headers({"Accept: application/vnd.github.v3.full+json", "User-Agent: RetrofitBean-Sample-App", "name:ljd"})
@GET("repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributorsAndAddHeader(@Path("owner") String owner, @Path("repo") String repo); @GET("search/repositories")
Call<RetrofitBean> queryRetrofitByGetCall(@Query("q") String owner, @Query("since") String time, @Query("page") int page, @Query("per_page") int per_Page); @GET("search/repositories")
Call<RetrofitBean> queryRetrofitByGetCallMap(@QueryMap Map<String, String> map); @GET("repos/{owner}/{repo}/contributors")
Observable<List<Contributor>> contributorsByRxJava(@Path("owner") String owner, @Path("repo") String repo); @GET("users/{user}")
Observable<User> userByRxJava(@Path("user") String user); @GET("/mobilesafe/shouji360/360safesis/360MobileSafe_6.2.3.1060.apk")
Call<ResponseBody> retrofitDownload();
}

Activity

public class MainActivity extends ListActivity {
private TextView tv;
private static final String baseUrl = "https://api.github.com/";
private static final String mUserName = "square";//哪个公司【square】
private static final String mRepo = "retrofit";//哪个项目【retrofit】
private CompositeSubscription mSubscriptions = new CompositeSubscription(); protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] array = {"1、简单完整演示retrofit的使用",
"2、添加Gson转换器",
"3、添加okHttp的日志拦截器Interceptor",
"4、使用自己封装的API,演示@Headers",
"5、演示同步请求",
"6、演示@Query",
"7、演示@QueryMap",
"8、最简单、完整的retrofit+rxJava示例",
"9、rxJava+retrofit增强",
"10、演示文件下载",};
tv = new TextView(this);
tv.setTextColor(Color.BLUE);
getListView().addFooterView(tv);
setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, array));
} @Override
protected void onDestroy() {
if (mSubscriptions != null) mSubscriptions.unsubscribe();
super.onDestroy();
} @Override
protected void onListItemClick(ListView l, View v, int position, long id) {
switch (position + 1) {
case 1://简单完整演示retrofit的使用
requestGitHubContributorsSimple();
break;
case 2://添加Gson转换器
requestGitHubContributorsByConverter();
break;
case 3://添加okHttp的日志拦截器Interceptor
requestGitHubContributorsAddOkHttpLog();
break;
case 4://使用自己封装的API,演示@Headers
requestGitHubContributorsAddHeader();
break;
case 5://演示同步请求
requestGitHubContributorsBySync();
break;
case 6://演示@Query
requestQueryRetrofitByGet(false);
break;
case 7://演示@QueryMap
requestQueryRetrofitByGet(true);
break;
case 8://最简单、完整的retrofit+rxJava示例
requestGitHubContributorsByRxJava();
break;
case 9://rxJava+retrofit增强
requestGitHubContributorsWithFullUserInfo();
break;
case 10://演示文件下载
retrofitDownload();
break;
}
} //1、简单示例
private void requestGitHubContributorsSimple() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.build();
GitHubApi repo = retrofit.create(GitHubApi.class);
Call<ResponseBody> call = repo.contributorsBySimpleGetCall(mUserName, mRepo);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> response) {
String result = null;
try {
result = response.body().string();
if (result == null) return;
} catch (IOException e) {
e.printStackTrace();
}
tv.setText("GitHub上对项目的贡献-1:\n");
ArrayList<Contributor> list = new Gson().fromJson(result, new TypeToken<List<Contributor>>() {
}.getType());
if (list == null || list.size() == 0) return;
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "\n");
}
} @Override
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} //2、添加Gson转换器
private void requestGitHubContributorsByConverter() {
new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())//转换器
.build()
.create(GitHubApi.class)
.contributorsByAddConverterGetCall(mUserName, mRepo)
.enqueue(new Callback<List<Contributor>>() {
@Override
public void onResponse(@NonNull Call<List<Contributor>> call, @NonNull Response<List<Contributor>> response) {
List<Contributor> list = response.body();
tv.setText("GitHub上对项目的贡献-2:\n");
if (list == null || list.size() == 0) return;
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "\n");
}
} @Override
public void onFailure(@NonNull Call<List<Contributor>> call, @NonNull Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} //3、添加okHttp的日志拦截器Interceptor
private void requestGitHubContributorsAddOkHttpLog() {
HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY); Retrofit retrofit = new Retrofit.Builder()
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(new OkHttpClient.Builder().addInterceptor(logInterceptor).build())
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build(); retrofit.create(GitHubApi.class)
.contributorsByAddConverterGetCall(mUserName, mRepo)
.enqueue(new Callback<List<Contributor>>() {
@Override
public void onResponse(@NonNull Call<List<Contributor>> call, @NonNull Response<List<com.bqt
.retrofit.bean.Contributor>> response) {
List<Contributor> list = response.body();
tv.setText("GitHub上对项目的贡献-3:\n");
if (list == null || list.size() == 0) return;
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "\n");
}
} @Override
public void onFailure(@NonNull Call<List<Contributor>> call, @NonNull Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} //4、使用自己封装的API,演示@Headers
private void requestGitHubContributorsAddHeader() {
createRetrofitService(GitHubApi.class)
.contributorsAndAddHeader(mUserName, mRepo)
.enqueue(new Callback<List<Contributor>>() {
@Override
public void onResponse(@NonNull Call<List<Contributor>> call, @NonNull Response<List<com.bqt
.retrofit.bean.Contributor>> response) {
List<Contributor> list = response.body();
tv.setText("GitHub上对项目的贡献-4:\n");
if (list == null || list.size() == 0) return;
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "\n");
}
} @Override
public void onFailure(@NonNull Call<List<Contributor>> call, @NonNull Throwable t) {
}
});
} //5、演示同步请求
private void requestGitHubContributorsBySync() {
final Call<List<Contributor>> call = createRetrofitService(GitHubApi.class)
.contributorsByAddConverterGetCall(mUserName, mRepo);
new Thread(() -> {
try {
Response<List<Contributor>> response = call.execute();//在子线程中请求网络
final List<Contributor> list = response.body();
runOnUiThread(() -> {
tv.setText("GitHub上对项目的贡献-5:\n");
for (Contributor contributor : list) {
tv.append(contributor.login + " " + contributor.contributions + "\n");
}
});
} catch (IOException e) {
e.printStackTrace();
}
}).start();
} //6和7、演示@Query和@QueryMap
private void requestQueryRetrofitByGet(boolean isQueryMap) {
GitHubApi mGitHubService = createRetrofitService(GitHubApi.class);
Call<RetrofitBean> call;
if (!isQueryMap) call = mGitHubService.queryRetrofitByGetCall("retrofit", "2016-03-29", 1, 3);
else {
Map<String, String> queryMap = new HashMap<>();
queryMap.put("q", "retrofit");
queryMap.put("since", "2016-03-29");
queryMap.put("page", "1");
queryMap.put("per_page", "3");
call = mGitHubService.queryRetrofitByGetCallMap(queryMap);
} call.enqueue(new Callback<RetrofitBean>() {
@Override
public void onResponse(@NonNull Call<RetrofitBean> call, @NonNull Response<RetrofitBean> response) {
RetrofitBean retrofitBean = response.body();
if (retrofitBean == null) return;
List<Item> list = retrofitBean.getItems();
if (list == null || list.size() == 0) return; tv.setText(new SimpleDateFormat("yyyy.MM.dd HH:mm:ss SSS", Locale.getDefault()).format(new Date()));
tv.append("\ntotal:" + retrofitBean.getTotalCount() + "\nincompleteResults:" + retrofitBean.getIncompleteResults());
for (Item item : list) {
tv.append("\n\n【name】" + item.name);
tv.append("\n【full_name】" + item.full_name);
tv.append("\n【 description】" + item.description);
}
} @Override
public void onFailure(@NonNull Call<RetrofitBean> call, @NonNull Throwable t) {
}
});
} //8、最简单、完整的retrofit+rxJava示例
private void requestGitHubContributorsByRxJava() {
createRetrofitService(GitHubApi.class)
.contributorsByRxJava(mUserName, mRepo)//
.subscribeOn(Schedulers.io())//
.observeOn(AndroidSchedulers.mainThread())//
.subscribe(...);
} //9、rxJava+retrofit增强
private void requestGitHubContributorsWithFullUserInfo() {
Subscription subscription = createRetrofitService(GitHubApi.class)
.contributorsByRxJava(mUserName, mRepo)//
.flatMap(...)
.flatMap(...)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(...;
mSubscriptions.add(subscription);
} //10、演示文件下载
public void retrofitDownload() {
//监听下载进度
final ProgressDialog dialog = new ProgressDialog(this);
dialog.setProgressNumberFormat("%1d KB/%2d KB");
dialog.setTitle("下载");
dialog.setMessage("正在下载,请稍后...");
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setCancelable(false);
dialog.show(); ProgressHelper.setProgressHandler(new DownloadProgressHandler() {
@Override
protected void onProgress(long bytesRead, long contentLength, boolean done) {
//在主线程中运行
dialog.setMax((int) (contentLength / 1024));
dialog.setProgress((int) (bytesRead / 1024));
if (done) dialog.dismiss();
}
}); Retrofit retrofit = new Retrofit.Builder()//
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//
.addConverterFactory(GsonConverterFactory.create())//
.baseUrl("http://msoftdl.360.cn")
.client(ProgressHelper.addProgress(null).build())
.build(); retrofit.create(GitHubApi.class).retrofitDownload()
.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> response) {
try {
InputStream is = response.body().byteStream();
File file = new File(Environment.getExternalStorageDirectory(), "12345.apk");
FileOutputStream fos = new FileOutputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[1024];
int len;
while ((len = bis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
fos.flush();
}
fos.close();
bis.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
} @Override
public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
}
});
} public static <T> T createRetrofitService(final Class<T> service) {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder builder = new OkHttpClient.Builder().addInterceptor(httpLoggingInterceptor);
Retrofit retrofit = new Retrofit.Builder()//
.client(ProgressHelper.addProgress(builder).build())//
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//
.addConverterFactory(GsonConverterFactory.create())//
.baseUrl("https://api.github.com/")//
.build();
return retrofit.create(service);
}
}

综合配置

请求参数封装:

public interface BqtService {
@GET("User")
Observable<BqtRes<User>> getUser(); @FormUrlEncoded
@POST("BuyInfo/buyRecord")
Observable<BqtRes<ArrayList<MyClassBean>>> getHistory(@Field("user_id") int uid, @Field("page") int page);
}

调用示例:

H.h().getUser()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(response -> L.i("onNext " + response.data.toString());//这里response.data的类型即是User

retrofit、okhttp、RxJava、Gson、拦截器、Header等配置

public class H {
private static Interceptor buildInterceptor() {
final String token = AccountManager.getInstance().getToken();
PackageInfo packInfo = null;
try {
packInfo = App.app.getPackageManager().getPackageInfo(App.app.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
final int version = packInfo == null ? 1 : packInfo.versionCode;
return new Interceptor() {//应用程序拦截器,只被调用一次
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request()
.newBuilder()
.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
.addHeader("Accept-Encoding", "gzip, deflate")
.addHeader("Connection", "keep-alive")
.addHeader("Accept", "*/*")
//****************************************自定义Header
.addHeader("version", version + "")//app版本号
.addHeader("token", token == null ? "" : token)//登录后返回的token
.addHeader("mobile", "1")// 0-PC,1-Android,2-IOS,3-web
.build();
return chain.proceed(request);
}
};
} private static Interceptor buildLogInterceptor() {
return new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
L.d(message);//这里会打印出大量的日志出来,所以不要和手动打印的日志混在一起
}
}).setLevel(HttpLoggingInterceptor.Level.BODY);//日志显示级别
} private static OkHttpClient buildOkHttp() {
return new OkHttpClient.Builder()
.addInterceptor(buildHeaderInterceptor())//自定义Header
.addInterceptor(buildLogInterceptor())//日志拦截
.connectTimeout(5, TimeUnit.SECONDS)
.build();
} private static Gson buildGson() {
return new GsonBuilder()//配置你的Gson
.setDateFormat("yyyy-MM-dd hh:mm:ss")
.setPrettyPrinting()
.serializeNulls()
.create();
} private static String buildBaseUrl() {
switch (UrlHelper.getEnv()) {
case 0: // baseUlr 必须以 / 结束,不然会抛出一个IllegalArgumentException
return "http://test.talk.99cj.com.cn/";
case 1:
return "http://wechat.99cj.com.cn/";
default:
return "http://wechat.99cj.com.cn/";
}
} private static Retrofit buildRetrofit(OkHttpClient client, Converter.Factory converterFactory, CallAdapter.Factory callAdapterFactory) {
return new Retrofit.Builder()
.baseUrl(buildBaseUrl())
.client(client)
.addConverterFactory(converterFactory)//可以接收自定义的Gson,当然也可以不传
.addCallAdapterFactory(callAdapterFactory)
.build();
} private static <T> T createRetrofitService(final Class<T> service) {
Retrofit retrofit = buildRetrofit(buildOkHttp(), //
GsonConverterFactory.create(buildGson()),//
RxJavaCallAdapterFactory.create());//
return retrofit.create(service);
} public static BqtService h() {
return createRetrofitService(BqtService.class);
}
}

添加上述【HttpLoggingInterceptor】拦截器后会打印如下日志

2017-06-20

Okhttp【简介】应用 示例的更多相关文章

  1. Android查缺补漏(IPC篇)-- 进程间通讯之Socket简介及示例

    本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8425736.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ...

  2. IdentityServer4 中文文档 -6- (简介)示例服务器和测试

    IdentityServer4 中文文档 -6- (简介)示例服务器和测试 原文:http://docs.identityserver.io/en/release/intro/test.html 目 ...

  3. Ruby简介,附带示例程序

    Ruby语言是日本人松本行弘于1993年器开始着手研发,经历2年时间,发布了Ruby语言的第一个版本:0.95版.     Ruby是一种非常简介的解释性语言,一种纯粹的面向对象编程语言,甚至比Jav ...

  4. IText简介及示例

    一.iText简介 iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库.通过iText不仅可以生成PDF或rtf的文档,而且可以将XML.Html文 ...

  5. Unity 3(一):简介与示例

    本文关注以下方面(环境为VS2012..Net Framework 4.5以及Unity 3): Ioc/DI简介: Unity简单示例 一.Ioc/DI简介 IoC 即 Inversion of C ...

  6. OkHttp简介

    什么是OKHttp 一般在Java平台上,我们会使用Apache HttpClient作为Http客户端,用于发送 HTTP 请求,并对响应进行处理.比如可以使用http客户端与第三方服务(如SSO服 ...

  7. JavaScript简介及示例

    JavaScript简介及使用 一.简介 JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛 ...

  8. Lambda表达式 简介 语法 示例

    Lambda 表达式也称为闭包,是匿名类的简短形式.Lambda 表达式简化了[单一抽象方法声明接口]的使用,因此 lambda 表达式也称为功能接口. 在 Java SE 7 中,单一方法接口可使用 ...

  9. Spring IO Platform简介及示例

    什么是Spring IO Platform Spring IO Platform,简单的可以认为是一个依赖维护平台,该平台将相关依赖汇聚到一起,针对每个依赖,都提供了一个版本号: 这些版本对应的依赖都 ...

  10. Lambda表达式 简介 语法 示例 匿名内部类

    在AS中使用 Lambda 表达式 Demo地址:https://github.com/baiqiantao/MultiTypeTest.git Gradle(Project级别)中添加classpa ...

随机推荐

  1. Java时间间隔问题在Android中的使用

    转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6606720.html 假设我们在做项目的时候,获取到了一段音频,也知道音频长度,那么我们想对音频做一些处理 ...

  2. web服务端安全之文件上传漏洞

    一.文件上传漏洞的原理 由于程序代码未对用户提交的文件进行严格的分析和检查,导致攻击者可以上传可执行的代码文件,从而获取web应用的控制权限. 常见于上传功能,富文本编辑器. 二.文件上传漏洞的防御 ...

  3. 深入理解ajax系列第八篇

    前面的话 在以前,网站的用户与后端交互的主要方式是通过HTML表单的使用.表单的引入在1993年,由于其简单性和易用性,直到电子商务出现之前一直保持着重要位置.理解表单提交,对于更深入地理解ajax是 ...

  4. 家谱(gen)

    家谱(gen) 时间限制  2S [问题描述]     现代的人对于本家族血统越来越感兴趣,现在给出充足的父子关系,请你编写程序找到某个人的最早的祖先. [输入格式]gen.in 输入文件由多行组成, ...

  5. luoguP3235 [HNOI2014]江南乐 数论分块 + 博弈论

    感觉其实很水? 题目就是一个Multi SG游戏,只需要预处理出所有的\(sg\)值即可\(O(Tn)\)计算 对于计算\(sg[n]\)而言,显然我们可以枚举划分了\(x\)堆来查看后继状态 那么, ...

  6. zoj 3469 区间dp **

    题意:有一家快餐店送外卖,现在同时有n个家庭打进电话订购,送货员得以V-1的速度一家一家的运送,但是每一个家庭都有一个不开心的值,每分钟都会增加一倍,值达到一定程度,该家庭将不会再订购外卖了,现在为了 ...

  7. Codeforces Round #257 (Div. 2) A. Jzzhu and Children

    A. Jzzhu and Children time limit per test 1 second memory limit per test 256 megabytes input standar ...

  8. CodeForces 128D Numbers 构造

    D. Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...

  9. C#高级编程9-目录

    C#高级编程 ===================================================== .NET体系结构 核心C# 对象与类型 继承 泛型 数组 运算符和类型强制转换 ...

  10. Python学习笔记(五)—列表的学习

    总结内容: 1.list的定义 2.list的取值 3.list数据的增加 4.list数据的删除 5.list数据的修改 6.list数据的查询 7.list方法的介绍 8.list的合并 9.多维 ...