Markdown版本笔记 | 个人GitHub首页 | 个人博客 | 个人微信 | 个人邮箱 |
---|---|---|---|---|
MyAndroidBlogs | baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
You'll also need Okio , which OkHttp uses for fast I/O and resizable调整 buffers。
Okio的API文档java
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.jarreact
Android下的网络框架:android
HttpClient在Android 6.0中已经被剔除掉了
,若是想要使用Volley还必须使用一个第三方的jai包。OkHttp是一个 Java 的 HTTP+SPDY
客户端开发包,同时也支持 Android,须要 Android 2.3 以上,同时还须要一个okio包。git
Retrofit
默认会使用OKHttp处理其网络层请求PS:
SPDY(读做“SPeeDY”)是Google开发的基于TCP的应用层协议,用以最小化网络延迟,提高网络速度,优化用户的网络使用体验。
SPDY并非一种用于替代HTTP的协议,而是对HTTP协议的加强。
新协议的功能包括数据流的多路复用、请求优先级以及HTTP报头压缩。
谷歌表示,引入SPDY协议后,在实验室测试中页面加载速度比原先快64%。github
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带宽.web
OkHttp is an HTTP client that's efficient by default:json
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.api
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.
Here’s some libraries that work nicely with OkHttp.
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。
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(); } } }
//【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(); }
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 = {"一、简单完整演示retrofit的使用", "二、添加Gson转换器", "三、添加okHttp的日志拦截器Interceptor", "四、使用本身封装的API,演示@Headers", "五、演示同步请求", "六、演示@Query", "七、演示@QueryMap", "八、最简单、完整的retrofit+rxJava示例", "九、rxJava+retrofit加强", "十、演示文件下载",}; 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; } } //一、简单示例 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(); } }); } //二、添加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(); } }); } //三、添加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(); } }); } //四、使用本身封装的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) { } }); } //五、演示同步请求 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和七、演示@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) { } }); } //八、最简单、完整的retrofit+rxJava示例 private void requestGitHubContributorsByRxJava() { createRetrofitService(GitHubApi.class) .contributorsByRxJava(mUserName, mRepo)// .subscribeOn(Schedulers.io())// .observeOn(AndroidSchedulers.mainThread())// .subscribe(...); } //九、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); } //十、演示文件下载 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