最近想測試從網頁上讀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();
}
}