1. HttpURLConnection基本使用
HttpURLConnection是网络请求的基本类,在具体了解HttpURLConnection的基本使用前,先了解一些RUL
1.1 URL介绍
统一资源定位符URL(Uniform Resource Locator)是www客户机访问Internet时用来标识资源的名字和地址。
URL的基本格式是:
<METHOD>://<HOSTNAME:PORT>/<PATH>/<FILE>
-
Method
是传输协议 -
HOSTNAME
是文档和服务器所在的Internet主机名(域名系统中DNS中的点地址) -
PORT
是服务端口号(可省略) -
PATH
是路径名 -
FILE
是文件名
示例:
http://www.weixueyuan.net/view/6079.html (www.weixueyuan.net是主机名,view/6079.html是文件路径和文件名)
简单的可以把URL理解为包含:协议、主机名、端口、路径、查询字符串和参数等内容。每一段可以独立设置。
Java中有个java.net包,其中的类是进行网络编程的,URL对象则是一个可以表示网络资源的类。程序利用URL对象能够实现Internet寻址、网络资源的定位连接、在客户机与服务器之间访问等。
URL对象的方法也很简单,基本上都是get方法,主要用于分段获取一个URL中各个部分,比单纯地使用一个字符串来表示链接地址,URL对象的方式更加灵活方便。
同时,它可以使用openConnection
方法,获取一个URLConnection对象,以建立网络连接。
1.2 HttpURLConnection使用
HttpURLConnection的基本使用步骤如下:
-
获取HttpURLConnection实例,需new一个URL对象,传入目标网络地址
URL url = new URL("http://www.baidu.com); HttpURLConnection connection = (HttpURLConnection) url.openConnection();
-
设置HTTP请求使用方法:一般有两种:GET与POST
connection.setRequestMethod("GET");
-
自由定制,比如设置连接超时,读取超时毫秒数等
connection.setConnectionTimeout(8000); connection.setReadTimeout(8000);
-
调用
getInputStream()
方法获取到服务器返回的输入流,对输入流进行读取InputStream in = connection.getInputStream();
-
最后,调用
disconnection()
方法将这个HTTP连接关闭掉connection.disconnection();
示例:
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 = (Button) findViewById(R.id.send_request);
responseText = (TextView) findViewById(R.id.response_text);
sendRequest.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.send_request) {
Log.e("MainActivity","first");
sendRequestWithHttpURLConnection();
}
}
private void sendRequestWithHttpURLConnection() {
//开启线程发起网络请求
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
//获取HttpRULConnection实例
URL url = new URL("https://www.baidu.com");
connection = (HttpURLConnection) url.openConnection();
//设置请求方法和自由定制
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
//获取响应码和返回的输入流
int i = connection.getResponseCode();
InputStream in = connection.getInputStream();
//对输入流进行读取
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
showResponse(response.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null) {
connection.disconnect();
}
}
}
}).start();
}
private void showResponse( final String response) {
runOnUiThread(new Runnable() {
@Override
public void run() {
//进行UI操作
responseText.setText(response);
}
});
}
}
在AndroidManifest.xml中注册权限
<uses-permission android:name="android.permission.INTERNET"/>
备注:(Android 9.0不能明文连接,需用https)
示例2:从网络中下载图片
-
修改activity_main.xml文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/send_request" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Send Request"/> <Button android:id="@+id/download_picture" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Download_picture"/> <ImageView android:id="@+id/imagPic" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/response_text" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </ScrollView> </LinearLayout>
-
新建StreamTool.java文件,读取流中文件
public class StreamTool { //从流中读取数据 public static byte[] read(InputStream inStream) throws Exception{ ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while((len = inStream.read(buffer)) != -1) { outStream.write(buffer,0,len); } inStream.close(); return outStream.toByteArray(); } }
-
新建GetData.java文件,获取数据类
public class GetData { // 定义一个获取网络图片数据的方法: public static byte[] getImage(String path) throws Exception { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 设置连接超时为5秒 conn.setConnectTimeout(5000); // 设置请求类型为Get类型 conn.setRequestMethod("GET"); // 判断请求Url是否成功 if (conn.getResponseCode() != 200) { throw new RuntimeException("请求url失败"); } InputStream inStream = conn.getInputStream(); byte[] bt = StreamTool.read(inStream); inStream.close(); return bt; } }
-
修改MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private TextView responseText; private String picture = "https://i.ytimg.com/vi/ck-2nnFC8oE/hqdefault.jpg"; private Bitmap bitmap; private ImageView imgPic; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button sendRequest = (Button) findViewById(R.id.send_request); responseText = (TextView) findViewById(R.id.response_text); imgPic = (ImageView) findViewById(R.id.imagPic); Button downloadPicture = (Button) findViewById(R.id.download_picture); downloadPicture.setOnClickListener(this); sendRequest.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.send_request) { sendRequestWithHttpURLConnection(); } else if (v.getId() == R.id.download_picture) { new Thread(new Runnable() { @Override public void run() { try { byte[] data = GetData.getImage(picture); bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); showBitmap(); } catch (Exception e) { e.printStackTrace(); } } }).start(); } } private void sendRequestWithHttpURLConnection() { //开启线程发起网络请求 new Thread(new Runnable() { @Override public void run() { HttpURLConnection connection = null; BufferedReader reader = null; try { URL url = new URL("https://www.baidu.com"); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); int i = connection.getResponseCode(); InputStream in = connection.getInputStream(); //对输入流进行读取 reader = new BufferedReader(new InputStreamReader(in)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } showResponse(response.toString()); } catch (Exception e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } if (connection != null) { connection.disconnect(); } } } }).start(); } private void showResponse( final String response) { runOnUiThread(new Runnable() { @Override public void run() { //进行UI操作 responseText.setText(response); } }); } private void showBitmap() { runOnUiThread(new Runnable() { @Override public void run() { imgPic.setImageBitmap(bitmap); } }); } }
备注:
- HttpURLConnection的
connect()
函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。 无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()
这个函数里面才正式发送出去。
网友评论