关于Android网络请求OkHttp的用法(一)
作者:黑衣侠客
HttpURLConnection
前言
首先,在过去,Android发送Http请求一共有两种方式,HttpURLConnection和HttpClient。但是,由于HttpClient存在API数量过多、扩展困难等缺点,在Android6.0系统中,HttpClient的功能被完全的移除了,标志着HttpClient被正式弃用了。我们Android中的OkHttp其实是HttpURLConnection的封装升级,因此,在学习OkHttp之前,我们应该先从HttpURLConnection入手学习,下面让我们进入正式的学习。
首先需要创建获取HttpURLConnection实例,一般只需要new出一个URL对象,并传入目标的网络地址,然后调用URL的openConnection方法即可。
URL url = new URL("https://www.baidu.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
在得到HttpURLConnection实例后,我们可以设置HTTP的请求方法。常用的请求方法有两个:GET和POST。其中GET表示希望从服务器那里获取数据,而POST则表示希望提交数据给服务器。写法如下:
connection.setRequestMethod("GET");
接下来就是自由定制的内容了,例如:设置连接超时、读取超时的毫秒数、以及服务器希望得到的一些消息等。示例写法如下:
connection.setConnectTimeout(8000);//连接超时,后面单位是毫秒
connection.setReadTimeout(8000);//读取超时
之后再调用getInputStream()方法就可以获取到服务器返回的输入流了,接下来就是对输入流进行读取了,如下所示:
InputStream in = connection.getInputStream();
最后调用disconnect()方法将这个HTTP连接关闭掉,如下所示:
connection.disconnect();
大致的介绍就这么多,下面是HttpURLConnection的应用项目实例:
MainActivity
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
TextView responseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sendRequest = findViewById(R.id.send_request);
responseText = findViewById(R.id.response_text);
sendRequest.setOnClickListener(this);
}
public void onClick(View v){//点击方法
if(v.getId()==R.id.send_request){
sendRequestWithHttpURLConnection();
}
}
private void sendRequestWithHttpURLConnection(){
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;//创建connection对象
BufferedReader reader = null;//创建BufferedReader对象
try {
URL url = new URL("https://www.baidu.com");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");//HttpURLConnection向目标地址(百度首页)发送了一条HTTP请求
connection.setConnectTimeout(8000);//连接
connection.setReadTimeout(8000);//读取
InputStream in = connection.getInputStream();
//下面对获取到的输入流进行读取
reader = new BufferedReader(new InputStreamReader(in));//对服务器的返回流进行读取
StringBuilder response = new StringBuilder();
String line;
while((line = reader.readLine())!=null){
response.append(line);//将获取到的输入流内容,按行读入response(StringBuilder)中
}
showResponse(response.toString());
} catch(Exception e){
e.printStackTrace();
} finally {
if(reader!=null){
try{
reader.close();
}catch(Exception e){
e.printStackTrace();
}
}
if(connection!=null){
connection.disconnect();//调用disconnect()方法将这个HTTP连接关闭掉
}
}
}
}).start();
}
private void showResponse(final String response){
runOnUiThread(new Runnable() {
@Override
public void run() {
//在这里进行对UI的操作
responseText.setText(response);
}
});
}
}
activity_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/send_request"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="Send Request"/>
<!--
ScrollView是垂直滑动布局
-->
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/response_text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>
</LinearLayout>
==注意:还要在AndroidManifest中添加权限
<uses-permission android:name="android.permission.INTERNET"/>
另外,我还添加了一个这个:
android:usesCleartextTraffic="true"
具体原因在这篇文章中可以看见
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.networktest2">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
OkHttp
前言
在开源盛行的今天,有许多的网络通信库都可以代替原生的HttpURLConnection,而OkHttp无疑是做的最出色的一个,OkHttp是由Square公司开发的,这个公司在开源事业上面贡献良多,除了OkHttp之外,还开发了Picasso、Retrofit等著名的开源项目。OkHttp不仅在接口封装上面做得简单易用,就连在底层实现上也是自成一派,那么现在就让我们来了解一下OkHttp的用法,OkHttp的项目主页地址是:https://github.com/square/okhttp
首先添加gradle依赖(最好是最新版本的)
implementation 'com.squareup.okhttp3:okhttp:4.2.2'
其次,创建一个OkHttpClient的实例:
OkHttpClient client = new OkHttpClient();
如果想要发起HTTP请求,就需要创建一个Request对象:
Request request = new Request.Builder().build();
当然,我们上面的代码创建的Request只是一个空的Request对象,并没有什么实际作用,我们可以在最终的build()方法之前连缀很多的方法来丰富这个Request对象。比如,可以通过url()方法来设置目标的网络地址:
Request request = new Request.Builder()
.url("https://www.baidu.com")
.build();
之后调用OkHttpClient的newCall()方法来创建一个Call对象,并调用它的execute()方法来发送请求并获取服务器返回的数据,写法如下:
Response response = client.newCall(request).execute();
其中,Response对象就是服务器返回的数据了,我们可以使用如下的写法来得到返回的具体内容:
String responseData = response.body().string();
使用OkHttp来进行对百度HTTP数据进行获取:
MainActivity
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
TextView responseText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sendRequest = findViewById(R.id.send_request);
responseText = findViewById(R.id.response_text);
sendRequest.setOnClickListener(this);
}
public void onClick(View v){//点击方法
if(v.getId()==R.id.send_request){
//sendRequestWithHttpURLConnection();
sendRequestWithOkHttp();
}
}
/*private void sendRequestWithHttpURLConnection(){
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;//创建connection对象
BufferedReader reader = null;//创建BufferedReader对象
try {
URL url = new URL("https://www.baidu.com");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");//HttpURLConnection向目标地址(百度首页)发送了一条HTTP请求
connection.setConnectTimeout(8000);//连接
connection.setReadTimeout(8000);//读取
InputStream in = connection.getInputStream();
//下面对获取到的输入流进行读取
reader = new BufferedReader(new InputStreamReader(in));//对服务器的返回流进行读取
StringBuilder response = new StringBuilder();
String line;
while((line = reader.readLine())!=null){
response.append(line);//将获取到的输入流内容,按行读入response(StringBuilder)中
}
showResponse(response.toString());
} catch(Exception e){
e.printStackTrace();
} finally {
if(reader!=null){
try{
reader.close();
}catch(Exception e){
e.printStackTrace();
}
}
if(connection!=null){
connection.disconnect();//调用disconnect()方法将这个HTTP连接关闭掉
}
}
}
}).start();
}*/
private void showResponse(final String response){
runOnUiThread(new Runnable() {
@Override
public void run() {
//在这里进行对UI的操作
responseText.setText(response);
}
});
}
private void sendRequestWithOkHttp(){
new Thread(new Runnable() {
@Override
public void run() {
try{
OkHttpClient client = new OkHttpClient();//创建OkHttp实例
Request request = new Request.Builder()
.url("https://www.baidu.com")
.build();//创建Request对象
Response response = client.newCall(request).execute();//调用OkHttpClient的newCall()方法来创建一个Call对象,并调用它的execute()方法来发送请求并获取服务器返回的数据
String responseData = response.body().string();//将response数据对象转为String类型
showResponse(responseData);
}catch(Exception e){
e.printStackTrace();
}
}
}).start();
}
}