有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

  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;
    }
}

工人阶级(做所有“肮脏”的工作):

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类)。我想在未来取得这样的成就

主要活动。java:

...
Worker mWorker = new Worker();
Weather mWeather = mWorker.getWeatherData();
...

2个问题:

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

  2. 如果是,我如何实施?我需要归还天气物体 从Worker开始,但是我不能这样做,因为它发生在单独的线程上,我想将Weather对象返回到主线程,但不知道如何实现


共 (1) 个答案

  1. # 1 楼答案

    1. 据我所知,你的M模型是你的Weather.java类,你的主要活动(以及额外添加的活动)是你的C控制器和 最后,你的layout.xml文件就是你的V视图。好吧是的, 这是按照MVC模式正确实现的
    2. 听起来你的Worker.java类应该是AsyncTask 实施

    使用AsyncTask的示例(这只是一个存根实现,请参阅下面的链接以查看完整的工作示例):

    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
        }
    }
    

    最后,您将执行以下异步任务:

    new WorkerTask().execute("your_url");
    

    更多使用AsyncTask hereherehere的示例。 官方文件见here

    关于AsyncTask和MVC设计模式

    这样做的一个缺点是,AsyncTask必须在MainActivity中实现(或者在任何你想使用它的地方),这与MVC设计相矛盾

    解决这个问题的方法是创建一个“HTTP调用方类”,它进行网络调用,并在AsyncTask doInBackground方法中调用

    使用这种方法,你会很乐意去做。您可以让控制器(MainActivity)执行AsyncTask(但不在MainActivity中执行任何实际的网络调用),创建一个新的HttpCallerClass,然后调用一个处理网络的方法。因此,MVC得以保留