Android 可扩展的网络请求框架

网络框架设计

搭建一个通用的、扩展性好、解耦合的网络框架需要一些设计和技术策略。以下是一些步骤和建议,可以帮助您构建一个高质量的网络框架:

  1. 明确需求: 在开始之前,明确您的项目需求和目标。考虑您需要支持哪些网络协议(如 HTTP、WebSocket)、数据格式(如 JSON、XML)、认证方式等。这有助于定义框架的范围和功能。

  2. 分层架构: 采用分层架构可以帮助您将不同功能模块分离开来,实现解耦合。常见的分层包括网络层、数据层、业务逻辑层和界面层。每个层次应该有明确的职责,不应互相混杂。

  3. 接口和抽象: 使用接口和抽象类定义公共的网络操作和回调方法。这有助于封装通用功能,并使不同部分之间的交互更加灵活。例如,定义一个 NetworkClient 接口,包含发送请求和处理响应的方法。

  4. 可扩展的配置: 设计一个可扩展的配置机制,允许应用在不同场景下进行定制。这可以通过配置文件、注入依赖或者反射机制来实现。

  5. 错误处理和回退机制: 考虑如何处理网络请求中可能发生的错误,包括网络连接问题、超时、服务端返回错误等。实现合适的错误处理和回退机制,以确保用户体验。

  6. 请求和响应封装: 封装请求和响应模型,将它们映射到适当的数据结构。这可以帮助您处理数据解析、序列化和转换的逻辑。

  7. 线程管理: 为了避免主线程被阻塞,将网络请求放在后台线程执行,同时确保在需要时切换回主线程更新 UI。您可以使用 AsyncTask、Handler、线程池等方法来实现线程管理。

  8. 缓存机制: 实现缓存机制可以减少重复请求,提高性能。可以根据请求的数据类型和更新频率选择合适的缓存策略,例如内存缓存、磁盘缓存等。

  9. 拦截器和中间件: 使用拦截器或中间件来实现一些通用的操作,例如添加请求头、记录请求日志、身份认证等。这有助于将一些通用逻辑从具体的请求中抽象出来。

  10. 依赖注入: 考虑使用依赖注入框架,如 Dagger 或 Hilt,来管理网络框架中的依赖关系。这可以提高代码的可测试性和可维护性。

  11. 单元测试和集成测试: 编写单元测试和集成测试来确保网络框架的正确性和稳定性。模拟各种网络情况和响应,测试不同场景下的行为。

  12. 文档和示例: 编写清晰的文档和示例,帮助其他开发人员理解和使用您的网络框架。

  13. 持续改进: 定期审查和改进网络框架,根据项目需求和反馈进行优化和升级。

搭建一个通用、扩展性好、解耦合的网络框架需要一定的时间和精力,但可以为您的项目带来许多好处。根据项目的实际情况,您可以根据上述建议进行定制和调整。

网络请求框架示例

搭建一个可扩展的网络请求框架需要考虑多个方面,包括但不限于代码组织、错误处理、可测试性和可扩展性。

当你的应用需要处理多种API请求和复杂的网络逻辑时,构建一个可扩展、易维护的网络请求框架是至关重要的。以下是一个更详细的例子,使用Retrofit和OkHttp作为基础,展示如何构建这样一个框架。

1. 引入依赖

build.gradle中添加所需依赖。

implementation 'com.squareup.retrofit2:retrofit:2.x.x'
implementation 'com.squareup.retrofit2:converter-gson:2.x.x'
implementation 'com.squareup.okhttp3:okhttp:4.x.x'

2. 定义公共接口和实体类

创建一个ApiService接口,定义所有的API调用。

public interface ApiService {
    @GET("users/{user}/repos")
    Call<List<Repo>> listRepos(@Path("user") String user);

    @POST("users/new")
    Call<User> createUser(@Body User user);

    @PUT("users/{user}/update")
    Call<User> updateUser(@Path("user") String user, @Body User updatedUser);

    // ...其他API调用
}

定义相应的数据模型。

public class Repo {
    public String name;
    // ...其他字段
}

public class User {
    public String username;
    public String email;
    // ...其他字段
}

3. 创建OkHttpClient

定义一个类用于创建定制的OkHttpClient,用于添加统一的Header、拦截器等。

public class CustomOkHttpClient {
    public static OkHttpClient create() {
        return new OkHttpClient.Builder()
            .addInterceptor(chain -> {
                Request request = chain.request().newBuilder()
                    .addHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN")
                    .build();
                return chain.proceed(request);
            })
            .build();
    }
}

4. 构建网络请求管理类

在这个类里,我们初始化Retrofit实例,并提供获取API接口实例的方法。

public class NetworkManager {
    private static Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.example.com/")
        .client(CustomOkHttpClient.create())
        .addConverterFactory(GsonConverterFactory.create())
        .build();

    public static ApiService getApiService() {
        return retrofit.create(ApiService.class);
    }
}

5. 错误处理和数据解析

创建一个工具类或方法,用于统一的错误处理和数据解析。

public class ErrorHandler {
    public static void handle(Callback callback, Throwable e) {
        // 统一处理错误,例如日志记录、显示错误消息等
        callback.onError(e);
    }
}

6. 业务逻辑封装

对业务逻辑进行封装,使其与网络请求解耦。

public class RepoManager {
    public interface RepoCallback {
        void onSuccess(List<Repo> repos);
        void onError(Throwable e);
    }

    public void fetchRepos(String user, RepoCallback callback) {
        NetworkManager.getApiService().listRepos(user).enqueue(new Callback<List<Repo>>() {
            @Override
            public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
                if (response.isSuccessful()) {
                    callback.onSuccess(response.body());
                } else {
                    // 处理API返回的错误
                    ErrorHandler.handle(callback, new Exception("API error"));
                }
            }

            @Override
            public void onFailure(Call<List<Repo>> call, Throwable t) {
                ErrorHandler.handle(callback, t);
            }
        });
    }
}

7. 单元测试和集成测试

  • 为以上各个部分编写单元测试和集成测试。

8. 添加文档

  • 编写有关如何使用这个框架的文档。

通过这样的组织结构,你可以容易地扩展你的网络请求框架,比如添加缓存机制、增加新的API请求等。这种结构也使得单元测试和集成测试变得更容易。

通过这种方式,你可以非常容易地扩展和维护你的网络请求框架。如果你需要添加新的API请求,只需在ApiService接口中添加新的方法,并在相应的业务逻辑类中调用它。这样做还有助于单元测试,因为你可以方便地模拟ApiService接口或其他组件进行测试。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
一个Android基于快速开发的一个框架 xUtils 它是在aFinal基础上进行重构和扩展框架 相比aFinal有很大的改善 同时 如果如果你的应用是基于网络的 那么只要处理得当 它会让你彻底的摆脱各种工具类和重复代码的困扰 xUtils 包含了很多实用的android工具 xUtils 源于Afinal框架 对Afinal进行了大量重构 使得xUtils支持大文件上传 更全面的http请求协议支持 拥有更加灵活的ORM 更多的事件注解支持且不受混淆影响 xUtils的四大组件: 一 ViewUtils 你受够了重复冗长的findViewById了嘛 你受够了各种监听事件的绑定了嘛 在这里 你只需要一句注解 如@ViewInject @OnClick 就能轻松摆脱小白似的代码 大大的上了一个档次 二 HttpUtils 支持的HTTP七种请求方式 非常便捷的满足你的接口请求的需要 同时还支持大文件上传下载 以及同步异步请求 三 BitmapUtils 你的程序因OOM强制关闭过嘛 你在为加在网络图片头疼嘛 有了组件 你将永久摆脱前面的问题 四 DbUtils 简单易用又出色的ORM框架 真的是谁用谁知道 直接轻松存储各种对象到sqlite数据库中 同时也能非常方便的进行各种条件查询 甚至分页查询 还有对表中数据的更新删除等操作 真正的实现 一行代码就可以进行增删改查 并且可通过注解自定义表名 列名 外键 唯一性约束 NOT NULL约束 CHECK约束等 支持事务 摘自github ">一个Android基于快速开发的一个框架 xUtils 它是在aFinal基础上进行重构和扩展框架 相比aFinal有很大的改善 同时 如果如果你的应用是基于网络的 那么只要处理得当 它会让你彻底的摆脱各种工具类和重复代码的困扰 [更多]
1、volley 项目地址 https://github.com/smanikandan14/Volley-demo (1) JSON,图像等的异步下载; (2) 网络请求的排序(scheduling) (3) 网络请求的优先级处理 (4) 缓存 (5) 多级别取消请求 (6) 和Activity和生命周期的联动(Activity结束时同时取消所有网络请求) 2、android-async-http 项目地址:https://github.com/loopj/android-async-http 文档介绍:http://loopj.com/android-async-http/ (1) 在匿名回调中处理请求结果 (2) 在UI线程外进行http请求 (3) 文件断点上传 (4) 智能重试 (5) 默认gzip压缩 (6) 支持解析成Json格式 (7) 可将Cookies持久化到SharedPreferences 3、Afinal框架 项目地址:https://github.com/yangfuhai/afinal 主要有四大模块: (1) 数据库模块:android中的orm框架,使用了线程池对sqlite进行操作。 (2) 注解模块:android中的ioc框架,完全注解方式就可以进行UI绑定和事件绑定。无需findViewById和setClickListener等。 (3) 网络模块:通过httpclient进行封装http数据请求,支持ajax方式加载,支持下载、上传文件功能。 (4) 图片缓存模块:通过FinalBitmap,imageview加载bitmap的时候无需考虑bitmap加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象。 FinalBitmap可以配置线程加载线程数量,缓存大小,缓存路径,加载显示动画等。FinalBitmap的内存管理使用lru算法, 没有使用弱引用(android2.3以后google已经不建议使用弱引用,android2.3后强行回收软引用和弱引用,详情查看android官方文档), 更好的管理bitmap内存。FinalBitmap可以自定义下载器,用来扩展其他协议显示网络图片,比如ftp等。同时可以自定义bitmap显示器, 在imageview显示图片的时候播放动画等(默认是渐变动画显示)。 4、xUtils框架 项目地址:https://github.com/wyouflf/xUtils 主要有四大模块: (1) 数据库模块:android中的orm框架,一行代码就可以进行增删改查; 支持事务,默认关闭; 可通过注解自定义表名,列名,外键,唯一性约束,NOT NULL约束,CHECK约束等(需要混淆的时候请注解表名和列名); 支持绑定外键,保存实体时外键关联实体自动保存或更新; 自动加载外键关联实体,支持延时加载; 支持链式表达查询,更直观的查询语义,参考下面的介绍或sample中的例子。 (2) 注解模块:android中的ioc框架,完全注解方式就可以进行UI,资源和事件绑定; 新的事件绑定方式,使用混淆工具混淆后仍可正常工作; 目前支持常用的20种事件绑定,参见ViewCommonEventListener类和包com.lidroid.xutils.view.annotation.event。 (3) 网络模块:支持同步,异步方式的请求; 支持大文件上传,上传大文件不会oom; 支持GET,POST,PUT,MOVE,COPY,DELETE,HEAD,OPTIONS,TRACE,CONNECT请求; 下载支持301/302重定向,支持设置是否根据Content-Disposition重命名下载的文件; 返回文本内容的请求(默认只启用了GET请求)支持缓存,可设置默认过期时间和针对当前请求的过期时间。 (4) 图片缓存模块:加载bitmap的时候无需考虑bitmap加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象; 支持加载网络图片和本地图片; 内存管理使用lru算法,更好的管理bitmap内存; 可配置线程加载线程数量,缓存大小,缓存路径,加载显示动画等... 5、ThinkAndroid 项目地址:https://github.com/white-cat/ThinkAndroid 主要有以下模块: (1) MVC模块:实现视图与模型的分离。 (2) ioc模块:android中的ioc模块,完全注解方式就可以进行UI绑定、res中的资源的读取、以及对象的初始化。 (3) 数据库模块:android中的orm框架,使用了线程池对sqlite进行操作。 (4) http模块:通过httpclient进行封装http数据请求,支持异步及同步方式加载。 (5) 缓存模块:通过简单的配置及设计可以很好的实现缓存,对缓存可以随意的配置 (6) 图片缓存模块:imageview加载图片的时候无需考虑图片加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象。 (7) 配置器模块:可以对简易的实现配对配置的操作,目前配置文件可以支持Preference、Properties对配置进行存取。 (8) 日志打印模块:可以较快的轻易的是实现日志打印,支持日志打印的扩展,目前支持对sdcard写入本地打印、以及控制台打印 (9) 下载器模块:可以简单的实现多线程下载、后台下载、断点续传、对下载进行控制、如开始、暂停、删除等等。 (10) 网络状态检测模块:当网络状态改变时,对其进行检 6、LoonAndroid 项目地址:https://github.com/gdpancheng/LoonAndroid 主要有以下模块: (1) 自动注入框架(只需要继承框架内的application既可) (2) 图片加载框架(多重缓存,自动回收,最大限度保证内存的安全性) (3) 网络请求模块(继承了基本上现在所有的http请求) (4) eventbus(集成一个开源的框架) (5) 验证框架(集成开源框架) (6) json解析(支持解析成集合或者对象) (7) 数据库(不知道是哪位写的 忘记了) (8) 多线程断点下载(自动判断是否支持多线程,判断是否是重定向) (9) 自动更新模块 (10) 一系列工具类
NoHttp 是专门做Android网络请求与下载的框架。支持HTTP/HTTPS,自动维持Cookie,异步/同步请求,大文件/多文件上传,文件下载;支持304缓存,302/303重定向,支持代理服务器。NoHttp特性:支持HTTP/HTTPS,自动维持Cookie,异步/同步请求,大文件/多文件上传,文件下载,上传下载均有进度。支持304缓存,自定义缓存,302/303重定向,支持代理服务器访问地址(如: Google)。NoHttp是队列,自动为请求排队,可以取消指定请求, 可以取消队列所有请求,亦可以停止队列。支持请求String、Bitmap、Json、JavaBean,可自定义扩展请求类型。Request对象包涵参数、文件、请求头等;Response对象包涵响应内容,响应头等信息,Cookie。使用Gradle构建时添加依赖:// 引用最新版 compile 'com.yolanda.nohttp:nohttp: ' // 或则引用指定版本 compile 'com.yolanda.nohttp:nohttp:1.0.0'一. 请求1.请求String数据// 请求对象 Request request = NoHttp.createStringRequest(url, requestMethod); //添加请求头 request.addHeader("AppVersioin", "2.0"); // 添加请求参数 request.add("userName", "yolanda"); //上传文件 request.add("file", new FileBinary(file)); ...2.请求Json数据// JsonObject Request request = NoHttp.createJsonObjectRequest(url, reqeustMethod); queue.add(what, request, responseListener); … // JsonArray Request request = NoHttp.createJsonArrayRequest(url, reqeustMethod); queue.add(what, request, responseListener);3. 请求Bitmap数据Request request = NoHttp.createImageRequest(url, requestMethod); ...4. 取消请求取消单个请求Request request = NoHttp.createStringRequest(url); ... request.cancel();从队列中取消指定的请求Request request = NoHttp.createStringRequest(url); request.setCancelSign(sign); … queue.cancelBySign(sign);取消队列中所有请求queue.cancelAll();停止队列RequestQueue queue = NoHttp.newRequestQueue(); ... queue.stop();5. 同步请求// 在当前线程发起请求,在线程这么使用 Request request = NoHttp.createStringRequest(url); Response response = NoHttp.startRequestSync(request); if (response.isSucceed()) {     // 请求成功 } else {     // 请求失败 }二. 缓存1. Http标准协议的缓存,比如响应码是304时现在很多公司使用了RESTFUL风格来写Http API,所以这个是必须有的。Request request = NoHttp.createJsonObjectRequest(url); // NoHttp本身是RESTFUL风格的标准Http协议,所以这里不用设置或者设置为DEFAULT request.setCacheMode(CacheMode.DEFAULT); ...2. 当请求服务器失败的时候,读取缓存Request request = NoHttp.createJsonObjectRequest(url); // 非标准Http协议,改变缓存模式为REQUEST_FAILED_READ_CACHE request.setCacheMode(CacheMode.REQUEST_FAILED_READ_CACHE); ...3. 如果发现有缓存直接成功,没有缓存才请求服务器我们知道ImageLoader的核心除了内存优化外,剩下一个就是发现把内地有图片则直接使用,没有则请求服务器,所以NoHttp这一点非常使用做一个ImageLoader。Request request = NoHttp.createJsonObjectRequest(url); // 非标准Http协议,改变缓存模式为IF_NONE_CACHE_REQUEST request.setCacheMode(CacheMode.IF_NONE_CACHE_REQUEST); ...请求图片,缓存图片。// 如果没有缓存才去请求服务器,否则使用缓存,缓存图片演示 Request request = NoHttp.createImageRequest(imageUrl); request.setCacheMode(CacheMode.IF_NONE_CACHE_REQUEST); ...4. 仅仅读取缓存Request request = NoHttp.createJsonObjectRequest(url); // 非标准Http协议,改变缓存模式为ONLY_READ_CACHE request.setCacheMode(CacheMode.ONLY_READ_CACHE); ...注意:缓存不管是String、Json、图片还是任何请求都可以被NoHttp缓存二、响应OnResponseListener responseListener = new OnResponseListener() {     @Override     public void onStart(int what) {         // 请求开始时,可以显示一个Dialog     }     @Override     public void onFinish(int what) {         // 请求接受时,关闭Dialog     }     @Override     public void onSucceed(int what, Response response) {         // 接受请求结果         String result = response.get();         // Bitmap imageHead = response.get(); // 如果是bitmap类型,都是同样的用法     }     @Override     public void onFailed(int what, String url, Object tag, Exception exception, ...) {         // 请求失败或者发生异常         // 这里根据exception处理不同的错误,比如超时、网络不好等     } };三. 自定义请求类型: FastJsonRequest1.定义请求对象public class FastJsonRequest extends RestRequestor { public FastJsonRequest(String url) {     super(url); } public FastJsonRequest(String url, RequestMethod requestMethod) {     super(url, requestMethod); } @Override public JSONObject parseResponse(String url, Headers headers, byte[] responseBody) {     String result = StringRequest.parseResponseString(url, headers, responseBody);     JSONObject jsonObject = null;     if (!TextUtils.isEmpty(result)) {         jsonObject = JSON.parseObject(result);     } else {         // 这里默认的错误可以定义为你们自己的数据格式         jsonObject = JSON.toJSON("{}");     }     return jsonObject; } @Override public String getAccept() {     // 告诉服务器你接受什么类型的数据, 会添加到请求头的Accept中     return "application/json;q=1"; } }2.使用自定义请求-和NoHttp默认请求没有区别Request mRequest = new FastJsonRequest(url, requestMethod); queue.add(what, mRequest, responseListener);五. 下载文件发起下载请求//下载文件 downloadRequest = NoHttp.createDownloadRequest(url, fielDir, fileName, true, false); // what 区分下载 // downloadRequest 下载请求对象 // downloadListener 下载监听 CallServer.getDownloadInstance().add(0, downloadRequest, downloadListener);暂停或者停止下载downloadRequest.cancel();监听下载过程private DownloadListener downloadListener = new DownloadListener() {     @Override     public void onStart(int what, boolean resume, long preLenght, Headers header, long count) {     }     @Override     public void onProgress(int what, int progress, long downCount) {         // 更新下载进度     }     @Override     public void onFinish(int what, String filePath) {     }     @Override     public void onDownloadError(int what, StatusCode code, CharSequence message) {     }     @Override     public void onCancel(int what) {     } }; 标签:NoHttp

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值