Android网络请求知识整理
时隔多月在10月24日这天整理了一篇个人安卓学习笔记,希望通过这篇博客传递知识,同时也能帮助自己更好的巩固知识。
项目展示
一、HttpUrlConnection GET和POST请求
HttpURLConnection的Get请求
//创建url,表示要访问的网络
URL url = new URL("http://www.baidu.com");
//构建访问连接对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置访问方式
conn.setRequestMethod("GET");
//设置连接超时
conn.setConnecTimeout(5000);
//获取返回的字节流
InputStream inputStream = conn.getInputStream();
//关闭连接
conn.disconnect();
实现网络请求实现步骤
网络访问必须要在线程中执行才行
- 创建URL对象
- 构建HTTPURLConnection 连接对象
- 设置访问方式
- 设置连接超时
- 获取返回的字节输入流
- 处理字节输入流,转换为字符串,处理界面更新
- 关闭连接对象
HttpURLConnection的Post请求
准备链接对象
//设置链接对象的网址
String url = "http://192.161.0.1:8080/Restaurant/user/login";
URL url = new URL(url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true); //支持提交数据
conn.setDoInput(true); //支持接收数据
conn.setRequestMenthod("POST");
json格式数据
conn.setRequestProperty("Conten-Type","application/json");
JSONObject obj = new JSONObject();
obj.put("userName","tom");
obj.put("userPassword","123");
String data = obj.toString();
普通表单数据
conn.setRequestProperty("Content-Type","application/")
二、OkHttp3知识详解
框架流程
OkHttpClient->Request->RealCall->Dispatcher->interceptors->RetryAndFollow/Bridge/Cache/Connect/CallServer
- OkHttpClient
- 首先会创建这个OkHttpClient对象,表示我们所有的请求的一个客户端的类,单例创建,只会创建一个
- Request
- 创建Request这个对象,这个对象封装了一些请求报文信息,请求URL地址,请求方法(get/post/put/delet…)还有各种请求头,然后通过Builder构建者模式来链式生成Request对象
- RealCall
- 通过调用Request.newCall方法来创建一个Call对象,这个Call对象,这个Call对象在我们的OkHttp中的实现类就是RealCall,这个RealCall代表着实际的OkHttp请求,他是连接Request和Response的一个桥梁,通过Call进行同步异步操作
- Dispatcher
- 决定OkHttp的同步或者异步,Dispatcher分发器,在他的内部维护了线程池,这个线程池用于执行网络请求,通过之前创建好的RealCall对象,他会添加到Dispathcher里面
- Dispatcher会不断的从request这个队列中去获取到他所需求的RealCall这个请求,然后判断是否存在缓存,如果没有缓存则通过调用ConnectInterceptor/CallServerInterceptor服务器数据的返回
- Iinterceptors
- 不管是同步还是异步,OKhttp内部会通过一个叫interceptors(拦截器列)的东西来进行真正的服务器数据获取,会构建一个拦截器列,然后依次执行整个拦截器中的每个拦截器来将我们服务器获得的数据返回。
- 无论同步或者异步最终都是会调用拦截器进行分发
基本使用方法
- 导入依赖,开启网络访问权限
- 创建OkHttpClient对象client
- 通过Builder模式创建Request对象、参数必须有url对象;Request.Builder设置更多的参数比如:header、method、get/post等
- 使用Client对象,将request对象封装为一个call对象
- 通过Call对象的execute()和cancel()等方法完成网络访问
implementation 'com.squareup.okhttp3:okhttp:3.12.1'
debugImplementation 'com.squareup.okhttp3:logging-interceptor:3.12.1'
开启网络访问权限
<uses-permission android:name="android.permission.INTERNET" />
OkHttp进行Get请求
- 获取OkHttpClient对象
OkHttpClient client = new OkHttpClient();
- 构造Request对象
通过建造者模式和链式调用指明进行Get请求,并通过Get请求的地址
Request request = new Request.Builder()
.get()
.url("https://www.baidu.com")
.build();
- 将Request封装成为Call
Call call = client.newCall(request);
- 根据需要调用同步或者异步请求方法
//Response response = call.execute();同步请求方法,返回Response会抛出IO异常
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//失败情况
Toast.makeText(OkHttpRequest.this, "网络访问失败", Toast.LENGTH_SHORT).show();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//请求成功
response = client.newCall(request).execute();
result = response.body().string();
runOnUiThread(new Runnable() {//子线程内无法更新,通过runOnUiThread来更新界面Ui
@Override
public void run() {
textView.setText(result);
}
});
}
});
Okhttp通过Post提交键值对
- 获取OkHttpClient对象
OkHttpClient client = new OkHttpClient();
- 构建FormBody,传入请求参数
构建构建FormBody formBody = new FormBody.Builder()
.add("id","1")
.add("name","尹志鹏")
.add("password","123456")
.build();
- 构建Request,将FormBody作为Post方法的参数传入
final Request request = new Request.Builder()
.url("http://www.baidu.com/")
.post(formBody)
.build();
- 将Request封装为Call
Call call = client.newCall(request);
- 调用请求重写回调方法
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Toast.makeText(OkHttpActivity.this, "Post Failed", Toast.LENGTH_SHORT).show();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String res = response.body().string();
runOnUiThread(new Runnable() {
@Override
public void run() {
contentTv.setText(res);
}
});
}
});
三、个人项目代码
public class OkHttpRequest extends AppCompatActivity implements View.OnClickListener {
private String TAG = "OkHttpRequest";
private EditText inputthing;
private Button tijiaoBtn;
private Button syncGet;
private Button asynGet;
private TextView textView;
private String result;
private Request request;
private Response response;
private Button OkHttpRequestPostFrom;
private Button OkHttpRequestPostGson;
private Gson gson;
//获取客户端对象
private static OkHttpClient client = new OkHttpClient();
private String inputId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ok_http_request);
init();
}
private void init() {
syncGet = findViewById(R.id.OkHttpRequest_syncGet);
asynGet = findViewById(R.id.OkHttpRequest_asyncGet);
textView = findViewById(R.id.OkHttpRequest_tx_text);
OkHttpRequestPostFrom = (Button) findViewById(R.id.OkHttpRequest_PostFrom);
OkHttpRequestPostGson = (Button) findViewById(R.id.OkHttpRequest_Gson);
tijiaoBtn = findViewById(R.id.OkHttpRequest_btn_tijiao);
inputthing = findViewById(R.id.OkHttpRequest_edText_input);
tijiaoBtn.setOnClickListener(this);
OkHttpRequestPostGson.setOnClickListener(this);
OkHttpRequestPostFrom.setOnClickListener(this);
syncGet.setOnClickListener(this);
asynGet.setOnClickListener(this);
tijiaoBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
inputId = inputthing.getText().toString();
Toast.makeText(OkHttpRequest.this, "输入的id值为" + inputId, Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.OkHttpRequest_syncGet://同步Get请求
initSyncData();
break;
case R.id.OkHttpRequest_asyncGet://异步Get请求
initAsyncData();
break;
case R.id.OkHttpRequest_PostFrom://Post请求
initPostFrom();
break;
case R.id.OkHttpRequest_Gson://Gson数据解析
initGson();
break;
}
}
/*
* Gson数据解析方法
* 1.导入依赖
* 2.创建实体类
* 3.实例化对象(gson对象和实体类)
* 4.获取gson解析数据
* */
private void initGson() {
final Request request = new Request.Builder()
.get()
.url("https://www.尹志鹏.com/android-system/user/getUser")
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Toast.makeText(OkHttpRequest.this, "网络请求失败!", Toast.LENGTH_SHORT).show();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
response = client.newCall(request).execute();
result = response.body().string();
Gson gson = new Gson();
final UserList userList = gson.fromJson(result,UserList.class);
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(userList.getStudentId());
}
});
}
});
}
private void initPostFrom() {
if (inputId == "" || inputId == null) {
Toast.makeText(this, "未输入参数自动设置为1", Toast.LENGTH_SHORT).show();
inputId = "1";
} else {
String url = "https://www.尹志鹏.com/android-system/user/postParamUser";
FormBody formBody = new FormBody.Builder()
.add("id", inputId)
.build();
request = new Request.Builder()
.url(url)
.post(formBody)
.build();
new Thread(new Runnable() {
@Override
public void run() {
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Toast.makeText(OkHttpRequest.this, "网络请求失败", Toast.LENGTH_SHORT).show();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
result = response.body().string();
Log.e(TAG, "onResponse: " + result);
OkHttpRequest.this.runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(result);
}
});
}
});
}
}).start();
}
}//Post请求
/*
* Get请求同步方法
* 同步调用容易阻塞主线程,一般不适用
* OKHttpclient client = new OkHttpClient();
* Request request = new Request.Builder().url(url).build();
* Request response = client.newCall(request).execute();
* String message = response.body().string();
* */
private void initSyncData() {
new Thread(new Runnable() {
@Override
public void run() {
/*
* 通过Builder设置更多的参数比如header、method、get等
* 使用Client对象,将request对象封装成为一个Call对象
* 通过Call对象的execute()和cancel()等方法完成网络访问
* */
//构造request对象,通过建造者模式和链式调用指明是Get方式和传入url地址
request = new Request.Builder()
.get()
.url("http://尹志鹏.com/web_home/static/api/news/categories.json")//输入需要请求的url
.build();
try {
response = client.newCall(request).execute();
result = response.body().string();
gson = new Gson();
final NewsList newsList = gson.fromJson(result, NewsList.class);
//不能再子线程更新UI,需要借助runOnUiThread()方法或者handler来处理
runOnUiThread(new Runnable() {
@Override
public void run() {
StringBuffer stringBuilder = new StringBuffer();
for (Integer integer : newsList.getExtend()) {
stringBuilder.append(" : " + integer);
}
textView.setText(stringBuilder.toString());
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}//Get同步请求
/*
* Get请求异步方法
* 异步请求调用的回调函数是在子线程,无法在子线程里面更新UI,需要借助runOnUiThread()方法或者Handler来处理
* OkHttpClient client = new OkHttpClient();
* Request request = new Request.Builder().url(url).build();
* client.newCall()request.enqueue.(new CallBack){onFailure(),onResponse()}
* */
private void initAsyncData() {
//新建一个客户端对象
Request request = new Request.Builder()
.get()
.url("https://www.尹志鹏.com/android-system/user/getUser")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//失败情况
Toast.makeText(OkHttpRequest.this, "网络访问失败", Toast.LENGTH_SHORT).show();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//请求成功
// response = client.newCall(request).execute();
result = response.body().string();
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(result);
}
});
}
});
}//Get异步请求
}
这段时间自己整理的学习笔记,可能不一定完善,如果存在问题还请各位大佬能够批评指正。最后祝各位1024节日快乐!