- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我已经经历了this和 this邮政。所以我真的同意第二个帖子,即演示者不应该知道 android 特定的东西。所以我在想的是将互联网检查放在服务层中。我正在使用 Rx Java 进行网络调用,所以我可以在进行服务调用之前进行网络检查,所以这样我需要手动抛出 IOException 因为当网络不可用时我需要在 View 上显示错误页面,另一种选择是我为没有互联网创建自己的错误类
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);
}
});
现在第二种方法更具可扩展性,但我不确定它是否有效,因为我会不必要地调用服务方法和 call.execute() 方法。
有什么建议应该使用哪种方式吗?还有我判断方式的参数是
效率
可扩展性
通用:我希望相同的逻辑可以用于遵循类似架构的应用程序,其中 MVP 和 Repository/DataProvider(可能从网络/db 提供数据)
如果你们已经在使用任何其他方式,也欢迎提出其他建议。
最佳答案
首先我们创建一个用于检查互联网连接的实用程序,我们可以通过两种方式创建该实用程序,一种是该实用程序仅发出一次状态,如下所示,
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。为什么要切换 map ?因为,我们这里有 2 个数据流,第一个是互联网连接,第二个是 Retrofit。首先我们将获取连接状态值(true/false),如果我们有 Activity 连接,我们将创建一个新的 Retrofit 流并返回开始获取结果,如果连接状态发生变化,switchMap 将首先停止现有的改造连接,然后决定我们是否需要开始一个新连接或忽略它。
编辑2:
所以你的意思是 switch map 会在互联网恢复后自行尝试?
Yes and No,先看看flatMap和switchMap的区别。假设我们有一个 editText 并且我们根据用户类型从网络中搜索一些信息,每次用户添加一个新角色我们都必须进行一个新查询(可以通过去抖减少),现在有这么多网络调用只有最新的结果很有用,使用 flatMap 我们将收到我们对网络进行的所有调用的所有结果,另一方面,使用 switchMap ,在我们进行查询时, 所有之前的调用都被丢弃。
现在这里的解决方案由两部分组成,
我们需要一个持续发送当前网络状态的 Observable,上面的第一个 InternetConnection 发送一次状态并调用 onComplete(),但是第二个有一个广播接收器,它会在网络连接时继续发送 onNext()状态变化。如果您需要针对案例 2 制定响应式(Reactive)解决方案
假设您选择 InternetConnection case-2,在这种情况下使用 switchMap(),因为当网络状态发生变化时,无论 Retrofit 正在做什么,我们都需要停止它,然后根据网络状态进行新电话或不调用电话。
我如何让我的 View 知道错误是 internet 的,这是否是可扩展的,因为我需要处理每个网络调用,关于编写包装器有什么建议吗?
编写包装器将是一个很好的选择,您可以创建自己的自定义响应,它可以从一组可能的响应中获取多个条目,例如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
关于android - 上网查,使用MVP、RX和Retrofit时放在哪里,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38242462/
我相信 Presenter 是负责处理 MVP 应用程序导航方面的人。这是真的还是有异常(exception)? 最佳答案 我认为 View 是唯一负责屏幕导航的 View 。 Here我们对这个“A
我看到了两种实现“加载”反馈的基本方法(例如旋转加载图标): 在演示者中: void displayData() { display.startShowingLoadingIcon();
我有一个方法,用户可以搜索文章编号,如果它在数据库中可用,则文章编号绑定(bind)到 BindingList。现在我想让用户知道该文章是否在数据库中不可用。我该如何以正确的方式做到这一点? 只需将消
我们正在使用 gwt-presenter,但并不是一个特定于此的问题...... 我有一张包含用户的表格。当我在 View 中构建表格时(根据演示者提供的数据),我需要在行的末尾添加两个操作按钮(“编
请用一个简单的例子来描述MVP-Passive View和MVP-Supervising controller的区别。最好显示如何使用 mvp 技术(被动 View 和监督 Controller )绑
GWT 2.1 包含一个 MVP framework其中包括 Google 的 Ray Ryan 在 Google I/O 2009 上概述的 PlaceService 实现。 那个talk启发了一些
在Model-View-Presenter模式中,我们应该在哪里编写用户输入的验证。 最佳答案 Realm 特定的规则/验证应在模型中。您可以使用model.validate()来告知您是否违反规则。
当我们在面试的时候被问到谈谈你对MVC,MVP,MVVM的理解。我们该如何回答,下面我们将对这些模式进行总结。 一、web1.0时代 在web1.0时代,当时并没有前端这个概念,当时如果要开发一个项目
我正在寻找有关 GWT 架构的指南 - 何时使用自包含小部件与 MVP/事件/场所。 背景 阅读了 Google 文档并搜索了 Stackoverflow,gwt-examples 项目为这个问题提供
在地点更改时更新事件状态的最佳做法是什么?假设您有一个带有 View 的事件,该 View 显示类别列表和类别中的项目列表。如果选择了不同的类别,则应用程序会使用类别 ID 转到新位置。然后我只想刷新
在 GWT 中使用 MVP 时,您将如何使用表?例如,如果您有一个用户表,您的 View 看起来像这样吗? public interface MyDisplay{ HasValue users();
我有一个 GWT 应用程序,我正在将 GWT MVP 与地点/事件一起使用。 我的应用程序布局类似于 菜单 |内容 菜单和内容显示将动态变化,其中一个单独变化。我的意思是,当内容显示更改时,我不想更新
我正在使用 Windows 窗体实现 MVP 模式,我对当前的实现有疑问,因为我正试图将其融入更复杂的架构中。 现在我有一个带有属性的完全不可知的 View ,一个在构造函数中注入(inject) V
对所有 GWT 大师的问题。 我是 GWT 的新手,正在尝试了解编写 GWT 应用程序的最佳实践。我经历过"Large scale application development and MVP"基于
我最近一直试图从架构的角度来理解 MVP 架构中交互器和用例之间的关系。我的疑问是关于部件之间的通信以及符合 MVP 标准的内容。 问题是我见过很多相互矛盾的流程图。其中一些似乎每个演示者都有一个交互
我有一个具有 MVP 架构模式的应用程序。 现在,我正在尝试在我的应用程序中实现 Livedata。 我搜索了很多,但我找不到任何教程或示例。 所有教程都说实时数据适用于 MVVM 模式。 在 MVP
我有一个关于在使用 MVP 时如何处理演示者之间的通信的问题。假设我有两个 MVP-triads。一个是产品列表(Triad A),另一个是有关当前所选产品的一般信息(Triad B)。 我如何告诉
我主要具有 ASP.Net 背景,并具有一些 MVC 知识。我也做了一些 Silverlight 和 MVVM,但是我现在即将转向 Winforms,我对它的经验很少,所以我想知道如何处理 MVP。
我读了鲍勃叔叔的《整洁架构书》。我尝试实现简单的例子。我有这个图: 我不明白如何实现红线部分。例如,我有一个简单的网页: 我有 2 个按钮、一个已编辑的文本和一个标签。如果我按下发送到服务器按钮 -
我正在查看 MVP 的 google 示例,我看到 this作为 Activity 的 onCreate 中的最后一个语句: new TaskDetailPresenter(
我是一名优秀的程序员,十分优秀!