android MVP - 应该如何从模型中调用网络层?
android MVP - How should the network layer be called , from model?
在 MVP android 中,我认为网络层(改造、截击等)不应该与模型分开。但是我需要一个关于如何构建模型的可靠示例。该模型应该是网络层在 api 调用完成时简单创建的单例吗?
让我们来看看我为我的一项活动安排的主持人:
public class MainActivityPresenter implements IMainPresenterContract, Callback {
IMainActivityViewContract view;//todo set up a weak reference to View to avoid leakage
NewsService interactor;
public MainActivityPresenter(IMainActivityViewContract view, NewsService interactor) {
this.view = view;
this.interactor = interactor;
}
public void loadResource() {
interactor.loadResource();
}
public void onRequestComplete(final NewsEntities newsEntities) {
view.dataSetUpdated(newsEntities.getResults());
}
@Override
public void onResult(final NewsEntities newsEntities) {
onRequestComplete(newsEntities);
}
public void goToDetailsActivity(Result result) {
view.goToDetailsActivity(result);
}
}
所以我的问题是关于传递给构造函数的 NewsService 交互器参数。我假设这应该是模型数据而不是网络服务。但它应该是什么样子呢?目前我的看起来像这样:
public class NewsService implements INewsServiceContract {
private Gson gson;
private Callback mCallback;
public NewsService() {
configureGson();
}
private static String readStream(InputStream in) {
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
String nextLine;
while ((nextLine = reader.readLine()) != null) {
sb.append(nextLine);
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
public void setCallBack(Callback cb) {
mCallback = cb; // or we can set up event bus
}
private void configureGson() {
GsonBuilder builder = new GsonBuilder();
builder.excludeFieldsWithoutExposeAnnotation();
gson = builder.create();
}
@Override
public void loadResource() {
//Todo could use a loader instead help with the config change or a headless fragment
new AsyncTask<String, String, String>() {
@Override
protected String doInBackground(String... params) {
String readStream = "";
HttpURLConnection con = null;
try {
URL url = new URL("https://api.myjson.com/bins/nl6jh");
con = (HttpURLConnection) url.openConnection();
readStream = readStream(con.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
finally {
if(con!=null)
con.disconnect();
}
return readStream;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
NewsService.this.onRequestComplete(result);
}
}.execute();
}
private void onRequestComplete(String data) {
data = data.replaceAll("\"multimedia\":\"\"", "\"multimedia\":[]");
news.hotels.com.sample.Model.NewsEntities newsEntities = gson.fromJson(data, NewsEntities.class);
mCallback.onResult(newsEntities);
}
}
因此您可以看到本例中的 NewsService 正在执行网络调用。我想我不应该把这个传给主持人。但是如何构建模型呢?谁调用新闻服务?
更新:这个问题是很久以前的了,请大家使用干净的架构方法,让你的演示者对网络层一无所知。
网络调用需要在模型层,并且应该由演示者触发。但它的模型层决定在哪里传输数据并且它对 Presenter 层隐藏。
我自己使用交互器 class 在模型层中执行此操作,演示者将使用此交互器获取数据,交互器将从数据库或服务器获取与情况相关的数据。
查看我的存储库中的示例项目:
https://gitlab.com/amirziarati/Echarge
我用 Dagger 做的 DI 可能会让你感到困惑。只看包装以及我如何在层之间分离关注点。
更新:我使用 Presenter 从服务器和数据库同步数据,这是错误的。演示者应该对这个过程一无所知。当时没发现这个问题
在 MVP android 中,我认为网络层(改造、截击等)不应该与模型分开。但是我需要一个关于如何构建模型的可靠示例。该模型应该是网络层在 api 调用完成时简单创建的单例吗?
让我们来看看我为我的一项活动安排的主持人:
public class MainActivityPresenter implements IMainPresenterContract, Callback {
IMainActivityViewContract view;//todo set up a weak reference to View to avoid leakage
NewsService interactor;
public MainActivityPresenter(IMainActivityViewContract view, NewsService interactor) {
this.view = view;
this.interactor = interactor;
}
public void loadResource() {
interactor.loadResource();
}
public void onRequestComplete(final NewsEntities newsEntities) {
view.dataSetUpdated(newsEntities.getResults());
}
@Override
public void onResult(final NewsEntities newsEntities) {
onRequestComplete(newsEntities);
}
public void goToDetailsActivity(Result result) {
view.goToDetailsActivity(result);
}
}
所以我的问题是关于传递给构造函数的 NewsService 交互器参数。我假设这应该是模型数据而不是网络服务。但它应该是什么样子呢?目前我的看起来像这样:
public class NewsService implements INewsServiceContract {
private Gson gson;
private Callback mCallback;
public NewsService() {
configureGson();
}
private static String readStream(InputStream in) {
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
String nextLine;
while ((nextLine = reader.readLine()) != null) {
sb.append(nextLine);
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
public void setCallBack(Callback cb) {
mCallback = cb; // or we can set up event bus
}
private void configureGson() {
GsonBuilder builder = new GsonBuilder();
builder.excludeFieldsWithoutExposeAnnotation();
gson = builder.create();
}
@Override
public void loadResource() {
//Todo could use a loader instead help with the config change or a headless fragment
new AsyncTask<String, String, String>() {
@Override
protected String doInBackground(String... params) {
String readStream = "";
HttpURLConnection con = null;
try {
URL url = new URL("https://api.myjson.com/bins/nl6jh");
con = (HttpURLConnection) url.openConnection();
readStream = readStream(con.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
finally {
if(con!=null)
con.disconnect();
}
return readStream;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
NewsService.this.onRequestComplete(result);
}
}.execute();
}
private void onRequestComplete(String data) {
data = data.replaceAll("\"multimedia\":\"\"", "\"multimedia\":[]");
news.hotels.com.sample.Model.NewsEntities newsEntities = gson.fromJson(data, NewsEntities.class);
mCallback.onResult(newsEntities);
}
}
因此您可以看到本例中的 NewsService 正在执行网络调用。我想我不应该把这个传给主持人。但是如何构建模型呢?谁调用新闻服务?
更新:这个问题是很久以前的了,请大家使用干净的架构方法,让你的演示者对网络层一无所知。
网络调用需要在模型层,并且应该由演示者触发。但它的模型层决定在哪里传输数据并且它对 Presenter 层隐藏。
我自己使用交互器 class 在模型层中执行此操作,演示者将使用此交互器获取数据,交互器将从数据库或服务器获取与情况相关的数据。
查看我的存储库中的示例项目:
https://gitlab.com/amirziarati/Echarge
我用 Dagger 做的 DI 可能会让你感到困惑。只看包装以及我如何在层之间分离关注点。
更新:我使用 Presenter 从服务器和数据库同步数据,这是错误的。演示者应该对这个过程一无所知。当时没发现这个问题