1

我正在开发一个应用程序,它使用 PHP 和 JSON 从 MySQL 数据库中提取天气数据。它检查用户是否有互联网连接,如果没有,它将查找本地存储的文件。如果该文件不存在,那么它将显示一条消息。要刷新列表,用户必须重新启动应用程序。我发现这对用户不太友好,所以我决定添加一个刷新数据的按钮。

我有两个类,我的 ListActivity 类(在下面的代码中称为 WeerActivity.java)和一个在新线程中从 Internet 收集所有数据的类(称为 InternetWeerThread.java)。我的 onClickListener,对于刷新按钮,是在 ListActivity 类中设置的。这会尝试将包含刷新代码的可运行文件发布到另一个类。但是,当我这样做时。我得到一个异常,因为代码仍然在 UI 线程上执行。

WeerActivity.java

public class WeerActivity extends ListActivity{

    private static Thread internetWeerThread;

    private InternetWeerThread internetWeerThreadInstance;

    public static Handler activityHandler;
    public static Handler internetHandler;
    public static ListView listView;
    public static Context context;
    public static LinearLayout weerContainer;
    public static Button refreshButton;



@Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        setContentView(R.layout.weer);
        refreshButton = (Button) findViewById(R.id.weer_refresh_button);
        listView = (ListView)findViewById(android.R.id.list);
        weerContainer = (LinearLayout) findViewById(R.id.weer_container);
        context = this;

        activityHandler = new Handler();
        internetWeerThreadInstance = new InternetWeerThread(activityHandler);
        internetWeerThread = internetWeerThreadInstance;
        internetHandler = InternetWeerThread.getHandler();
        internetWeerThread.start();

        refreshButton.setOnClickListener(new Button.OnClickListener(){
            public void onClick(View v){
                internetHandler.post(internetWeerThreadInstance.new Refresh());
            }
        });
    }
}

InternetWeerThread.java

class InternetWeerThread extends Thread{

    private Handler activityHandler;

    private static String html;
    private static JSONArray weerItems;
    private static ArrayList<WeerData> weerData = new ArrayList<WeerData>();
    private static WeerAdapter adapter;
    private static String JSONString;

    private static final String timeoutString = "Unable to connect with the server, check your internet connection";
    private static final Handler internetWeerThread = new Handler();

    // CONSTRUCTOR
    public InternetWeerThread(Handler activityHandler){
        this.activityHandler = activityHandler;
    }

    public static Handler getHandler(){
        return internetWeerThread;
    }

    @Override
    public void run(){
        onRefresh();
    }

    // method that gets called by the Runnable Refresh (and onCreate)
    private void onRefresh(){
        try{
            weerItems = getWeerItems("http://192.168.178.14/weer.php");
            JSONString = weerItems.toString();
            FileAccess.createFile(WeerActivity.context, "weer.txt", JSONString);
            displayData(weerItems);
        }catch(IOException e){
            e.printStackTrace();
            System.out.println(WeerActivity.context);
            if(FileAccess.fileExists(WeerActivity.context, "weer.txt")){ // read data from file
                JSONArray JSONData;
                try {
                    if(FileAccess.readFile(WeerActivity.context, "weer.txt") != null){
                        JSONData = new JSONArray(FileAccess.readFile(WeerActivity.context, "weer.txt"));
                        displayData(JSONData);
                        activityHandler.post(new Updater());
                    }else{
                        activityHandler.post(new TimeOut());
                    }
                } catch (JSONException je) {
                    je.printStackTrace();
                    activityHandler.post(new TimeOut());
                }
            }else{ // display message that there is no internet connection and no file present
                activityHandler.post(new TimeOut());
            }
        }
    }

    private JSONArray getWeerItems(String link) throws IOException{
        HttpUriRequest request = new HttpGet(link.toString());

        BasicHttpParams httpParameters = new BasicHttpParams();
        int timeoutConnection = 3000;
        ConnManagerParams.setTimeout(httpParameters, timeoutConnection);

        HttpClient httpClient = new DefaultHttpClient(httpParameters);
        HttpResponse response = httpClient.execute(request);

        if(response.getStatusLine().getStatusCode() == 200){
            JSONArray jArray = new JSONArray();

            try {
                URL url = new URL(link);
                HttpURLConnection con = (HttpURLConnection) url.openConnection();
                readStream(con.getInputStream());

                try {
                    jArray = new JSONArray(html);           
                } catch (JSONException e) {
                    e.printStackTrace();

                }
                return jArray;
            }catch (Exception e) {
                e.printStackTrace();
            }
            return jArray;
        }else{
            activityHandler.post(new TimeOut());

            JSONArray jArray = new JSONArray();
            return jArray;
        }
    }

    private void readStream(InputStream in){
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";
            html = "";
            while ((line = reader.readLine()) != null) {
                html += line;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void displayData(JSONArray jArray){
        try{
            int length;
            if(jArray.length() < 7){
                length = jArray.length();
            }else if (jArray.length() > 7){
                length = 7;
            }else{
                length = 7;
            }
            for(int i = 0; i < length; i++){
                JSONObject row = jArray.getJSONObject(i);
                int temperatureDay = row.getInt("temperature_day");
                int temperatureNight = row.getInt("temperature_night");
                String date = row.getString("date");
                int weatherType = row.getInt("weather_type");

                WeerData singleWeerData = new WeerData();
                singleWeerData.setTemperatureDay(temperatureDay);
                singleWeerData.setTemperatureNight(temperatureNight);
                singleWeerData.setDate(date);
                singleWeerData.setWeatherType(weatherType);

                weerData.add(i, singleWeerData);
            }

            activityHandler.post(new Updater());
        }catch(JSONException e){
            e.printStackTrace();
        }
    }

    // update the listView
    public class Updater implements Runnable{
        public void run(){
            adapter = new WeerAdapter(WeerActivity.context, R.layout.weer_row, weerData);
            WeerActivity.listView.setAdapter(adapter);
        }
    }

线程和 Runnables 对我来说是新的。这是我正在创建的第一个 Android 应用程序。所以希望有人可以帮助我解决这个问题。

任何帮助将不胜感激 !

4

0 回答 0