目录
版本:Android Studio 2024.1.1
SDK:34
一、添加HTTP依赖库
在app->build.gradle 添加okhttp依赖库
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
如下所示:
plugins {
alias(libs.plugins.android.application)
}
android {
namespace 'com.example.mytest'
compileSdk 34
defaultConfig {
applicationId "com.example.mytest"
minSdk 25
targetSdk 34
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
//HTTP客户端库
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
implementation libs.appcompat
implementation libs.material
implementation libs.activity
implementation libs.constraintlayout
testImplementation libs.junit
androidTestImplementation libs.ext.junit
androidTestImplementation libs.espresso.core
}
二、添加权限
在app->src->main->AndroidManifest.xml添加网络权限
<!-- 网络权限-->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 网络状态权限-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 保持唤醒状态-->
<uses-permission android:name="android.permission.WAKE_LOCK" />
如下所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- 网络权限-->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 网络状态权限-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 保持唤醒状态-->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyTest"
tools:targetApi="31">
<activity
android:name=".utils.ToastUtil"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 开启MQTT服务-->
<service android:name="org.eclipse.paho.android.service.MqttService" />
</application>
</manifest>
三、封装工具类
源码:
package com.example.mytest;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import okhttp3.*;
public class HttpUtils {
private static final String TAG = "HttpUtils";
private static HttpUtils instance;
private OkHttpClient client;
private HttpUtils() {
client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
}
public static HttpUtils getInstance() {
if(instance == null){
synchronized (HttpUtils.class){
if(instance == null){
instance = new HttpUtils();
}
}
}
return instance;
}
//GET请求
public void get(String url) {
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 处理请求失败
Log.e("HTTP Request", "Error: ", e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
// 获取响应体
// 注意:response.body().string() 只能调用一次 因为是流数据
String responseData = response.body().string();
Log.d("HTTP Request", "Response Code: " + responseData);
// 处理响应数据
} else {
// 处理错误响应
Log.e("HTTP Request", "Response Code: " + response.code());
}
}
});
}
// POST 请求
public void post(String url, String json) {
RequestBody body = RequestBody.create(json,MediaType.parse("application/json; charset=utf-8"));
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 处理请求失败
Log.e("HTTP Request", "Error: ", e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
// 获取响应体
String responseData = response.body().string();
Log.d("HTTP Request", "Response Code: " + responseData);
// 处理响应数据
} else {
// 处理错误响应
Log.e("HTTP Request", "Response Code: " + response.code());
}
}
});
}
//文件下载
public void downloadFile(String url, String savePath) {
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("HTTP Request", "Error: ", e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
// 获取响应体
InputStream inputStream = response.body().byteStream();
//提取url中的文件名,用于创建文件
int lastIndex = url.lastIndexOf('/');
String fileName = url.substring(lastIndex + 1);
// 创建输出流,try可以自动回收资源,避免资源泄漏
try (FileOutputStream outputStream = new FileOutputStream(savePath + fileName)) {
byte[] buffer = new byte[4096]; // 缓冲区大小
int count;
while ((count = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, count);
}
// 文件下载完成
Log.d("HTTP Request", "File downloaded successfully to: " + savePath + fileName);
}
} else {
// 处理错误响应
Log.e("HTTP Request", "Response Code: " + response.code());
}
}
});
}
// 文件上传
public void uploadFile(String url, File file) {
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(), RequestBody.create(file,MediaType.parse("application/octet-stream")))
.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("HTTP Request", "Error: ", e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
// 获取响应体
String responseData = response.body().string();
Log.d("HTTP Request", "Response Code: " + responseData);
// 处理响应数据
} else {
// 处理错误响应
Log.e("HTTP Request", "Response Code: " + response.code());
}
}
});
}
}
四、使用HTTP工具类(直接调用)
1.GET请求
HttpUtils.getInstance().get("http://192.168.1.16:8090");
2.POST请求
HttpUtils.getInstance().post("http://192.168.1.16:8090","{\"test\":\"123\"}");
3.文件下载
HttpUtils.getInstance().downloadFile("https://files.cnblogs.com/files/xiaochina/hfs汉化.rar","/data/data/com.example.mytest/files/");
4.文件上传
HttpUtils.getInstance().uploadFile("http://192.168.1.16:8090",file);
文件操作(测试)拓展:
//文件创建
//应用私有文件操作方式,适用于小文件测试
FileOutputStream fos = openFileOutput("test.txt",MODE_PRIVATE);
fos.write("hellow world".getBytes()); //字符串转字节数组写入文件
fos.close();Toast.makeText(this,"写入成功",Toast.LENGTH_LONG).show();
//文件读取
FileInputStream fis = openFileInput("test.txt");
byte[] bytes = new byte[fis.available()]; //创建一个和文件大小相同的字节数组
fis.read(bytes);
fis.close();Toast.makeText(this,new String(bytes),Toast.LENGTH_LONG).show();
//文件上传
//私有文件路径:/data/data/包名/files/文件名
//打开View---Tool Windows---Device Explorer可查看设备文件,默认关闭
File file = new File("/data/data/com.example.mytest/files/test.txt");
HttpUtils.getInstance().uploadFile("http://192.168.1.16:8090",file);