带你封装MVP架构(上)|青训营笔记(二)

简介: 我们做一个 MVP 架构的封装,主要其相对于MVC更加解耦,能让开发人员在编写代码的时候更加高效和舒服。

MyUtil

该工具类获得了一个全局的 Context ,以及根据此context,创建了开启加载动画以及关闭加载动画的方法

public class MyUtil {
    /**
     * 全局context
     */
    private static Application mApplicationContext;
    private static RxDialogLoading rxDialogLoading;
    /**
     * @param app 初始化全局context
     */
    public static void initialize(Application app) {
        mApplicationContext = app;
    }
    /**
     * 获得全局context
     *
     * @return 当前的全局context
     */
    public static Application getApplication() {
        return mApplicationContext;
    }
    /**
     * 关闭键盘
     */
    public static void closeSoftKeyboard() {
        InputMethodManager inputManger = (InputMethodManager) ActivityUtil.getCurrentActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (inputManger != null) {
            inputManger.hideSoftInputFromWindow(ActivityUtil.getCurrentActivity().getWindow().getDecorView().getWindowToken(), 0);
        }
    }
    public static String getString(int id) {
        return getApplication().getResources().getString(id);
    }
    /**
     * 展示dialog
     *
     * @param context 传入当前Acitivity
     */
    public static void showLoading(Context context){
        if (rxDialogLoading == null){
            rxDialogLoading = new RxDialogLoading(context);
            rxDialogLoading.setCanceledOnTouchOutside(false);
        }
        rxDialogLoading.show();
    }
    /**
     * 成功隐藏dialog,显示成功
     */
    public static void dismissSuccessLoading(){
        rxDialogLoading.cancel(RxDialogLoading.RxCancelType.success,getString(R.string.load_success));
    }
    /**
     * 失败隐藏dialog,显示失败
     */
    public static void dismissFailedLoading(){
        rxDialogLoading.cancel(RxDialogLoading.RxCancelType.error,getString(R.string.load_error));
    }
}
复制代码

Retrofit + Rxjava 打造优雅网络请求方式

由于该模块代码繁多,文章不会描述每一个类,完整代码请查阅http

其中的 cookie 包是用于做登录状态持久化,但是本demo中未用到

gson 包是做了一个转换器,对网络数据的请求报文和响应报文做了一次数据筛查

API 类是定义了所有的网络请求方法

RetrofitService 类是对该网络模块的集成的方法,是 Retrofit 的核心方法

BaseResponseBodyConverter

该方法是继承了类型为响应报文的 Retrofit 转换器类,可以对对响应报文做数据筛查。我们可以筛查出响应的报文的错误码或者错误描述进行自动的异常处理。

例如返回的错误码描述为当前登录状态过期,那么我们可以取消登录状态,程序自动跳转到登录页面中。

亦或是错误码为非正常状态下,自动抛出自定义的异常,然后App对该异常做 Toast 描述之类的

public class BaseResponseBodyConverter<T> implements Converter<ResponseBody, T> {
    private final TypeAdapter<T> adapter;
    BaseResponseBodyConverter(TypeAdapter<T> adapter) {
        this.adapter = adapter;
    }
    @Override
    public T convert(ResponseBody value) throws IOException {
        String jsonString = value.string();
        try{
            JSONObject object = new JSONObject(jsonString);
            int code = object.getInt(MyUtil.getString(R.string.code));
            String data ;
            if (code == 1) return adapter.fromJson(jsonString);
            else  data = object.getString(MyUtil.getString(R.string.msg));
            throw new BaseException(code, data);
        }catch (JSONException ex){
            ex.printStackTrace();
            try {
                JSONObject object = new JSONObject(jsonString);
                int error_code = object.getJSONObject("data").getInt(MyUtil.getString(R.string.error_code));
                if (0 != error_code ) {
                    String data;
                    data = object.getJSONObject("data").getString(MyUtil.getString(R.string.error_msg));
                    //异常处理
                    throw new BaseException(error_code, data);
                }
                //正确返回整个json
                return adapter.fromJson(jsonString);
            } catch (JSONException e) {
                e.printStackTrace();
                //数据解析异常即json格式有变动
                throw new BaseException(MyUtil.getString(R.string.PARSE_ERROR_MSG));
            }
        }finally {
            value.close();
        }
    }
}
复制代码

需要注意的是,我们需要针对不同格式的响应报文,定制不同的筛查策略和处理逻辑

MoreBaseUrlInterceptor

自定义一个过滤器,在该过滤器中,我们可以对请求的做一些自动的更改

例如下例,我们可以在检测到请求头中带 urlName 字段的时候,去做一个对应的 BaseUrl 的更新;我们也还可以在这里做一些譬如key这些字段的添加等等

public class MoreBaseUrlInterceptor implements Interceptor {
    private final HashMap<String,String> keyUrl;
    public MoreBaseUrlInterceptor(HashMap<String, String> keyUrl) {
        this.keyUrl = keyUrl;
    }
    @Override
    public Response intercept(Chain chain) throws IOException {
        //获取原始的originalRequest
        Request originalRequest = chain.request();
        //获取老的url
        HttpUrl oldUrl = originalRequest.url();
        //获取originalRequest的创建者builder
        Request.Builder builder = originalRequest.newBuilder();
        //获取头信息的集合如:base,geo
        List<String> urlNameList = originalRequest.headers("urlName");
        if (urlNameList.size() > 0) {
            //删除原有配置中的值,就是namesAndValues集合里的值
            builder.removeHeader("urlName");
            //获取头信息中配置的value,如:m或者mock
            String urlName = urlNameList.get(0);
            HttpUrl baseURL;
            //根据头信息中配置的value,来匹配新的base_url地址
            baseURL = HttpUrl.parse(Objects.requireNonNull(keyUrl.get(urlName)));
            //重建新的HttpUrl,需要重新设置的url部分
            HttpUrl newHttpUrl = oldUrl.newBuilder()
                    .scheme(baseURL.scheme())//http协议如:http或者https
                    .host(baseURL.host())//主机地址
                    .encodedPath(baseURL.encodedPath() +
                            oldUrl.encodedPath().substring(1))//构建路径,为适配MOCK中给出的BaseURL带有Path路径的情况
                    .port(baseURL.port())//端口
                    .build();
            //获取处理后的新newRequest
            Request newRequest = builder.url(newHttpUrl).build();
            return  chain.proceed(newRequest);
        }else{
            Request reOriginalRequest = builder.url(oldUrl).build();
            return chain.proceed(reOriginalRequest);
        }
    }
}
复制代码

RetrofitService

该类是 Retrofit 服务类,对外提供一个服务的单例,然后添加好前面编写的转换器以及过滤器等信息。这样子供外部统一调用这个 Retrofit 单例即可。

public class RetrofitService {
    private volatile static RetrofitService apiRetrofit;
    private API.SZApi apiServer;
    /**
     * 单例调用
     *
     * @return RetrofitService
     */
    public static RetrofitService getInstance() {
        if (apiRetrofit == null) {
            synchronized (Object.class) {
                if (apiRetrofit == null) {
                    apiRetrofit = new RetrofitService();
                }
            }
        }
        return apiRetrofit;
    }
    /**
     * 获取api对象
     *
     * @return api对象
     */
    public API.SZApi getApiService() {
        return apiServer;
    }
    /**
     * 初始化retrofit
     */
    private RetrofitService() {
        //配置okHttp并设置时间、日志信息和cookies
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(new MoreBaseUrlInterceptor(API.getKeyUrl()))
                .addInterceptor(httpLoggingInterceptor)
                //设置超时时间
                .connectTimeout(15, TimeUnit.SECONDS)
                //设置Cookie持久化
//                .cookieJar(new CookiesManager(MyUtil.getApplication()))
                .build();
        //关联okHttp并加上rxJava和Gson的配置和baseUrl
        Retrofit retrofit = new Retrofit.Builder()
                .client(okHttpClient)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(BaseConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(API.BASE_URL)
                .build();
        apiServer = retrofit.create(API.SZApi.class);
    }
}
复制代码


相关文章
|
3月前
|
前端开发 测试技术 数据处理
Kotlin教程笔记 - MVP与MVVM架构设计的对比
Kotlin教程笔记 - MVP与MVVM架构设计的对比
112 4
|
3月前
|
前端开发 Java 测试技术
android MVP契约类架构模式与MVVM架构模式,哪种架构模式更好?
android MVP契约类架构模式与MVVM架构模式,哪种架构模式更好?
110 0
|
4月前
|
前端开发 测试技术 数据处理
Kotlin教程笔记 - MVP与MVVM架构设计的对比
Kotlin教程笔记 - MVP与MVVM架构设计的对比
75 3
|
4月前
|
前端开发 Java 测试技术
android MVP契约类架构模式与MVVM架构模式,哪种架构模式更好?
android MVP契约类架构模式与MVVM架构模式,哪种架构模式更好?
51 2
|
6月前
|
Android开发 iOS开发
Android项目架构设计问题之将隐式跳转的逻辑进行抽象和封装如何解决
Android项目架构设计问题之将隐式跳转的逻辑进行抽象和封装如何解决
71 0
|
8月前
|
移动开发 小程序 安全
基础入门-APP架构&小程序&H5+Vue语言&Web封装&原生开发&Flutter
基础入门-APP架构&小程序&H5+Vue语言&Web封装&原生开发&Flutter
|
8月前
|
设计模式 存储 前端开发
MVVM、MVC、MVP三种常见软件架构设计模式的区别
MVC、MVP 和 MVVM 是三种常见的软件架构设计模式,主要通过分离关注点的方式来组织代码结构,优化开发效率。
167 12
|
9天前
|
传感器 监控 安全
智慧工地云平台的技术架构解析:微服务+Spring Cloud如何支撑海量数据?
慧工地解决方案依托AI、物联网和BIM技术,实现对施工现场的全方位、立体化管理。通过规范施工、减少安全隐患、节省人力、降低运营成本,提升工地管理的安全性、效率和精益度。该方案适用于大型建筑、基础设施、房地产开发等场景,具备微服务架构、大数据与AI分析、物联网设备联网、多端协同等创新点,推动建筑行业向数字化、智能化转型。未来将融合5G、区块链等技术,助力智慧城市建设。
|
2月前
|
Cloud Native API 持续交付
云原生架构下的微服务治理策略与实践####
本文旨在探讨云原生环境下微服务架构的治理策略,通过分析当前面临的挑战,提出一系列实用的解决方案。我们将深入讨论如何利用容器化、服务网格(Service Mesh)等先进技术手段,提升微服务系统的可管理性、可扩展性和容错能力。此外,还将分享一些来自一线项目的经验教训,帮助读者更好地理解和应用这些理论到实际工作中去。 ####
69 0
|
2月前
|
Java 开发者 微服务
从单体到微服务:如何借助 Spring Cloud 实现架构转型
**Spring Cloud** 是一套基于 Spring 框架的**微服务架构解决方案**,它提供了一系列的工具和组件,帮助开发者快速构建分布式系统,尤其是微服务架构。
301 69
从单体到微服务:如何借助 Spring Cloud 实现架构转型

热门文章

最新文章