HTTP协议
我们做android开发的,做的就是程序方面的,用术语说就是应用层,给用户用的东西,那么应用层就需要受到http协议的控制,下面我们看看http协议的主要特点
- 支持c/s模式
- 简单快速:只需要传送请求方法和路径,请求方法常用的有:GET、HEAD、POST等
- 灵活:允许传输任意类型的数据对象,用Content-Type进行标记
- 无连接: 限制每次连接只处理一个请求
- 无状态:对书屋处理没有记忆功能
HTTP的URL格式
- http://host[:port][/path]
- http表示要通过HTTP协议来定位网络资源;host表示合法的Internet主机域名或者IP地址;port指定一个端口号,为空则使用默认端口88;path指定请求资源的URI;
常见的状态码的意思如下
200 OK:客户端请求成功
403 Forbidden:服务器收到请求,但是拒绝提供服务
404 Not Found:服务器无法根据客户端的请求找到资源
500 Internal Server Error:服务器发生不可预期的错误
http网络请求的问题(https是没有问题的)
- 更改网络安全配置
- 在res新增xml目录,创建
network_security_config.xml请求
<network-security-config>
<base-config cleartextTrafficPermitted="true"/>
</network-security-config>
- 在AndroidManifest.xml中的application标签增加一下属性
android:networkSecurityConfig="@xml/network_security_config">
Android常用的网络编程框架
- OkHttp(已经代替了HttpURLConnection)
- 配置
- OkHttp支持Android2.3及其以上版本,java要求JDK1.7以上
- 添加依赖:
implementation 'com.squareup.okhttp3:okhttp:4.2.1'
- 添加权限:
<uses-permission android:name="android.permission.INTERNET" />
OkHttp开发基本思路
- OkHttp的每次网络请求是一个Request,提供Request必要的参数url、header等,基于Request构造处一个call对象,再调用它的execute()方法,就能取得web Server回复的数据
- 如果同步调用,需要在独立的线程中运行,使用异步调用,则采用回调的方式执行,在内部封装了一个请求队列
- 基本步骤
- 新建一个OkHttpClient对象
- 通过Request.Builder对象新建一个Request对象
- 通过Request对象构造Call对象,调用enqueue()以异步的方式将call加入调度堆列,等待request执行完成
- 通过Call对象的Callback对象返回执行结果
GET请求
private void get(String url){
Request request=new Request.Builder().url(url)
//设置和添加Header
.header("user-agent",
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36" +
"(KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36")
.addHeader("Accept","application/json")
.get()
.method("GET",null)
.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()){
//获得响应主体的json字符串
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){
tvResult.setText("未获得数据");
}
else {
//解析数据
IpData data=ip.getData();
//显示出来的只是放进去的值,别的那么多数据,显示不出来
tvResult.setText(data.getIp()+","+data.getArea());
}
}
});
}
}
});
}
Http Header的读写
- 当写到请求头的时候,使用header(name,value)可以设置唯一的name、value.如果已经优质,旧的将被移除,然后添加新的
- 使用addHeader(name、value)可以添加多值(添加,不移除已有的)
post异步请求
- 通过RequestBody构建请求数据
FormBody.Builder builder=new FormBody.Builder();
for (String key:params.keySet()){
//构建要post到Server的数据
builder.add(key,params.get(key));
}
return builder.build();
}
post异步请求JSON数据
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown;charset=utf-8");
private void post(String url,Map<String,String> params){
RequestBody body=setRequestBody(params);
Request request=new Request.Builder().url(url).post(body)
post方式提交Multipart文件
public static MediaType MEDIA_TYPE_PNG=MediaType.parse("img/png");
private void uploadImage(String url,String fileName){
//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)
.post(body)
.build();
Post异步下载文件
@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.在界面上给出提示信息
tvResult.post(new Runnable() {
@Override
public void run() {
tvResult.setText(fileName+"下载成功,存放在"+path);
}
});
}
图片加载框架Glide
- 添加依赖:
implementation 'com.github.bumptech.glide:glide:4.10.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
//https图片处理
implementation 'com.github.bumptech.glide:okhttp3-integration:4.10.0'
- 添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
- 使用
Glide.with(this).load("http://goo.gl/gegYUd"),into (imgeView);
Glide 加载https图片
public static OkHttpClient handleSSLHandshakeByOkHttp() {
X509TrustManager trustManager = (X509TrustManager) getTrustManager()[0];
return new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
//支持HTTPS请求,跳过证书验证
.sslSocketFactory(getSSLSocketFactory(), trustManager)
.hostnameVerifier(new TrustAllHostnameVerifier())
.build();
}
-
创建继承AppGlideModule类的自定义类,重写registerComponents()方法