您的位置:首页 > 理论基础 > 计算机网络

Android HttpURLConnection数据获取并JSON解析

2014-04-29 14:06 726 查看
程序开发的时候,一般通过一个接口从服务端获取数据。获取数据回来后,如果是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源代码:

点击下载源码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: