# PdNetwork **Repository Path**: gzlpsdp/pd-network ## Basic Information - **Project Name**: PdNetwork - **Description**: 自定义封装okhttp网络请求 - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-11-27 - **Last Updated**: 2025-12-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## Pd网络请求库使用文档 [![](https://jitpack.io/v/com.gitee.gzlpsdp/pd-network.svg)](https://jitpack.io/#com.gitee.gzlpsdp/pd-network) ## 概述 这是一个基于 OkHttp 封装的 Android 网络请求库,支持同步/异步请求、文件上传下载、Token 管理、进度回调等功能。 ## 配置示例 ```java public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); // 基础配置 HttpConfig config = new HttpConfig.Builder("11") .setConnectTimeout(2000) // 连接超时 2秒 .setReadTimeout(30000) // 读取超时 30秒 .setWriteTimeout(30000) // 写入超时 30秒 .setEnableLog(false) // 调试模式开启日志 .setAutoAddToken(true) // 开启自动 Token 管理 .setTokenHeaderName("Authorization") // Token 头部名称 .setTokenPrefix("") // Token 前缀 // 新增:添加统一请求头 .addCommonHeader("client", "app") // 公共请求头,会被动态请求头覆盖 .addCommonHeader("version", "1.0.0") // 版本号 .addCommonHeader("platform", "android") // 平台标识 .addCommonHeader("Content-Type", "application/json") // 默认Content-Type // 静态请求头(优先级最高,不会被覆盖) .addStaticHeader("X-App-ID", "your-app-id") .addStaticHeader("X-Request-Source", "mobile-app") .build(); // 初始化网络库(带 Context 支持 Token 持久化) HttpManager.init(this, config); // 或者你可以在初始化后动态添加请求头 HttpManager.getInstance().addCommonHeader("app-channel", "official"); HttpManager.getInstance().addStaticHeader("X-Device-ID", getDeviceId()); } private String getDeviceId() { // 获取设备ID的逻辑 return "device-id-123456"; } } ``` ## 使用示例 ```java // 1. 普通GET请求(会自动带上配置的统一请求头) HttpManager.getInstance().getAsync("user/info", null, UserInfo.class, new HttpCallback() { @Override public void onSuccess(UserInfo data) { // 处理成功 } @Override public void onError(int code, String message) { // 处理错误 } @Override public void onFailure(IOException e) { // 处理网络异常 } }, "user_info_request"); // 2. 带自定义headers的请求(会与配置的统一请求头合并) Map customHeaders = new HashMap<>(); customHeaders.put("X-Custom-Header", "custom-value"); customHeaders.put("Accept-Language", "zh-CN"); HttpManager.getInstance().getAsync("api/data", null, customHeaders, DataResponse.class, new HttpCallback() { @Override public void onSuccess(DataResponse data) { // 处理成功 } @Override public void onError(int code, String message) { // 处理错误 } @Override public void onFailure(IOException e) { // 处理网络异常 } }, "data_request", true); // 3. 动态修改请求头 // 添加新的公共请求头 HttpManager.getInstance().addCommonHeader("api-version", "v2"); // 添加静态请求头(优先级最高) HttpManager.getInstance().addStaticHeader("X-Session-ID", "session-123"); // 移除请求头 HttpManager.getInstance().removeCommonHeader("client"); // 4. 文件上传(也会带上统一请求头) File imageFile = new File("/path/to/image.jpg"); HttpManager.getInstance().uploadFile("upload/image", imageFile, "image", null, UploadResponse.class, new ProgressCallback() { @Override public void onSuccess(UploadResponse data) { // 上传成功 } @Override public void onProgress(long bytesWritten, long contentLength, float progress) { // 更新上传进度 Log.d("Upload", "进度: " + (progress * 100) + "%"); } @Override public void onError(int code, String message) { // 上传错误 } @Override public void onFailure(IOException e) { // 网络异常 } }, "upload_request"); ``` ## 快速开始 **1. 添加依赖** 在项目的 build.gradle 中添加: ```gradle dependencies { implementation 'com.gitee.gzlpsdp:pd-network:版本号' } ``` **2. 初始化** 在 Application 类中初始化网络库: ```java public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); // 基础配置 HttpConfig config = new HttpConfig.Builder("https://api.example.com/") .setConnectTimeout(10000) // 连接超时 10秒 .setReadTimeout(15000) // 读取超时 15秒 .setWriteTimeout(15000) // 写入超时 15秒 .setEnableLog(BuildConfig.DEBUG) // 调试模式开启日志 .setAutoAddToken(true) // 开启自动 Token 管理 .setTokenHeaderName("Authorization") // Token 头部名称 .setTokenPrefix("Bearer ") // Token 前缀 .build(); // 初始化网络库(带 Context 支持 Token 持久化) HttpManager.init(this, config); } } ``` ## 基础请求 ### GET 请求 **异步 GET 请求(不带参数)** ```java HttpManager.getInstance().getAsync("/api/users", UserList.class, new HttpCallback() { @Override public void onSuccess(UserList result) { // 请求成功,处理数据 updateUI(result); } @Override public void onError(int code, String message) { // 服务器返回错误 showError("错误码: " + code + ", 信息: " + message); } @Override public void onFailure(Throwable throwable) { // 网络异常 showError("网络请求失败: " + throwable.getMessage()); } }, "get_users"); ``` **异步 GET 请求(带参数)** ```java Map params = new HashMap<>(); params.put("page", "1"); params.put("limit", "20"); params.put("keyword", "搜索关键词"); HttpManager.getInstance().getAsync("/api/search", params, SearchResult.class, new HttpCallback() { @Override public void onSuccess(SearchResult result) { // 处理搜索结果 displaySearchResults(result); } @Override public void onError(int code, String message) { showError("搜索失败: " + message); } @Override public void onFailure(Throwable throwable) { showError("网络异常: " + throwable.getMessage()); } }, "search_request"); ``` **同步 GET 请求** ```java // 注意:同步请求需要在子线程中执行 new Thread(() -> { HttpResponse response = HttpManager.getInstance().getSync("/api/user/123", User.class); if (response.isSuccess()) { User user = response.getData(); // 切换到主线程更新 UI runOnUiThread(() -> updateUserInfo(user)); } else { runOnUiThread(() -> showError(response.getMessage())); } }).start(); ``` ### POST 请求 **表单 POST 请求** ```java Map params = new HashMap<>(); params.put("username", "user@example.com"); params.put("password", "password123"); HttpManager.getInstance().postAsync("/api/login", params, LoginResponse.class, new HttpCallback() { @Override public void onSuccess(LoginResponse result) { // 登录成功,保存 Token if (result.getToken() != null) { HttpManager.getInstance().setToken(result.getToken()); } navigateToHome(); } @Override public void onError(int code, String message) { showError("登录失败: " + message); } @Override public void onFailure(Throwable throwable) { showError("网络异常: " + throwable.getMessage()); } }, "login_request"); ``` **JSON POST 请求** ```java String json = "{\"title\":\"文章标题\",\"content\":\"文章内容\",\"tags\":[\技术\",\"Android\"]}"; HttpManager.getInstance().postAsync("/api/articles", json, Article.class, new HttpCallback
() { @Override public void onSuccess(Article result) { showSuccess("文章发布成功"); refreshArticleList(); } @Override public void onError(int code, String message) { showError("发布失败: " + message); } @Override public void onFailure(Throwable throwable) { showError("网络异常: " + throwable.getMessage()); } }, "create_article"); ``` ### Token 管理 **设置 Token** ```java // 登录成功后设置 Token HttpManager.getInstance().setToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."); // 设置自定义 Token 类型 HttpManager.getInstance().setToken("token_value", "Custom"); ``` **清除 Token** ```java // 退出登录时清除 Token HttpManager.getInstance().clearToken(); ``` **获取当前 Token** ```java String token = HttpManager.getInstance().getToken(); ``` **Token 控制** **需要 Token 的请求(默认自动添加)** ```java // 获取用户信息 - 会自动添加 Token HttpManager.getInstance().getAsync("/api/user/profile", UserProfile.class, new HttpCallback() { @Override public void onSuccess(UserProfile result) { displayUserProfile(result); } @Override public void onError(int code, String message) { if (code == 401) { // Token 过期,跳转到登录页 handleTokenExpired(); } else { showError(message); } } @Override public void onFailure(Throwable throwable) { showError("网络异常"); } }, "get_profile"); ``` **不需要 Token 的请求(明确指定)** ```java // 公开接口 - 明确不添加 Token HttpManager.getInstance().getAsync("/api/public/news", null, NewsList.class, new HttpCallback() { @Override public void onSuccess(NewsList result) { displayNews(result); } @Override public void onError(int code, String message) { showError("加载失败: " + message); } @Override public void onFailure(Throwable throwable) { showError("网络异常"); } }, "get_news", false); // 最后一个参数 false 表示不添加 Token ``` ### 文件操作 **文件上传** ```java File imageFile = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "photo.jpg"); Map params = new HashMap<>(); params.put("description", "用户头像"); params.put("category", "avatar"); HttpManager.getInstance().uploadFile("/api/upload", imageFile, "file", params, UploadResult.class, new ProgressCallback() { @Override public void onProgress(long currentBytes, long totalBytes, float progress) { // 更新上传进度 progressBar.setProgress((int) (progress * 100)); progressText.setText(String.format("上传中 %.1f%%", progress * 100)); } @Override public void onSuccess(UploadResult result) { progressBar.setProgress(100); showSuccess("上传成功: " + result.getFileUrl()); } @Override public void onError(int code, String message) { showError("上传失败: " + message); } @Override public void onFailure(Throwable throwable) { showError("上传异常: " + throwable.getMessage()); } }, "upload_avatar"); ``` **多文件上传** ```java // 如果需要上传多个文件,可以循环调用上传方法 List files = getSelectedFiles(); for (int i = 0; i < files.size(); i++) { File file = files.get(i); Map params = new HashMap<>(); params.put("index", String.valueOf(i)); HttpManager.getInstance().uploadFile("/api/upload", file, "files", params, UploadResult.class, new ProgressCallback() { // ... 进度回调 }, "upload_file_" + i); } ``` **文件下载** ```java String fileUrl = "https://example.com/files/document.pdf"; String savePath = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "document.pdf").getAbsolutePath(); HttpManager.getInstance().downloadFile(fileUrl, savePath, new ProgressCallback() { @Override public void onProgress(long currentBytes, long totalBytes, float progress) { // 更新下载进度 progressBar.setProgress((int) (progress * 100)); progressText.setText(String.format("下载中 %.1f%%", progress * 100)); } @Override public void onSuccess(File result) { progressBar.setProgress(100); showSuccess("下载完成: " + result.getAbsolutePath()); openFile(result); } @Override public void onError(int code, String message) { showError("下载失败: " + message); } @Override public void onFailure(Throwable throwable) { showError("下载异常: " + throwable.getMessage()); } }, "download_file"); ``` ## 高级功能 **自定义 Token 处理** ```java public class CustomTokenInterceptor implements TokenInterceptor { @Override public Request addToken(Request request, String token) { // 自定义 Token 添加逻辑 return request.newBuilder() .addHeader("Authorization", "Custom " + token) .addHeader("X-Device-ID", getDeviceId()) .addHeader("X-App-Version", getAppVersion()) .build(); } @Override public boolean shouldAddToken(Request request) { // 自定义 Token 添加判断逻辑 String url = request.url().toString(); // 为所有非公开接口添加 Token return !url.contains("/public/") && !url.contains("/auth/login") && !url.contains("/auth/register"); } @Override public void onTokenExpired() { // Token 过期处理 runOnUiThread(() -> { // 显示重新登录对话框 showReLoginDialog(); }); } private String getDeviceId() { return Settings.Secure.getString( getContentResolver(), Settings.Secure.ANDROID_ID ); } private String getAppVersion() { try { PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0); return pInfo.versionName; } catch (PackageManager.NameNotFoundException e) { return "unknown"; } } } // 设置自定义 Token 拦截器 HttpManager.getInstance().setTokenInterceptor(new CustomTokenInterceptor()); ``` **请求取消管理** ```java public class MainActivity extends AppCompatActivity { private static final String TAG_PROFILE = "get_profile"; private static final String TAG_UPLOAD = "upload_file"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 发起请求时指定标签 loadUserProfile(); uploadUserFile(); } private void loadUserProfile() { HttpManager.getInstance().getAsync("/api/user/profile", UserProfile.class, new HttpCallback() { // ... 回调方法 }, TAG_PROFILE); } private void uploadUserFile() { // 文件上传请求 HttpManager.getInstance().uploadFile("/api/upload", file, "file", null, UploadResult.class, new ProgressCallback() { // ... 回调方法 }, TAG_UPLOAD); } @Override protected void onStop() { super.onStop(); // 取消特定请求 HttpManager.getInstance().cancelRequest(TAG_PROFILE); } @Override protected void onDestroy() { super.onDestroy(); // 取消所有请求 HttpManager.getInstance().cancelAllRequests(); } } ``` **错误处理最佳实践** ```java public class NetworkUtils { public static void handleNetworkError(int code, String message, Throwable throwable) { if (throwable != null) { // 网络异常 if (throwable instanceof SocketTimeoutException) { showToast("网络连接超时,请重试"); } else if (throwable instanceof ConnectException) { showToast("网络连接失败,请检查网络设置"); } else { showToast("网络异常: " + throwable.getMessage()); } return; } // 服务器返回错误 switch (code) { case 400: showToast("请求参数错误"); break; case 401: showToast("登录已过期,请重新登录"); navigateToLogin(); break; case 403: showToast("没有访问权限"); break; case 404: showToast("请求的资源不存在"); break; case 500: showToast("服务器内部错误"); break; case 503: showToast("服务暂时不可用"); break; default: showToast("错误码: " + code + ", 信息: " + message); break; } } } // 使用示例 HttpManager.getInstance().getAsync("/api/data", Data.class, new HttpCallback() { @Override public void onSuccess(Data result) { // 处理成功 } @Override public void onError(int code, String message) { NetworkUtils.handleNetworkError(code, message, null); } @Override public void onFailure(Throwable throwable) { NetworkUtils.handleNetworkError(0, null, throwable); } }, "get_data"); ``` ## 配置选项 **HttpConfig 配置参数** | 参数 | 类型 | 默认值 | 说明 | |:-------:|:--------:|:----------:|:---------:| | baseUrl | String | 无 | 基础URL | | connectTimeout | long | 15000 | 连接超时(毫秒)| |readTimeout | long | 15000| 读取超时(毫秒)| |writeTimeout| long| 15000| 写入超时(毫秒)| |retryOnConnectionFailure| boolean| true| 是否重试连接失败| |enableLog| boolean| true| 是否启用日志| |autoAddToken| boolean |true| 是否自动添加| Token| |tokenHeaderName| String| "Authorization"| Token 头部名称| |tokenPrefix| String| "Bearer "| Token 前缀| ## 注意事项 权限要求:确保在 AndroidManifest.xml 中添加网络权限 ```xml ``` 主线程限制:同步请求必须在子线程中执行 内存泄漏:在 Activity/Fragment 销毁时取消相关请求 Token 安全:Token 会自动保存到 SharedPreferences,确保应用安全 进度回调:进度回调会在主线程执行,可以直接更新 UI ## 常见问题 **Q: 如何修改超时时间?** A: 在初始化时配置: ```java new HttpConfig.Builder("https://api.example.com/") .setConnectTimeout(30000) .setReadTimeout(30000) .setWriteTimeout(30000) .build(); ``` **Q: 如何禁用自动 Token 添加?** A: 在配置中设置: ```java .setAutoAddToken(false) ``` **Q: 如何处理 Token 过期?** A: 实现 TokenInterceptor 的 onTokenExpired 方法: ```java @Override public void onTokenExpired() { // 刷新 Token 或跳转到登录页 } ``` **Q: 如何添加公共请求头?** A: 使用自定义 Token 拦截器: ```java @Override public Request addToken(Request request, String token) { return request.newBuilder() .addHeader("Authorization", "Bearer " + token) .addHeader("X-Platform", "Android") .addHeader("X-App-Version", BuildConfig.VERSION_NAME) .build(); } ```