在Android中从来不缺少网络请求的框架或者说是工具,从最早的xUtIls工具,到Volley,再到okHttp,(好比从最早的底层基于
httpclient
到现在底层使用的HttpUrlConnection
-早期的错误认知
),时代在改变,很多东西也更趋近与完美,既然okHttp使用已经有一段时间了,那么我们本篇为大家带来的就是okHttp的熟练使用 ~
关联篇
此篇主要使用OkHttp实践了俩个Demo,并未针对OkHttp本身做出详细解释,不过可以通过代码进行简单学习 ~
基础配置
第一篇写于 - 2017-02-12
首先如果我们使用Ecplice或者AndroidStudio的话是需要添加不同的配置,对应工具的依赖配置方式如下:
- Ecplise中在lib内部添加以下俩个jar包:
- AndroidStudio添加依赖:
compile 'com.squareup.okhttp:okhttp:2.4.0'
compile 'com.squareup.okio:okio:1.5.0'
添加权限
<uses-permission android:name="android.permission.INTERNET"/>
MIME 类型 - MIME 参考手册
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准
MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据
常用类型
- json : application/json
- xml : application/xml
- png : image/png
- jpg : image/jpeg
- gif : imge/gif
MediaType
MediaType:指的是要传递的数据的MIME类型,构造参数如下
private MediaType(String mediaType, String type, String subtype, String charset) {
this.mediaType = mediaType;
this.type = type;
this.subtype = subtype;
this.charset = charset;
}
MediaType对象包含了三种信息:type 、subtype以及charset,一般将这些信息传入parse()方法中,这样就可以解析出MediaType对象;
示例解析: "text/x-markdown; charset=utf-8"
- type值是text,表示是文本这一大类
- /后面的x-markdown是subtype,表示是文本这一大类下的markdown这一小类
- charset=utf-8 则表示采用UTF-8编码
入门实践
使用步骤
- 基础配置完成后,创建
okHttp
的实例 - 创建请求,在
Request.Builder()
中添加请求信息,内部包含url,请求方式等,当然最后记得.build()提交 - 以
异步发起请求
,使用call.enqueue
,加入调度获取回调
效果
- 实现前
- 实现后
实现过程
MainActivity
package com.example.okhttpdemo;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.app.Activity;
public class MainActivity extends Activity implements OnClickListener {
private TextView mGet;
private TextView mPost;
private TextView mContent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
mGet = (TextView) findViewById(R.id.okhttp_get);
mPost = (TextView) findViewById(R.id.okhttp_post);
mContent = (TextView) findViewById(R.id.tv_content);
mGet.setOnClickListener(this);
mPost.setOnClickListener(this);
mContent.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.okhttp_get:
// GET请求,获取Json数据
doGet();
break;
case R.id.okhttp_post:
// Post请求,提交给服务器数据
doPost();
break;
default:
break;
}
}
private void doGet() {
new Thread(new Runnable() {
@Override
public void run() {
// 1.创建实例对象
OkHttpClient getOkHttp = new OkHttpClient();
// 2-1.创建请求信息-先创建请求的容器.在填充请求的数据,并提交
Request request = new Request.Builder()
.url("http://apis.juhe.cn/catering/query?key=key&lng=121.538123&lat=31.677132&radius=2000")
.build();
// 3.使用okhttp的实例发送请求,并执行,回调
Call newCall = getOkHttp.newCall(request);
newCall.enqueue(new Callback() {
private String responseData;
@Override
public void onResponse(Call arg0, Response arg1)
throws IOException {
//获取请求结果
responseData = arg1.body().string();
//因为我们要让UI改变,所以在主线程改变UI
runOnUiThread(new Runnable() {
@Override
public void run() {
// 设置到我们的显示区
mContent.setText(responseData);
}
});
}
@Override
public void onFailure(Call arg0, IOException arg1) {
}
});
}
}).start();
}
public void doPost() {
new Thread(new Runnable() {
private String postResposeData;
@Override
public void run() {
// 同样先创建Okhttp实例化
OkHttpClient postOkHttp = new OkHttpClient();
// 区别:post请求我们知道都是传的实体类型,所以我门用request body来存放对象要提交的参数
FormBody body = new FormBody.Builder()
.add("username", "ourtext")
.add("password", "666666")
.build();
// 创建请求体,添加请求内容
Request request = new Request.Builder()
.post(body)
.url("http://apis.juhe.cn/catering/query?key=key&lng=121.538123&lat=31.677132&radius=2000")
.build();
// 请求回调,获取服务器返回的数据
//注释部分:同步请求
//Response execute = postOkHttp.newCall(request).execute();
//postResposeData = execute.toString();
//返回数据为:postResposeData=Response{protocol=http/1.1, code=200, message=OK, url=http://apis.juhe.cn/catering/query?key=key&lng=121.538123&lat=31.677132&radius=2000}
//我们同样如get请求使用异步请求
postOkHttp.newCall(request).enqueue(new Callback() {
private String responseData;
@Override
public void onResponse(Call arg0, Response arg1) throws IOException {
//返回的数据
responseData = arg1.body().string();
runOnUiThread(new Runnable() {
public void run() {
mContent.setText(responseData);
}
});
}
@Override
public void onFailure(Call arg0, IOException arg1) {
}
});
}
}).start();
}
}
activity_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/okhttp_get"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="5dp"
android:text="Get请求" />
<TextView
android:id="@+id/okhttp_post"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="5dp"
android:text="Post请求" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#000" />
<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:text="Json数据展示区" />
</LinearLayout>
进阶实践
其实早期针对于OkHttp中get、post请求的 demo 记录过那么俩篇,后来都被我总结到这里了…
因上半部分针对的效果场景并未说明,故此处同样讲解的是OkHttp下的Get请求与Post请求(不包含文件与图片的上传与下载)
前提 (使用了三方平台的接口)
Effect
实现过程
MainActivity
package com.example.dow.okpost;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
private TextView mContent;
private TextView mBtn1;
private TextView mBtn2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String PROJECT_KEY="a79a913e685b1e7c";
//这里post请求用到了此URL
final String URL="http://api.jisuapi.com/train/station2s?appkey="+PROJECT_KEY;
mBtn1 = (TextView) findViewById(R.id.tv_Btn1);
mBtn2 = (TextView) findViewById(R.id.tv_Btn2);
mContent = (TextView) findViewById(R.id.tv_content);
mBtn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient okHttpClient = new OkHttpClient();
FormBody Body = new FormBody.Builder()
.add("start","上海")
.add("end","北京")
.add("ishigh","0").build();
Request request = new Request.Builder()
.post(Body)
.url(URL)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String result = response.body().string();
runOnUiThread(new Runnable() {
@Override
public void run() {
mContent.setText(result);
}
});
}
});
}
}).start();
}
});
mBtn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
// 1.创建实例对象
OkHttpClient getOkHttp = new OkHttpClient();
// 2-1.创建请求信息-先创建请求的容器.在填充请求的数据,并提交
final Request request = new Request.Builder()
.url("http://api.jisuapi.com/train/station2s?appkey=a79a913e685b1e7c&start=杭州&end=北京&ishigh=0")
.build();
// 3.使用okhttp的实例发送请求,并执行,回调
Call newCall = getOkHttp.newCall(request);
newCall.enqueue(new Callback() {
public String responseData;
@Override
public void onResponse(Call arg0, Response arg1)
throws IOException {
//获取请求结果
responseData = arg1.body().string();
//因为我们要让UI改变,所以在主线程改变UI
runOnUiThread(new Runnable() {
@Override
public void run() {
mContent.setText(responseData);
}
});
}
@Override
public v ilure(Call arg0, IOException arg1) {
}
}
}).start();
}
});
}
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.dow.okpost.MainActivity">
<TextView
android:layout_width="match_parent"
android:padding="8dp"
android:gravity="center"
android:id="@+id/tv_Btn1"
android:layout_height="wrap_content"
android:text="Post查询数据" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#2b2b2b"
/>
<TextView
android:layout_width="match_parent"
android:padding="8dp"
android:gravity="center"
android:id="@+id/tv_Btn2"
android:layout_height="wrap_content"
android:text="Get查询数据" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#2b2b2b"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/tv_content"
/>
</LinearLayout>