自定义View系列教程00–推翻自己和过往,重学自定义View
自定义View系列教程01–常用工具介绍
自定义View系列教程02–onMeasure源码详尽分析
自定义View系列教程03–onLayout源码详尽分析
自定义View系列教程04–Draw源码分析及其实践
自定义View系列教程05–示例分析
自定义View系列教程06–详解View的Touch事件处理
自定义View系列教程07–详解ViewGroup分发Touch事件
自定义View系列教程08–滑动冲突的产生及其处理
探索Android软键盘的疑难杂症
深入探讨Android异步精髓Handler
详解Android主流框架不可或缺的基石
站在源码的肩膀上全解Scroller工作机制
Android多分辨率适配框架(1)— 核心基础
Android多分辨率适配框架(2)— 原理剖析
Android多分辨率适配框架(3)— 使用指南
本文将用最简的代码和语句介绍OkHttp3的常用基本操作。
准备工作
导入OkHttp3
compile 'com.squareup.okhttp3:okhttp:3.8.1'
添加权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
请注意:假若你看到此处不明白为什么需要做这些准备工作,那么请点击浏览器右上角的八叉 ( X )
Post,Get,上传,下载
package com.cn.okhttp01;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* 原创作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class MainActivity extends AppCompatActivity {
public final static String TAG="reborn";
private static final int REQUEST_CODE = 9527;
private static String[] PERMISSIONS = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE };
private Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init(){
mContext=this;
verifyStoragePermissions(this);
}
private void testOkHttp(){
testUpload();
}
public void verifyStoragePermissions(Activity activity) {
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, PERMISSIONS, REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
testOkHttp();
} else {
Toast.makeText(mContext, "您未授权存储权限", Toast.LENGTH_LONG).show();
}
break;
default:
}
}
//Get同步请求
public void testGet1(){
new Thread(new Runnable() {
@Override
public void run() {
try{
String url="http://blog.csdn.net/lfdfhl";
OkHttpClient okHttpClient=new OkHttpClient();
Request.Builder requestBuilder=new Request.Builder();
requestBuilder.url(url);
Request request=requestBuilder.build();
Call call=okHttpClient.newCall(request);
Response response=call.execute();
String result=response.body().string();
response.body().close();
Log.i(TAG,"测试Get同步请求 "+result);
}catch (Exception e){
}
}
}).start();
}
//Get异步请求
public void testGet2(){
new Thread(new Runnable() {
@Override
public void run() {
try{
String url="http://blog.csdn.net/lfdfhl";
OkHttpClient okHttpClient=new OkHttpClient();
Request.Builder requestBuilder=new Request.Builder();
requestBuilder.url(url);
Request request=requestBuilder.build();
Call call=okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
int code=response.code();
String result=response.body().string();
response.body().close();
Log.i(TAG,"code="+code);
Log.i(TAG,"测试Get异步请求 "+result);
}
});
}catch (Exception e){
}
}
}).start();
}
//POST同步请求
public void testPost1(){
new Thread(new Runnable() {
@Override
public void run() {
try{
String url="http://106.14.136.52:8080/user/login";
OkHttpClient okHttpClient=new OkHttpClient();
Request.Builder requestBuilder=new Request.Builder();
FormBody.Builder formBodyBuilder=new FormBody.Builder();
formBodyBuilder.add("username","andy");
formBodyBuilder.add("password","123456");
RequestBody requestBody=formBodyBuilder.build();
requestBuilder.url(url);
requestBuilder.post(requestBody);
requestBuilder.addHeader("apikey","81bf9da930c7f9825a3c3383f1d8d766");
Request request=requestBuilder.build();
Response response=okHttpClient.newCall(request).execute();
int code=response.code();
String result=response.body().string();
response.body().close();
Log.i(TAG,"code="+code);
Log.i(TAG,"测试Post同步请求 "+result);
}catch (Exception e){
}
}
}).start();
}
//POST异步请求
public void testPost2(){
new Thread(new Runnable() {
@Override
public void run() {
try{
String url="http://106.14.136.52:8080/user/login";
OkHttpClient okHttpClient=new OkHttpClient();
Request.Builder requestBuilder=new Request.Builder();
FormBody.Builder formBodyBuilder=new FormBody.Builder();
formBodyBuilder.add("username","andy");
formBodyBuilder.add("password","123456");
RequestBody requestBody=formBodyBuilder.build();
requestBuilder.url(url);
requestBuilder.post(requestBody);
Request request=requestBuilder.build();
Call call=okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
int code=response.code();
String result=response.body().string();
response.body().close();
Log.i(TAG,"code="+code);
Log.i(TAG,"测试Post异步请求 "+result);
}
});
}catch (Exception e){
}
}
}).start();
}
//下载
public void testDownload(){
new Thread(new Runnable() {
@Override
public void run() {
try{
String url="http://img.blog.csdn.net/20161023140032428";
final File downloadFile=new File(getExternalCacheDir().toString()+File.separator+"test.jpg");
OkHttpClient okHttpClient=new OkHttpClient();
Request.Builder requestBuilder=new Request.Builder();
requestBuilder.url(url);
Request request=requestBuilder.build();
Call call=okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()){
InputStream inputStream=response.body().byteStream();
FileOutputStream fileOutputStream=new FileOutputStream(downloadFile);
int len=0;
byte b []=new byte[1024*2];
while ((len=inputStream.read(b))!=-1){
fileOutputStream.write(b,0,len);
}
fileOutputStream.close();
inputStream.close();
}
response.body().close();
Bitmap bitmap = BitmapFactory.decodeFile(downloadFile.getAbsolutePath());
Log.i(TAG,"width="+bitmap.getWidth());
Log.i(TAG,"height="+bitmap.getHeight());
}
});
}catch (Exception e){
}
}
}).start();
}
//上传
public void testUpload(){
new Thread(new Runnable() {
@Override
public void run() {
try{
String url ="http:192.168.0.103:8081/SpringMVC07/testUpload/uploadFile.do";
OkHttpClient okHttpClient=new OkHttpClient();
MultipartBody.Builder multipartBodyBuilder=new MultipartBody.Builder();
//添加文件
File file=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"test.jpg");
String fileName=file.getName();
MediaType mediaType=MediaType.parse("image/*");
RequestBody requestBody=RequestBody.create(mediaType,file);
multipartBodyBuilder.setType(MultipartBody.FORM);
multipartBodyBuilder.addFormDataPart("photo",fileName,requestBody);
//添加参数
multipartBodyBuilder.addFormDataPart("name","zxx");
multipartBodyBuilder.addFormDataPart("number","9527");
multipartBodyBuilder.addFormDataPart("country","China");
MultipartBody multipartBody=multipartBodyBuilder.build();
Request.Builder requestBuilder=new Request.Builder();
requestBuilder.url(url);
requestBuilder.post(multipartBody);
Request request=requestBuilder.build();
Call call=okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i(TAG,"onFailure");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i(TAG,"onResponse");
}
});
}catch (Exception e){
}
}
}).start();
}
}
请注意:测试时,请将url替换成您自己的可用地址
OkHttp拦截器
package com.cn.okhttp02;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
* 原创作者:谷哥的小弟
* 博客地址:http://blog.csdn.net/lfdfhl
*/
public class MainActivity extends AppCompatActivity {
public final static String TAG="reborn";
private Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
testApplicationInterceptors();
testNetworkInterceptors();
}
private void init(){
mContext=this;
}
//测试Application Interceptors
public void testApplicationInterceptors(){
new Thread(new Runnable() {
@Override
public void run() {
try{
Log.i(TAG,"----> run");
String url="http://blog.csdn.net/lfdfhl";
OkHttpClient.Builder okHttpClientBuilder= new OkHttpClient.Builder();
//添加应用拦截器
okHttpClientBuilder.addInterceptor(new LoggingInterceptor());
OkHttpClient okHttpClient=okHttpClientBuilder.build();
Request.Builder requestBuilder=new Request.Builder();
requestBuilder.url(url);
requestBuilder.addHeader("os","Android");
requestBuilder.addHeader("country","China");
Request request=requestBuilder.build();
Call call=okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i(TAG,"----> onFailure");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i(TAG,"----> onResponse");
int code=response.code();
String result=response.body().string();
response.body().close();
Log.i(TAG,"测试Application Interceptors "+result);
}
});
}catch (Exception e){
}
}
}).start();
}
//测试Network Interceptors
public void testNetworkInterceptors(){
new Thread(new Runnable() {
@Override
public void run() {
try{
Log.i(TAG,"----> run");
String url="http:www.github.com";
OkHttpClient.Builder okHttpClientBuilder= new OkHttpClient.Builder();
//添加网络拦截器
okHttpClientBuilder.addNetworkInterceptor(new LoggingInterceptor());
OkHttpClient okHttpClient=okHttpClientBuilder.build();
Request.Builder requestBuilder=new Request.Builder();
requestBuilder.url(url);
requestBuilder.addHeader("os","Android");
requestBuilder.addHeader("country","China");
Request request=requestBuilder.build();
Call call=okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i(TAG,"----> onFailure");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i(TAG,"----> onResponse");
int code=response.code();
String result=response.body().string();
response.body().close();
Log.i(TAG,"测试Network Interceptors "+result);
}
});
}catch (Exception e){
}
}
}).start();
}
class LoggingInterceptor implements Interceptor {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Log.i(TAG,"----> intercept");
Request request = chain.request();
long t1 = System.nanoTime();
Log.i(TAG, "intercept: " + String.format("Sending request %s on %s%n%s",request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
Log.i(TAG, "intercept: " + String.format("Received response for %s in %.1fms%n%s",response.request().url(), (t2 - t1) / 1e6d, response.headers()));
return response;
}
}
}
什么是拦截器呢?
拦截器能对Call进行监测、改写、重试连接;它能够对请求和响应进行二次加工。通俗地说:拦截器是请求和回复之间的一道门——发出请求时数据需要从这道门出去;接收响应时数据需要从这道门进来。当然,当数据(不论进出)经过这道门时,该门可对数据进行某些操作。
OkHttp3常用的拦截器分为:
- Application Interceptors 应用拦截器
- Network Interceptors 网络拦截器
这两个拦截器有什么区别呢?
Application interceptors 应用拦截器
Don’t need to worry about intermediate responses like redirects and retries.
不关心中间过程的响应,如重定向和重试Are always invoked once, even if the HTTP response is served from the cache.
总是只调用一次,即使HTTP响应是从缓存中获取Observe the application’s original intent. Unconcerned with OkHttp-injected headers like If-None-Match.
关注应用程序的初衷. 不关心OkHttp注入的头信息如: If-None-Match.Permitted to short-circuit and not call Chain.proceed().
允许短路且不调用Chain.proceed()Permitted to retry and make multiple calls to Chain.proceed().
允许重试,多次调用 Chain.proceed()
Network Interceptors 网络拦截器
Able to operate on intermediate responses like redirects and retries.
能够操作中间过程的响应,如重定向和重试.Not invoked for cached responses that short-circuit the network.
当网络短路返回缓存响应时不被调用Observe the data just as it will be transmitted over the network.
只观察在网络上传输的数据.Access to the Connection that carries the request.
携带请求访问连接
拦截器使用场景
- 为request统一添加header
- 检查response判定用户登录信息是否失效,并用Dialog提示用户登录
- 重写响应头和改变响应体。但不是很推荐这么做,因为可能违反web服务器的期望。