1. 程式人生 > >Android HttpURLConnection資料獲取並JSON解析

Android HttpURLConnection資料獲取並JSON解析

程式開發的時候,一般通過一個介面從服務端獲取資料。獲取資料回來後,如果是JSON資料,則需要通過JSON解析;如果是XML資料,則需要經過XML解析後,才適合顯示在手機螢幕上。

本文主要講解,通過HttpURLConnection從服務端獲取資料,然後經過JSON解析後,顯示在手機螢幕上。

下一篇文章與這篇文章實現的效果是一樣的。只不過,下一篇文章用到的網路請求時用到的是Apache包中的HttpClient。

實現效果圖:

相關原始碼:

佈局檔案:

activity_main:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="HTML網頁檢視器" />

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/textView"
        android:hint="請輸入網址"
        android:singleLine="true"
        android:text="http://m.weather.com.cn/data/101010100.html" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/editText"
        android:text="點 擊 獲 取" />

    <ScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/button" >

        <TextView
            android:id="@+id/textViewContent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="" />
    </ScrollView>

</RelativeLayout>

程式碼檔案:

MainActivity:

package com.net;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.httphtmlchakanqi.R;
import com.utils.HttpUtils;
/**
 * 通過介面,獲取網路的資訊,然後經過JSON解析,顯示在螢幕上。
 * 方法一:
 * @author Administrator
 *
 */
public class MainActivity extends Activity implements OnClickListener {
	private EditText editText;
	private Button button;
	private TextView textView;
	private final int SUCCESS = 1;
	private final int FAILURE = 0;
	private final int ERRORCODE = 2;
	protected String weatherResult;

	private Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case SUCCESS:
				/**
				 * 獲取資訊成功後,對該資訊進行JSON解析,得到所需要的資訊,然後在textView上展示出來。
				 */
				JSONAnalysis(msg.obj.toString());
				Toast.makeText(MainActivity.this, "獲取資料成功", Toast.LENGTH_SHORT)
				.show();
				break;

			case FAILURE:
				Toast.makeText(MainActivity.this, "獲取資料失敗", Toast.LENGTH_SHORT)
						.show();
				break;

			case ERRORCODE:
				Toast.makeText(MainActivity.this, "獲取的CODE碼不為200!",
						Toast.LENGTH_SHORT).show();
				break;
			default:
				break;
			}
		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		/**
		 * 初始化
		 */
		init();
	}
	
	private void init() {
		editText = (EditText) findViewById(R.id.editText);
		button = (Button) findViewById(R.id.button);
		textView = (TextView) findViewById(R.id.textViewContent);
		button.setOnClickListener(this);
	}
	
	/**
	 * JSON解析方法
	 */
	protected void JSONAnalysis(String string) {
		JSONObject object = null;
		try {
			object = new JSONObject(string);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		/**
		 * 在你獲取的string這個JSON物件中,提取你所需要的資訊。
		 */
		JSONObject ObjectInfo = object.optJSONObject("weatherinfo");
		String city = ObjectInfo.optString("city");
		String date = ObjectInfo.optString("date_y");
		String week = ObjectInfo.optString("week");
		String temp = ObjectInfo.optString("temp1");
		String weather = ObjectInfo.optString("weather1");
		String index = ObjectInfo.optString("index_d");

		weatherResult = "城市:" + city + "\n日期:" + date + "\n星期:" + week
				+ "\n溫度:" + temp + "\n天氣情況:" + weather + "\n穿衣指數:" + index;
		textView.setText(weatherResult);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.button:
			/**
			 * 點選按鈕事件,在主執行緒中開啟一個子執行緒進行網路請求
			 * (因為在4.0只有不支援主執行緒進行網路請求,所以一般情況下,建議另開啟子執行緒進行網路請求等耗時操作)。
			 */
			new Thread() {
				public void run() {
					int code;
					try {
						String path = editText.getText().toString();
						URL url = new URL(path);
						/**
						 * 這裡網路請求使用的是類HttpURLConnection,另外一種可以選擇使用類HttpClient。
						 */
						HttpURLConnection conn = (HttpURLConnection) url
								.openConnection();
						conn.setRequestMethod("GET");//使用GET方法獲取
						conn.setConnectTimeout(5000);
						code = conn.getResponseCode();
						if (code == 200) {
							/**
							 * 如果獲取的code為200,則證明資料獲取是正確的。
							 */
							InputStream is = conn.getInputStream();
							String result = HttpUtils.readMyInputStream(is);
							
							/**
							 * 子執行緒傳送訊息到主執行緒,並將獲取的結果帶到主執行緒,讓主執行緒來更新UI。
							 */
							Message msg = new Message();
							msg.obj = result;
							msg.what = SUCCESS;
							handler.sendMessage(msg);

						} else {
						
							Message msg = new Message();
							msg.what = ERRORCODE;
							handler.sendMessage(msg);
						}
					} catch (Exception e) {

						e.printStackTrace();
						/**
						 * 如果獲取失敗,或出現異常,那麼子執行緒傳送失敗的訊息(FAILURE)到主執行緒,主執行緒顯示Toast,來告訴使用者,資料獲取是失敗。
						 */
						Message msg = new Message();
						msg.what = FAILURE;
						handler.sendMessage(msg);
					}
				};
			}.start();
			break;

		default:
			break;
		}
	}

}

HttpUtils(將從服務端獲取過來的位元組流轉換成字串):
package com.utils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
 * 將位元組流轉換為字串的工具類
 */
public class HttpUtils {

	public static String readMyInputStream(InputStream is) {
		byte[] result;
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len;
			while ((len = is.read(buffer))!=-1) {
				baos.write(buffer,0,len);
			}
			is.close();
			baos.close();
			result = baos.toByteArray();
			
		} catch (IOException e) {
			e.printStackTrace();
			String errorStr = "獲取資料失敗。";
			return errorStr;
		}
		return new String(result);
	}

}

可以看到,程式碼相對來說比較簡單。希望有興趣的學者,可以認真研究後,自己能夠輕鬆的寫出來。

下面提供相應Demo原始碼: