Android网络编程
一、基本协议
拥有Ip地址和端口号,用于准确处理一个网络数据包
拥有OSI七层模型的TCP/IP七层协议族
二、Http协议
应用层的面向对象的协议,支持c/s模式
三、Android的网络访问
需要网络安全配置
res/xml目录下
<network-security-config>
<base-config cleartextTrafficPermitted="true"/>
</network-security-config>
AndroidManifest.xml下
android:networkSecurityConfig="@xml/network_security_config"
HttpURLConnection的通信,通过URL的openConnection方法获得对象
HttpURLConnection connection = null;//获得对象
InputStream is = null;//获得输入流
//将url字符串转为URL对象
URL url = new URL(urlPath);
//获得HttpURLConnection对象
connection = (HttpURLConnection) url.openConnection();
//设置连接的相关参数
connection.setRequestMethod("GET");//默认为GET
connection.setUseCaches(false);//不使用缓存
connection.setConnectTimeout(15000);//设置连接超时时间
connection.setReadTimeout(15000);//设置读取超时时间
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36\n");
connection.setDoInput(true);//设置是否从httpUrlConnection读入,默认true
HttpURLConnection访问HTTP资源一般步骤
①根据URL地址创建URL对象
②使用URL对象的openConnection( )方法获取Ht tpURLConnect ion对象
③设置连接的属性,包括GET/ POST请求方式
④输入、输出数据
⑤关闭输入、输出流
⑥在AndroidMani fest配置文件中设置访问INTERNET的权限
GET方式
public static String post(String urlPath,List<NameValuePair> params){
//处理请求参数
if (params == null || params.size() == 0){
return get(urlPath);
}
try {
String body = getParamString(params);
byte[] data = body.getBytes();
//将url字符串转为URL对象
URL url = new URL(urlPath);
//获得HttpURLConnection对象
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//设置连接的相关参数
connection.setRequestMethod("POST");//默认为POST
connection.setUseCaches(false);//不使用缓存
connection.setConnectTimeout(15000);//设置连接超时时间
connection.setReadTimeout(15000);//设置读取超时时间
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36\n");
connection.setDoInput(true);//设置是否从httpUrlConnection读入,默认true
connection.setDoOutput(true);
//配置https的证书
if ("https".equalsIgnoreCase(url.getProtocol())) {
((HttpsURLConnection) connection).setSSLSocketFactory(HttpsUtil.getSSLSocketFactory());
}
//设置请求头属性,写入参数
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length",String.valueOf(data.length));
OutputStream os = connection.getOutputStream();
os.write(data);
os.flush();
//进行数据的读取,首先判断响应码是否为200
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//获得输入流
InputStream is = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
//读取数据
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
//关闭资源
is.close();
connection.disconnect();
//返回结果
return response.toString();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
post方式
public static String post(String urlPath,List<NameValuePair> params){
//处理请求参数
if (params == null || params.size() == 0){
return get(urlPath);
}
try {
String body = getParamString(params);
byte[] data = body.getBytes();
//将url字符串转为URL对象
URL url = new URL(urlPath);
//获得HttpURLConnection对象
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//设置连接的相关参数
connection.setRequestMethod("POST");//默认为POST
connection.setUseCaches(false);//不使用缓存
connection.setConnectTimeout(15000);//设置连接超时时间
connection.setReadTimeout(15000);//设置读取超时时间
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36\n");
connection.setDoInput(true);//设置是否从httpUrlConnection读入,默认true
connection.setDoOutput(true);
//配置https的证书
if ("https".equalsIgnoreCase(url.getProtocol())) {
((HttpsURLConnection) connection).setSSLSocketFactory(HttpsUtil.getSSLSocketFactory());
}
//设置请求头属性,写入参数
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length",String.valueOf(data.length));
OutputStream os = connection.getOutputStream();
os.write(data);
os.flush();
//进行数据的读取,首先判断响应码是否为200
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
//获得输入流
InputStream is = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
//读取数据
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
//关闭资源
is.close();
connection.disconnect();
//返回结果
return response.toString();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
四、Android的网络框架
OkHttp
添加依赖: implementation com. squareup. okhttp3 :okhttp:4.2.1
添加权限: <uses-permission android : name= android. permission. INTERNET" />
基本用法
- 新建一个0kHttpClient对象
- 通过Request. Builder对象新建一个Request对象
- 通过Reques t对象构造Call对象,调用enqueue( )以异步的方式将call加入调度队列,等待request执行完成
- 通过Call对象的Callback对象返回执行结果
get方法
//构造Request
Request request = new Request.Builder()
.url(url)
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 " +
"(KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36")
.addHeader("Accept","application/json")
.get()
.method("GET",null)
.build();
get异步请求( enqueue(new Callback() )
//发送请求,并处理回调
OkHttpClient client = HttpsUtil.handleSSLHandshakeByOkHttp();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.e("OKActivity",e.getMessage());
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
if (response.isSuccessful()){
//获取响应主体的字符串
String json = response.body().string();
//使用FastJson库解析json字符串
final Ip ip = JSON.parseObject(json,Ip.class);
runOnUiThread(new Runnable() {
@Override
public void run() {
//根据返回的code判断获取是否成功
if (ip.getCode() != 0){
ok.setText("未获得数据");
}else {
//解析数据
IpData data = ip.getData();
ok.setText(ip.getData().getIp() + "," + data);
}
}
});
}
}
});
}
post方法
通过RequestBody 构建请求数据
//将请求的参数组装成RequestBody
private RequestBody setRequestBody(Map<String,String> params){
FormBody.Builder builder = new FormBody.Builder();
for (String key : params.keySet()){
builder.add(key,params.get(key));
}
return builder.build();
}
private void post(String url,Map<String,String> params){
RequestBody body = setRequestBody(params);
//构造Request
Request request = new Request.Builder().url(url).post(body)
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 " +
"(KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36")
.addHeader("Accept","application/json")
.build();
//发送请求,并处理回调
OkHttpClient client = HttpsUtil.handleSSLHandshakeByOkHttp();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
if (response.isSuccessful()){
//获取响应主体的字符串
String json = response.body().string();
//使用FastJson库解析json字符串
final Ip ip = JSON.parseObject(json,Ip.class);
runOnUiThread(new Runnable() {
@Override
public void run() {
//根据返回的code判断获取是否成功
if (ip.getCode() != 0){
ok.setText("未获得数据");
}else {
//解析数据
IpData data = ip.getData();
ok.setText(ip.getData().getIp() + "," + data);
}
}
});
}
}
});
}
上传文件
// 1. 创建请求主体RequestBody
RequestBody fileBody = RequestBody.create(new File(fileName), MEDIA_TYPE_PNG);
RequestBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("title", "头像")
.addFormDataPart("file", fileName, fileBody)
.build();
// 2. 创建请求
Request request = new Request.Builder()
.url(url)
.header("Authorization", "Client-ID 4ff8b2fc6d5f339")
.header("User-Agent", "NetworkDemo")
.post(body)
.build();
// 3. 创建OkHttpClient对象,发送请求,并处理回调
OkHttpClient client = HttpsUtil.handleSSLHandshakeByOkHttp();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.e(TAG, e.getMessage());
runOnUiThread(new Runnable() {
@Override
public void run() {
ok.setText(fileName + "上传失败");
}
});
}
@Override
public void onResponse(@NotNull Call call, @NotNull final Response response) throws IOException {
final String str = response.body().string();
runOnUiThread(new Runnable() {
@Override
public void run() {
ok.setText("上传成功," + str);
}
});
}
});
}
下载文件
private void downFile(final String url, final String path) {
// 1. 创建Requet对象
Request request = new Request.Builder().url(url).build();
// 2. 创建OkHttpClient对象,发送请求,并处理回调
OkHttpClient client = HttpsUtil.handleSSLHandshakeByOkHttp();
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
if (response.isSuccessful()) {
// 1. 获取下载文件的后缀名
String ext = url.substring(url.lastIndexOf(".") + 1);
// 2. 根据当前时间创建文件名,避免重名冲突
final String fileName = System.currentTimeMillis() + "." + ext;
// 3. 获取响应主体的字节流
InputStream is = response.body().byteStream();
// 4. 将文件写入path目录
writeFile(is, path, fileName);
// 5. 在界面给出提示信息
ok.post(new Runnable() {
@Override
public void run() {
ok.setText(fileName + "下载成功,存放在" + path);
}
});
}
}
@Override
public void onFailure(@NotNull Call call, @NotNull final IOException e) {
Log.d(TAG, e.getMessage());
runOnUiThread(new Runnable() {
@Override
public void run() {
ok.setText("下载失败," + e.getMessage());
}
});
}
});
}