博主前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住也分享一下给大家,
点击跳转到网站
前言: 在过去,Android上发送HTTP请求一般有两种方式:HttpURLConnection和HttpClient,由于HttpClient存在的API数量过多,扩展困难等缺点,在Android6.0系统中,HttpClient的功能被完全移除了。
而 OkHttp 是由Square公司开发的,OkHttp在接口封装上做的简单易用,比起原生的HttpURLConnection,可以说是有过之而无不及,现在已经成为了广大Android开发者首选的网络通信库。
使用HttpURLConnection进行网络请求详解请看这篇文章
同步请求与异步请求的概念:
简单地说,同步就是发出一个请求后什么事都不做,一直等待请求返回后才会继续做事;异步就是发出请求后继续去做其他事,这个请求处理完成后会通知你,这时候就可以处理这个回应了。
写了个Demo去理解Okhttp中的get同步请求与异步请求,和post同步请求与异步请求
1.get的同步请求,其中的讲解,已经在代码中注释了出来。
//get同步请求
public void getSync(View view) {
//在Android 中完成网络请求必须在子线程中完成
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url("http://www.httpbin.org/get?a=1&b=2").build();
//准备好请求的Code对象
Call call = okHttpClient.newCall(request);
try {
//同步请求要创建子线程,是因为execute()方法,会阻塞后面代码的执行
//只有执行了execute方法之后,得到了服务器的响应response之后,才会执行后面的代码
//所以同步请求要在子线程中完成
Response response = call.execute();
//把服务器给我们响应的字符串数据打印出来
Log.i(TAG,"getSync:"+response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
2.get异步请求:
//get的异步请求
public void getAsync(View view) {
//定义okhttp对象
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url("http://www.httpbin.org/get?a=1&b=2").build();
Call call = okHttpClient.newCall(request);
//异步请求:不用创建子线程
//enqueue()并不会阻塞代码的执行,不需要与服务器请求完成之后,才会执行后面的代码
//而且enqueue内部会为我们创建子线程
call.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 {
Log.i("TAG", "onResponse: " + (Looper.getMainLooper().getThread() == Thread.currentThread()));//为false 表示这是在子线程,需要切换到主线程才能操作UI
if (response.isSuccessful()){
Log.i(TAG,"getAsync:"+response.body().string());
}
}
});
}
3.post同步请求:
//post同步请求
public void postSync(View view) {
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient okHttpClient = new OkHttpClient();
//post请求规定,把参数放在请求体里面,用form表单的方式来添加我们的请求体
FormBody formBody = new FormBody.Builder().add("a", "10000").add("b", "15000").build();
Request request = new Request.Builder().url("http://www.httpbin.org/post")
.post(formBody)
.build();
Call call = okHttpClient.newCall(request);
try {
Response response = call.execute();
Log.i(TAG,"postSync:"+response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
4.post的异步请求:
//post异步请求
public void postAsync(View view) {
OkHttpClient okHttpClient = new OkHttpClient();
FormBody formBody = new FormBody.Builder().add("a", "1000").add("b", "2000").build();
Request request = new Request.Builder().url("http://www.httpbin.org/post")
.post(formBody)
.build();
Call call = okHttpClient.newCall(request);
call.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 {
Log.i("TAG", "onResponse: " + (Looper.getMainLooper().getThread() == Thread.currentThread()));//为false 表示这是在子线程,需要切换到主线程才能操作UI
if (response.isSuccessful()){
Log.i(TAG,"postAsync:"+response.body().string());
}
}
});
}
上面用到的http服务器是公用的,需要的拿去用:地址www.httpbin.org/
新增:
一、 使用OkHttp 上传图片到服务器
private void UpLoadImage(String pictPath, String fileName) { //参数1:图片路径 参数2:图片名称
new Thread(new Runnable() {
@Override
public void run() {
String url = "具体的URL地址";
//定义OkHttp
OkHttpClient okHttpClient = new OkHttpClient();
MediaType JSON = MediaType.parse("multipart/form-data");
//定义请求体
RequestBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", fileName,
RequestBody.create(JSON, new File(pictPath)))//addFormDataPart方法的第一个参数是key值,第二个参数是上传文件的名字,第三个参数是需要上传的文件
.build();
try {
//执行OkHttp
Request request = new Request.Builder()
.post(body)
.url(url)
.build();
Response response = okHttpClient.newCall(request).execute();
String ss = response.body().string();
ResultMsg resultMsg = new Gson().fromJson(ss, ResultMsg.class);
if (resultMsg.Result.equals("1")) {
Looper.prepare();
Toast.makeText(ChangeInformationActivity.this, "图片上传成功!", Toast.LENGTH_SHORT).show();
Looper.loop();
} else {
Looper.prepare();
Toast.makeText(ChangeInformationActivity.this, resultMsg.Message, Toast.LENGTH_SHORT).show();
Looper.loop();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
二、 使用OkHttp 通过GET异步请求从服务器获取图片,下载到手机图库中,代码如下:
btn_save_image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//申请读取或修改存储卡的权限
//对于共享区间写入的权限,在API29 Android系统10之前是需要申请的
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
if (ContextCompat.checkSelfPermission(OkHttpActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(OkHttpActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
} else {
SaveImage();
}
} else {
SaveImage();
}
}
});
SaveImage()方法实现从服务器下载一张图片,保存到图库中的功能:
//定义OkHttp
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url("https://cdn.pixabay.com/photo/2021/12/13/15/14/flowers-6868494_960_720.jpg")
.build();
Call call = okHttpClient.newCall(request);
//进行GET的异步请求
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) { //没有网络的情况下,会回调这个方法
Log.e(TAG, "onFailure: " + "失败");
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
//当前就是子线程所以不用再开启子线程了
InputStream inputStream = response.body().byteStream();
//之后包装成处理流,提高流的读取
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
BufferedOutputStream bufferedOutputStream = null;
try {
//保存到图库的URI
Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());
OutputStream outputStream = getContentResolver().openOutputStream(uri);
bufferedOutputStream = new BufferedOutputStream(outputStream);
//定义每次读取的字节数
byte[] buffer = new byte[1024 * 8];
int len;
int length = 0;
while ((len = bufferedInputStream.read(buffer)) != -1) {
bufferedOutputStream.write(buffer, 0, len);
length += len;
}
Log.i(TAG, "length: " + length);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedOutputStream != null) {
bufferedOutputStream.close();
}
if (bufferedInputStream != null) {
bufferedInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
以上就是Okhttp框架的简单实用~,如有不当之处,还望各位网友加以指正!