搜尋此網誌

2015年8月20日 星期四

【Android】實作從html讀取JSON 〈2〉

最近想測試從網頁上讀Json並在Android手機上

舊方法:【Java】實作從html讀取JSON (應該是說在Android API 22之後Apache HTTP Client Removal,Http Get /post的方法被捨棄 )

新方法:以HttpURLConnection實作讀取

因為是要顯示在Android 手機上,那種耗時的網路連線、資料整理的動作並不能在main thread中做處理,所以需要額外開一條Thread在background做處理或是以AsyncTask。
在這裡使用AsyncTask來處理相關動作。(更多關於AsyncTask)

較重要的程式碼,如下:

AndroidManifest.xml
須加上
<uses-permission android:name="android.permission.INTERNET" />
允許使用網路
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">
</uses-permission>
允許檢查網路狀態

FetchTask.java
public class FetchTask extends AsyncTask<String,Void,String> {

    interface OnFetchListener {
        public void OnAirDataFetchFinished();
    }

    private OnFetchListener onFetchListener;

    public void setOnFetchListener(OnFetchListener listener) {
        onFetchListener =listener;
    }



    @Override
    protected String doInBackground(String... params) {
        DataFetcher.getInstance().fetchAirData();
        return  DataFetcher.getInstance().getResult();
    }

    @Override
    protected void onPostExecute(String s) {
        onFetchListener.OnAirDataFetchFinished();
    }
}
DataFetcher.java
public class DataFetcher {
    private StringBuilder airData = new StringBuilder();
    private String path = "http://......";
    private ArrayList<AirSiteObject> mItems;

    private DataFetcher() {

    }

    private static DataFetcher mFetcher;

    public static DataFetcher getInstance() {
        if (null == mFetcher) {
            mFetcher = new DataFetcher();
        }
        return mFetcher;
    }

    public void fetchAirData() {
        HttpURLConnection httpURLConnection = null;
        try {
            URL url = new URL(path);
            httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.connect();
            int status = httpURLConnection.getResponseCode();
            switch (status) {
                case 200:
                case 201:
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "UTF-8"));
                    String line;
                    while ((line = bufferedReader.readLine()) != null) {
                        airData.append(line + "\n");
                    }
                    bufferedReader.close();

            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            if (httpURLConnection != null) {
                httpURLConnection.disconnect();

            }
        }

    }

    public String getResult() {
        return airData.toString();
    }

    //JSONParser
    public ArrayList<AirSiteObject> GetAirData(String result) {
        mItems =new ArrayList<AirSiteObject>();
        JSONObject obj;
        try {
            JSONArray jsonArray = new JSONArray(result);
            for (int i = 0; i < jsonArray.length(); i++) {
                obj = jsonArray.getJSONObject(i);
                mItems.add(new AirSiteObject(obj));
            }

        } catch (JSONException e) {
            Log.e("MYAPP", "unexpected JSON exception", e);
        }
        return mItems;
    }
}
MainActivity.java
private FetchTask mFetchAirDataTask;
記得要
implements FetchTask.OnFetchListener
onCraete method
mFetchAirDataTask = new FetchTask();mFetchAirDataTask.setOnFetchListener(this);executeTask();

判斷網路是否正常
private void executeTask() {
    if (ToolsHelper.isNetworkAvailable(this)) {
        mFetchAirDataTask.execute();    } else {
        Toast.makeText(this, "未偵測到網路,請確認網路狀況。", Toast.LENGTH_LONG).show();    }
}

實作OnFetchListener介面的OnAirDataFetchFinished method
@Override
    public void OnAirDataFetchFinished() {
        String result = DataFetcher.getInstance().getResult();
        listView.setAdapter(new ViewItemAdapter(this, DataFetcher.getInstance().GetAirData(result)));
        if (DataFetcher.getInstance().GetAirData(result).size() == 0) {
            Toast.makeText(this, "資料讀取失敗,請稍候再重試。", Toast.LENGTH_LONG).show();
        }
    }

1 則留言:

匿名 提到...

為什麼使用HttpURLConnection 而不使用 Apache HTTP Client
說明如下
http://droidyue.com/blog/2015/05/30/android-http-clients/