第12天几种网络请求方式
安卓中常见的网络请求方式:
一.HttpUrlConnection(基础,必须掌握,需要封装)
1.get请求
2.post请求
3.下载网络视频/音乐/图片到SD卡中
二.HttpClient(已经过时,不推荐使用)
android 6.0(api 23) SDK,不再提供org.apache.http.*,书写简单 但是效率比HttpUrlConnection低,DefaultHttpClient该类已经不提供了
三.Xutils(第三方框架,不推荐使用)
此框架庞大而周全,这个框架可以网络请求,同时可以图片加载,又可以数据存储,又可以 View 注解,使用这种框架很方便,这样会使得你整个项目对它依赖性太强,万一以后这个库不维护了,或者中间某个模块出问题了,这个影响非常大,所以在项目开发时,一般会更喜欢选择专注某一领域的框架。
1.添加依赖: implementation ‘org.xutils:xutils:3.5.1’
2.创建MyApplication 初始化
清单文件:
3. Java代码
(1)get请求
(2)post请求
(3)加载图片
四.Okhttp(第三方框架,必须掌握,需要封装)
okhttp是一个第三方类库,用于android中请求网络。
这是一个开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献(该公司还贡献了Picasso和LeakCanary) 。用于替代HttpUrlConnection和Apache HttpClient(android API23 里已移除HttpClient)。
1.同步get请求:开启子线程
2.同步post请求:开启子线程
3.异步get请求:不需要开启子线程
4.异步post请求:不需要开启子线程
五.Volley(第三方框架,必须掌握)
-
所谓Volley,它是2013年Google I/O上发布的一款网络框架,基于Android平台,能使网络通信更快,更简单,更健全
-
优点:
(1)默认Android2.3及以上基于HttpURLConnection,2.3以下使用基于HttpClient;
(2)符合Http 缓存语义 的缓存机制(提供了默认的磁盘和内存等缓存);
(3)请求队列的优先级排序;
(4)提供多样的取消机制;
(5)提供简便的图片加载工具(其实图片的加载才是我们最为看重的功能);(6)一个优秀的框架。 -
缺点:
它只适合数据量小,通信频繁的网络操作,如果是数据量大的,像音频,视频等的传输,还是不要使用Volley的为好 -
工作原理
其中蓝色的是主线程,绿色的是缓存线程,黄色的是网络线程
1.当一个Request请求添加到RequestQueue请求队列中,Volley就开始工作了。RequestQueue请求队列中持有一个CacheDispatcher缓存管家和一组NetworkDispatcher网络管家。
2.RequestQueue会先叫来CacheDispatcher缓存管家,让他去看看,当前请求的数据在没在cache中。
2.1.当前的数据在cache中,那就把数据从cache中取出来,然后经过一番加工,将加工好的数据交付给主线程
2.2.当前数据没在cache中,进行第3步
3.进行到了这一步,那肯定是数据没有在缓存中,那只能去网络中获取了,这时候RequestQueue会叫来NetworkDispatcher,NetworkDispatcher可是有一帮呢,其实这是一个线程池,默认情况下会启动4个线程去网络下载数据。所以RequestQueue把当前闲着的NetworkDispatcher叫来,给他们分配任务。
4.拿到任务的NetworkDispatcher就会去网络上下载数据了,与此同时,他会判断下载到的数据能否写入到cache缓存中,如果可以的话就写入cache,以便于下一次直接从cache中获取到数据。最后,将数据加工,交付给主线程。
1.get请求
2.post请求
3.请求图片
六.全部代码(9个网络请求,没有封装,后期封装)
1.xml布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.media.day12_httpurlconnection.HttpUrlConnectionActivity"
android:orientation="vertical">
<Button
android:id="@+id/get"
android:text="urlconnection_get请求"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/post"
android:text="urlconnection_post请求"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/okhttp_tongbu_get"
android:text="okhttp_同步get请求"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/okhttp_tongbu_post"
android:text="okhttp_同步post请求"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/okhttp_yibu_get"
android:text="okhttp_异步get请求"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/okhttp_yibu_post"
android:text="okhttp_异步get请求"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/volley_get"
android:text="volley_get请求"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/volley_post"
android:text="volley_post请求"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/volley_image"
android:text="volley_图片请求"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
2.Java代码
/**
* 一。HttpUrlConnection
* 1.get请求:thread+handler
* 2.post请求:thread+handler
*
* 二。okhttp网络请求
* implementation 'com.squareup.okhttp3:okhttp:3.12.1'
* 同步和异步的区别:同步需要开启子线程做处理 ;异步不需要,本身封装了线程
* 1。get同步请求:thread
* 2。post同步请求
* 3。get异步请求:
* 4。post异步请求
*
* 三。volley网络请求
* implementation 'eu.the4thfloor.volley:com.android.volley:2015.05.28'
* 1。get请求
* 2。post请求
* 3。请求图片
*
* 四。三者的区别
* 1。HttpUrlConnection 需要封装;Okhttp 需要封装;volley 不需要封装
* 2。数量小使用volley;数量大使用Okhttp
*
* */
public class HttpUrlConnectionActivity extends AppCompatActivity implements View.OnClickListener{
Button get,post,okhttp_tongbu_get,okhttp_tongbu_post,okhttp_yibu_get,okhttp_yibu_post,volley_get,volley_post,volley_image;
ImageView imageView;
//get请求网址
String get_str="http://10.211.55.6:8080/lianxi/login?username=12&password=12";
//post请求网址
String post_str="http://10.211.55.6:8080/lianxi/login";
//图片请求网址
String image_url="https://images0.cnblogs.com/blog/651487/201501/281616176915467.jpg";
//volley 请求队列
RequestQueue requestQueue;
//handler处理,volley不需要使用
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==101){
String result= (String) msg.obj;
Toast.makeText(HttpUrlConnectionActivity.this, "get:"+result, Toast.LENGTH_SHORT).show();
}else if(msg.what==102){
String result= (String) msg.obj;
Toast.makeText(HttpUrlConnectionActivity.this, "post:"+result, Toast.LENGTH_SHORT).show();
}else if(msg.what==103){
String result= (String) msg.obj;
Toast.makeText(HttpUrlConnectionActivity.this, "okhttp_get_同步请求:"+result, Toast.LENGTH_SHORT).show();
}else if(msg.what==104){
String result= (String) msg.obj;
Toast.makeText(HttpUrlConnectionActivity.this, "okhttp_post_同步请求:"+result, Toast.LENGTH_SHORT).show();
}else if(msg.what==105){
String result= (String) msg.obj;
Toast.makeText(HttpUrlConnectionActivity.this, "okhttp_get_异步请求:"+result, Toast.LENGTH_SHORT).show();
}else if(msg.what==106){
String result= (String) msg.obj;
Toast.makeText(HttpUrlConnectionActivity.this, "okhttp_post_异步请求:"+result, Toast.LENGTH_SHORT).show();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_http_url_connection);
get=findViewById(R.id.get);
post=findViewById(R.id.post);
okhttp_tongbu_get=findViewById(R.id.okhttp_tongbu_get);
okhttp_tongbu_post=findViewById(R.id.okhttp_tongbu_post);
okhttp_yibu_get=findViewById(R.id.okhttp_yibu_get);
okhttp_yibu_post=findViewById(R.id.okhttp_yibu_post);
volley_get=findViewById(R.id.volley_get);
volley_post=findViewById(R.id.volley_post);
volley_image=findViewById(R.id.volley_image);
imageView=findViewById(R.id.image);
get.setOnClickListener(this);
post.setOnClickListener(this);
okhttp_tongbu_get.setOnClickListener(this);
okhttp_tongbu_post.setOnClickListener(this);
okhttp_yibu_get.setOnClickListener(this);
okhttp_yibu_post.setOnClickListener(this);
volley_get.setOnClickListener(this);
volley_post.setOnClickListener(this);
volley_image.setOnClickListener(this);
//创建Volley请求队列
requestQueue = Volley.newRequestQueue(this);
requestQueue.start();
}
@Override
public void onClick(View v) {
switch (v.getId()){
//UrlConnection get请求
case R.id.get:
get();
break;
//UrlConnection post请求
case R.id.post:
post();
break;
//okhttp:同步get请求:需要开启线程做处理
case R.id.okhttp_tongbu_get:
okhttp_tongbu_get();
break;
//okhttp:同步post请求:需要开启线程做处理
case R.id.okhttp_tongbu_post:
okhttp_tongbu_post();
break;
//okhttp:异步get请求 不需要开线程
case R.id.okhttp_yibu_get:
okhttp_yibu_get();
break;
//okhttp:异步post请求 不需要开线程
case R.id.okhttp_yibu_post:
okhttp_yibu_post();
break;
//volley:get请求
case R.id.volley_get:
volley_get();
break;
//volley:post请求
case R.id.volley_post:
volley_post();
break;
//volley:图片
case R.id.volley_image:
volley_image();
break;
}
}
private void get() {
new Thread(new Runnable() {
@Override
public void run() {
URL url = null;
StringBuffer stringBuffer=new StringBuffer();
try {
url = new URL(get_str);
HttpURLConnection connection= (HttpURLConnection) url.openConnection();
connection.setReadTimeout(5000);
connection.setConnectTimeout(5000);
if(connection.getResponseCode()==200) {
InputStream inputStream = connection.getInputStream();
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) != -1) {
stringBuffer.append(new String(bytes, 0, len));
}
}
Message obtain = Message.obtain();
obtain.what=101;
obtain.obj=stringBuffer.toString();
handler.sendMessage(obtain);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private void post() {
new Thread(new Runnable() {
@Override
public void run() {
URL url = null;
StringBuffer stringBuffer=new StringBuffer();
try {
url = new URL(post_str);
HttpURLConnection connection= (HttpURLConnection) url.openConnection();
connection.setReadTimeout(5000);
connection.setConnectTimeout(5000);
//设置post请求
connection.setRequestMethod("POST");
//设置允许输入
connection.setDoInput(true);
//设置允许输出
connection.setDoOutput(true);
//获得输出流传递数据
OutputStream outputStream = connection.getOutputStream();
outputStream.write("username=ytx&password=123".getBytes());
outputStream.flush();
if(connection.getResponseCode()==200) {
InputStream inputStream = connection.getInputStream();
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) != -1) {
stringBuffer.append(new String(bytes, 0, len));
}
}
Message obtain = Message.obtain();
obtain.what=102;
obtain.obj=stringBuffer.toString();
handler.sendMessage(obtain);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private void okhttp_tongbu_get() {//需要开启子线程
new Thread(new Runnable() {
@Override
public void run() {
//TODO 1:创建OkHttpClient对象
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(5, TimeUnit.SECONDS);
builder.readTimeout(5,TimeUnit.SECONDS);
OkHttpClient client = builder.build();
//TODO 2:创建Request对象
Request.Builder request_builder = new Request.Builder();
request_builder.url(get_str);
Request request = request_builder.build();
//TODO 3:发起请求
Call call = client.newCall(request);
//TODO 4:得到response对象
Response response=null;
try {
response= call.execute();
} catch (IOException e) {
e.printStackTrace();
}
//TODO 5:获得响应体
String result=null;
try {
result = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
Message obtain = Message.obtain();
obtain.what=103;
obtain.obj=result;
handler.sendMessage(obtain);
}
}).start();
}
private void okhttp_tongbu_post() {//需要开启子线程
new Thread(new Runnable() {
@Override
public void run() {
//TODO 1:创建OkHttpClient对象
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(5, TimeUnit.SECONDS);
builder.readTimeout(5,TimeUnit.SECONDS);
OkHttpClient client = builder.build();
//TODO 2:创建Request对象
Request.Builder request_builder = new Request.Builder();
request_builder.url(post_str);
//设置post提交的参数
FormBody.Builder form_builder = new FormBody.Builder();
form_builder.add("username","ytx");
form_builder.add("password","123");
FormBody formBody = form_builder.build();
request_builder.post(formBody);
Request request = request_builder.build();
//TODO 3:发起请求
Call call = client.newCall(request);
//TODO 4:得到response对象
Response response=null;
try {
response= call.execute();
} catch (IOException e) {
e.printStackTrace();
}
//TODO 5:获得响应体
String result=null;
try {
result = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
Message obtain = Message.obtain();
obtain.what=104;
obtain.obj=result;
handler.sendMessage(obtain);
}
}).start();
}
private void okhttp_yibu_get() {//异步: 不需要开启子线程
//TODO 1:创建OkHttpClient对象
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(5, TimeUnit.SECONDS);
builder.readTimeout(5,TimeUnit.SECONDS);
OkHttpClient client = builder.build();
//TODO 2:创建Request对象
Request.Builder request_builder = new Request.Builder();
request_builder.url(get_str);
Request request = request_builder.build();
//TODO 3:发起请求
Call call = client.newCall(request);
//TODO 4:得到response对象
call.enqueue(new Callback(){
//失败,在子线程中
@Override
public void onFailure(Call call, IOException e) {
Message obtain = Message.obtain();
obtain.what=105;
obtain.obj="请求失败";
handler.sendMessage(obtain);
}
//成功在子线程中
@Override
public void onResponse(Call call, Response response) throws IOException {
String result =response.body().string();
Message obtain = Message.obtain();
obtain.what=105;
obtain.obj=result;
handler.sendMessage(obtain);
}
});
}
private void okhttp_yibu_post() {//异步:不需要开启子线程
//TODO 1:创建OkHttpClient对象
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(5, TimeUnit.SECONDS);
builder.readTimeout(5,TimeUnit.SECONDS);
OkHttpClient client = builder.build();
//TODO 2:创建Request对象
Request.Builder request_builder = new Request.Builder();
request_builder.url(post_str);
//设置post提交的参数
FormBody.Builder form_builder = new FormBody.Builder();
form_builder.add("username","ytx");
form_builder.add("password","123");
FormBody formBody = form_builder.build();
request_builder.post(formBody);
final Request request = request_builder.build();
//TODO 3:发起请求
Call call = client.newCall(request);
//TODO 4:得到response对象
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Message obtain = Message.obtain();
obtain.what=106;
obtain.obj="请求失败";
handler.sendMessage(obtain);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String result=response.body().string();
Message obtain = Message.obtain();
obtain.what=106;
obtain.obj=result;
handler.sendMessage(obtain);
}
});
}
private void volley_image() {
//参数一:网址 参数二:response监听器 参数三:图片最大宽度 参数四:图片最大高度 参数五:图片的格式 参数六:错误监听器
ImageRequest imageRequest = new ImageRequest(image_url, new com.android.volley.Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
imageView.setImageBitmap(response);
}
}, 500, 500, Bitmap.Config.RGB_565, new com.android.volley.Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(HttpUrlConnectionActivity.this, "失败", Toast.LENGTH_SHORT).show();
}
});
requestQueue.add(imageRequest);
}
private void volley_post() {
//StringRequest 网络请求返回字符串
//参数一:请求方式 参数二:网址 参数三:response监听器 参数四:错误监听器
StringRequest stringRequest = new StringRequest(StringRequest.Method.POST, post_str, new com.android.volley.Response.Listener<String>() {
@Override
public void onResponse(String response) {
Toast.makeText(HttpUrlConnectionActivity.this, ""+response, Toast.LENGTH_SHORT).show();
}
}, new com.android.volley.Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(HttpUrlConnectionActivity.this, ""+error.getMessage(), Toast.LENGTH_SHORT).show();
}
}){//重写getParams方法,设置请求参数
@Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> map=new HashMap<>();
map.put("username","ytx");
map.put("password","123");
return map;
}
};
//添加到队列中
requestQueue.add(stringRequest);
}
private void volley_get(){
//StringRequest 网络请求返回字符串
//参数一:请求方式 参数二:网址 参数三:response监听器 参数四:错误监听器
StringRequest stringRequest = new StringRequest(StringRequest.Method.GET, get_str, new com.android.volley.Response.Listener<String>() {
@Override
public void onResponse(String response) {
Toast.makeText(HttpUrlConnectionActivity.this, ""+response, Toast.LENGTH_SHORT).show();
}
}, new com.android.volley.Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(HttpUrlConnectionActivity.this, ""+error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
//添加到队列中
requestQueue.add(stringRequest);
}
}