java - Android,从网络获取数据并更新 UI(多线程和 MVC 设计模式)

标签 java android multithreading okhttp

目前正在开发天气应用程序。我要严格遵守两条规则:

  1. MVC 设计模式
  2. 当我处理网络时使用多线程。

问题是将这些东西组合成一个整体,这是我的部分代码:

天气类(代表一个天气对象):

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个问题:

  1. 这是 MVC 的正确设计吗? (我的意思是,所有以某种方式处理与仅更新 View 的 Controller 分离的数据的代码)

  2. 如果是,我该如何实现?我需要返回 Weather 对象 来自 Worker,但是我不能这样做,因为它发生在单独的线程上,我想将 Weather 对象返回到主线程,但不知道如何实现它。

最佳答案

  1. 据我所知,您的M模型是您的Weather.java 类,您的MainActivity(和其他添加的Activity)是您的C Controller 和 最后,您的 layout.xml 文件就是您的View View 。所以 AFAIK 是的, 这是按照 MVC 模式正确实现的。
  2. 听起来你的 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 , herehere . 找到官方文档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/

相关文章:

java - 对于 64 位 Windows,我们需要使用 64 位 java

java - 按钮交互失败

java - 在 Storm TrackedTopology 单元测试中运行 Trident 拓扑

android - 媒体播放器总是循环播放,永不停止

java - 在 Java 中向 Firebase 中的特定主题发送通知

android - 以编程方式添加多个 fragment

java - 从十六进制转换为字节

CLONE_VM 标志使 itimer 不准确?

java - 了解 JFrame 何时完全绘制

java - 如何将简单的 Java Echo Server 改为多线程?