android – 互联网检查,使用MVP,RX和Retrofit时放置在哪里

我已经通过了 thisthis的帖子.所以我真的同意第二篇帖子,主持人不应该知道特定于Android的东西.所以我在想的是将互联网检查放在服务层.
我正在使用Rx Java进行网络调用,所以我可以在进行服务调用之前进行网络检查,这样我就需要手动抛出和IOException,因为我需要在网络不可用时在视图上显示错误页面,另一个选择是我为没有互联网创建我自己的错误
Observable<PaginationResponse<Notification>> response = Observable.create(new Observable.OnSubscribe<PaginationResponse<Notification>>() {
            @Override
            public void call(Subscriber<? super PaginationResponse<Notification>> subscriber) {
                if (isNetworkConnected()) {
                    Call<List<Notification>> call = mService.getNotifications();
                    try {
                        Response<List<Notification>> response = call.execute();
                        processpaginationResponse(subscriber,response);
                    } catch (IOException e) {
                        e.printstacktrace();
                        subscriber.onError(e);
                    }
                } else {
//This is I am adding manually
                    subscriber.onError(new IOException);
                }
                subscriber.onCompleted();
            }
        });

我的另一种方法是将拦截添加到OkHttpClient并将其设置为改装

OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
        builder.addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                if (!isNetworkConnected()) {
                    throw new IOException();
                }
                final Request.Builder builder = chain.request().newBuilder();

                Request request = builder.build();

                return chain.proceed(request);
            }
        });

现在第二种方法更具可扩展性,但我不确定它是否有效,因为我将不必要地调用service方法和call.execute()方法.

有什么建议应该使用哪种方式?
我的判断方式也是我的参数

>效率
>可扩展性
> Generic:我希望这个相同的逻辑可用于遵循类似架构的应用程序,其中MVP和Repository / DataProvider(可以从network / db提供数据)

如果您的人已经在使用任何其他方式,也欢迎其他建议.

解决方法

首先我们创建一个用于检查Internet连接的实用程序,我们可以通过两种方式创建此实用程序,其中一个实用程序仅发出一次状态,如下所示,
public class InternetConnection {
    public static Observable<Boolean> isInterneton(Context context) {
        ConnectivityManager connectivityManager
                = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return Observable.just(activeNetworkInfo != null && activeNetworkInfo.isConnected());
    }
}

创建此实用程序的其他方法是,如果实用程序发生更改,它将继续发出连接状态,如下所示:

public class InternetConnection {
    public Observable<Boolean> isInterneton(Context context) {
        final IntentFilter filter = new IntentFilter();
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);

        return Observable.create(new Observable.OnSubscribe<Boolean>() {
            @Override
            public void call(final Subscriber<? super Boolean> subscriber) {
                final broadcastReceiver receiver = new broadcastReceiver() {
                    @Override
                    public void onReceive(Context context,Intent intent) {
                        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                        NetworkInfo netInfo = cm.getActiveNetworkInfo();
                        subscriber.onNext(netInfo != null && netInfo.isConnected());
                    }
                };

                context.registerReceiver(receiver,filter);

                subscriber.add(unsubscribeInUiThread(() -> context.unregisterReceiver(receiver)));
            }
        }).defaultIfEmpty(false);
    }

    private Subscription unsubscribeInUiThread(final Action0 unsubscribe) {
        return Subscriptions.create(() -> {
            if (Looper.getMainLooper() == Looper.myLooper()) {
                unsubscribe.call();
            } else {
                final Scheduler.Worker inner = AndroidSchedulers.mainThread().createWorker();
                inner.schedule(() -> {
                    unsubscribe.call();
                    inner.unsubscribe();
                });
            }
        });
    }
}

接下来,在您的dataSource或Presenter中使用switchMap或flatMap检查互联网连接,然后再进行任何网络操作,如下所示:

private Observable<List<GitHubUser>> getGitHubUsersFromretrofit() {
    return isInterneton(context)
            .filter(connectionStatus -> connectionStatus)
            .switchMap(connectionStatus -> gitHubApiInterface.getGitHubUsersList()
                    .map(gitHubUserList -> {
                       gitHubUserDao.storeOrUpdateGitHubUserList(gitHubUserList);
                        return gitHubUserList;
                    }));
}

请注意,我们使用的是switchMap而不是flatMap.为什么switchMap?因为,我们这里有2个数据流,第一个是互联网连接,第二个是Retrofit.首先我们将获取连接状态值(true / false),如果我们有活动连接,我们将创建一个新的Retrofit流并返回开始获取结果,如果我们连接状态发生变化,switchMap将首先停止现有改进连接,然后决定是否需要启动新的或忽略它.

编辑:
这是样本之一,可能会提供更好的清晰度https://github.com/viraj49/Realm_android-injection-rx-test/blob/master/app-safeIntegration/src/main/java/tank/viraj/realm/dataSource/GitHubUserListDataSource.java

EDIT2:

所以你的意思是一旦互联网回来,开关地图会自己尝试吗?

是和否,我们首先看看flatMap和amp;之间的区别. switchMap.假设我们有一个editText,我们根据用户类型从网络中搜索一些信息,每次用户添加一个新的字符时我们都要进行新的查询(可以通过去抖动减少),现在只有这么多的网络调用最新的结果是有用的,使用flatMap,我们将收到我们对网络进行的所有调用的所有结果,另一方面,使用switchMap,当我们进行查询时,所有先前的调用都将被丢弃.

现在解决方案由2部分组成,

>我们需要一个持续发出网络当前状态的Observable,上面的第一个InternetConnection发送状态一次并调用onComplete(),但第二个有一个broadcast接收器,它将在网络状态改变时继续发送onNext().如果你需要制定一个反应性解决方案,请选择案例2
>假设你选择了InternetConnection case-2,在这种情况下使用switchMap(),因为当网络状态发生变化时,我们需要停止Retrofit的工作,然后根据网络状态进行新的调用或者不要打个电话.

如何让我的视图知道错误是互联网,这也是可扩展的,因为我需要处理每个网络调用,有关编写包装器的任何建议吗?

编写包装器是一个很好的选择,您可以创建自己的自定义响应,该响应可以从一组可能的响应中获取多个条目,例如: SUCCESS_INTERNET,SUCCESS_LOGIN,ERROR_INVALID_ID

EDIT3:请在此处找到更新的InternetConnectionUtil https://github.com/viraj49/Realm_android-injection-rx-test/blob/master/app-safeIntegration/src/main/java/tank/viraj/realm/util/InternetConnection.java

关于同一主题的更多细节在这里https://medium.com/@Viraj.Tank/android-mvp-that-survives-view-life-cycle-configuration-internet-changes-part-2-6b1e2b5c5294

EDIT4:我最近使用Android架构组件创建了一个Internet实用程序 – LiveData,你可以在这里找到完整的源代码,
https://github.com/viraj49/Internet-Utitliy-using-AAC-LiveData

这里有代码的详细描述,
https://medium.com/@Viraj.Tank/internet-utility-using-android-architecture-components-livedata-e828a0fcd3db

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


这篇“android轻量级无侵入式管理数据库自动升级组件怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定...
今天小编给大家分享一下Android实现自定义圆形进度条的常用方法有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文...
这篇文章主要讲解了“Android如何解决字符对齐问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android...
这篇文章主要介绍“Android岛屿数量算法怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android岛屿数量算...
本篇内容主要讲解“Android如何开发MQTT协议的模型及通信”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Andro...
本文小编为大家详细介绍“Android数据压缩的方法是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android数据压缩的方法是什么”文章能帮助大家解决疑惑...
这篇“Android怎么使用Intent传大数据”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅...
本文小编为大家详细介绍“Android事件冲突怎么解决悬浮窗拖拽问题”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android事件冲突怎么解决悬浮窗拖拽问题”文...
这篇文章主要介绍了Android拼接如何实现动态对象的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android拼接如何实现动态对象文...
今天小编给大家分享一下Android全面屏适配怎么实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下...
本篇内容介绍了“Android怎么开发Input系统触摸事件分发”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何...
今天小编给大家分享一下AndroidRoom怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下...
本文小编为大家详细介绍“AndroidRoom使用方法有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“AndroidRoom使用方法有哪些”文章能帮助大家...
这篇文章主要介绍“Android中的OpenGL怎么配置使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android中的Open...
这篇文章主要介绍了Android如何自定义自动识别涂鸦工具类的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Android如何自定义自动...
今天小编给大家分享一下Android如何自定义有限制区域的图例角度自识别涂鸦工具类的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以...
今天小编给大家分享一下ReactNative错误采集原理在Android中如何实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章...
这篇文章主要讲解了“Android崩溃日志收集和保存代码分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“A...
这篇“Android面向单Activity开发实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大...
本篇内容介绍了“Android应用启动白屏处理的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何...