目前正在开发天气应用程序。我要严格遵守两条规则:
- MVC 设计模式
- 当我处理网络时使用多线程。
问题是将这些东西组合成一个整体,这是我的部分代码:
天气类(代表一个天气对象):
public class Weather {
private int mTimeInSeconds;
private String mTimeZone;
private int mTemperature;
private String mSummary;
public Weather(int timeInSeconds, String timeZone, int temperature, String summary) {
mTimeInSeconds = timeInSeconds;
mTimeZone = timeZone;
mTemperature = temperature;
mSummary = summary;
}
public String getTime() {
SimpleDateFormat formatter = new SimpleDateFormat("h:mm a");
formatter.setTimeZone(TimeZone.getTimeZone(mTimeZone));
Date dateTime = new Date(mTimeInSeconds * 1000);
String timeAsString = formatter.format(dateTime);
return timeAsString;
}
public int getTemperature() {
return mTemperature;
}
public String getSummary() {
return mSummary;
}
}
worker 类(Class)(做所有“脏”工作):
public class Worker {
private final OkHttpClient mClient = new OkHttpClient();
private String apiKey = "Secret!11";
private double latitude = 37.8267;
private double longitude = -122.423;
private String forecastUrl = "https://api.forecast.io/forecast/"
+apiKey
+"/"
+latitude
+","
+longitude;
public void getCurrentWeather() throws Exception {
final Request request = new Request.Builder()
.url(forecastUrl)
.build();
mClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
Log.v(MainActivity.TAG, e.getMessage());
}
@Override
public void onResponse(Response response) throws IOException {
try {
JSONObject weatherData = new JSONObject(response.body().string());
JSONObject currentlyWeather = weatherData.getJSONObject("currently");
Log.v(MainActivity.TAG, currentlyWeather.toString());
} catch (JSONException e) {
Log.v(MainActivity.TAG, e.getMessage());
}
}
});
}
}
基于我对 MVC 的理解,我将所有数据和围绕该数据的逻辑放在模型(Worker 和 Weather 类)中。我想在
主 Activity .java:
...
Worker mWorker = new Worker();
Weather mWeather = mWorker.getWeatherData();
...
2个问题:
这是 MVC 的正确设计吗? (我的意思是,所有以某种方式处理与仅更新 View 的 Controller 分离的数据的代码)
如果是,我该如何实现?我需要返回 Weather 对象 来自 Worker,但是我不能这样做,因为它发生在单独的线程上,我想将 Weather 对象返回到主线程,但不知道如何实现它。
最佳答案
- 据我所知,您的M模型是您的
Weather.java
类,您的MainActivity(和其他添加的Activity)是您的C Controller 和 最后,您的layout.xml
文件就是您的View View 。所以 AFAIK 是的, 这是按照 MVC 模式正确实现的。 - 听起来你的
Worker.java
类应该属于AsyncTask
执行。
使用 AsyncTask
的示例(这只是一个 stub 实现,请参阅下面的链接以查看完整的工作示例):
private class WorkerTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
//Network calls go here. This will be done in the background,
//in a separate thread
//Finally, you return your result here to onPostExecute
return result;
}
@Override
protected void onPostExecute(String result) {
//This method runs on the main UI thread. Here you update your UI o return data to your caller class.
}
@Override
protected void onPreExecute() {
//Called before execution
}
@Override
protected void onProgressUpdate(Void... values) {
//If you want to update your UI with your current progress, that code goes here
}
}
最后,您将像这样执行 AsyncTask:
new WorkerTask().execute("your_url");
更多使用 AsyncTask 的示例 here , here和 here . 找到官方文档here .
关于 AsyncTask 和 MVC 设计模式
这样做的一个缺点是 AsyncTask 必须在您的 MainActivity(或您想要使用它的任何地方)中实现,这与 MVC 设计相矛盾。
对此的解决方案是创建一个“HTTP 调用程序类”,它执行网络调用,并在您的 AsyncTask doInBackground
方法中调用。
使用这种方法,您就可以开始了。您可以让您的 Controller (MainActivity) 执行 AsyncTask(但不在 MainActivity 中进行任何实际的网络调用)创建一个新的 HttpCallerClass,然后调用一个处理网络的方法。因此,保留了 MVC。
关于java - Android,从网络获取数据并更新 UI(多线程和 MVC 设计模式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28645303/