Http网络连接处理

    |     2015年8月5日   |   网络通讯   |     0 条评论   |    1600

这里我们将学习Android程序如何进行网络连接,获取网络返回数据,如果对HTTP网络协议还不了解的可以参考深入理解HTTP协议,在进行网络连接操作前需要先在程序的manifest文件中添加下面的permissions:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

同时要检查当前网络环境是否可用

ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (isGpsConnection() || isWiFiConnection()) {
    //网络连接可用
} else {
    //网络连接不可用!
}
 /**
     * 检查网络连接是否可用
     */
    public boolean isGpsConnection(){
        ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            //网络连接可用
            return true;
        } else {
            //网络连接不可用!
            return false;
        }
    }

    public boolean isWiFiConnection(Context inContext) {
        Context context = inContext.getApplicationContext();
        ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        if (connectivity != null) {
            NetworkInfo[] info = connectivity.getAllNetworkInfo();
            if (info != null) {
                for (int i = 0; i < info.length; i++) {
                    if (info[i].getTypeName().equals("WIFI") && info[i].isConnected()) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

网络操作会遇到不可预期的延迟。显然为了避免一个不好的用户体验,总是在UI Thread之外去执行网络操作。AsyncTask 类提供了一种简单的方式来处理这个问题
doInBackground()) 执行 downloadUrl()方法。Web URL作为参数,方法downloadUrl() 获取并处理网页返回的数据,执行完毕后,传递结果到onPostExecute()。参数类型为String.
onPostExecute()) 获取到返回数据并显示到UI上。

private class DownloadWebpageText extends AsyncTask<String, Void, String> {
		@Override
		protected String doInBackground(String... urls) {

			// 参数从execute()方法传入, params[0]表示url.
			//获取url资源数据并返回
		}

		// onPostExecute方法中处理AsyncTask返回的结果
		@Override
		protected void onPostExecute(String result) {

		}

	}

我们来看下完整的实例代码
布局文件activity_httpconnection_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/http_url_edit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入URL地址" />

    <TextView
        android:id="@+id/http_content_txt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button android:id="@+id/http_get_content_btn"
        android:layout_width="match_parent"
        android:onClick="onConnectionClickHandler"
        android:layout_height="wrap_content" />

</LinearLayout>

原代码 HttpExampleActivity.java

public class HttpExampleActivity extends Activity {
	private static final String DEBUG_TAG = "HttpExample";
	private EditText mUrlText;
	private TextView mShowMessageTxt;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_httpconnection_layout);
		mUrlText = (EditText) findViewById(R.id.http_url_edit);
		mShowMessageTxt = (TextView) findViewById(R.id.http_content_txt);
	}

	/**
	 * 用户点击此按钮时执行异步任务,在执行前需检查网络是否可用.
	 *
	 */
	public void onConnectionClickHandler(View view) {
		String stringUrl = mUrlText.getText().toString();// 获取请求的URL从EditText控件中.
		ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
		if (networkInfo != null && networkInfo.isConnected()) {
			new DownloadWebpageText().execute(stringUrl);
		} else {
			mShowMessageTxt.setText("网络连接不可用!");
		}
	}

	private class DownloadWebpageText extends AsyncTask<String, Void, String> {
		@Override
		protected String doInBackground(String... urls) {

			// 参数从execute()方法传入, params[0]表示url.
			try {
				return downloadUrl(urls[0]);
			} catch (IOException e) {
				return "Unable to retrieve web page. URL may be invalid.";
			}
		}

		// onPostExecute方法中处理AsyncTask返回的结果
		@Override
		protected void onPostExecute(String result) {
			mShowMessageTxt.setText(result);
		}

	}

	/**
	 * 根据给定的url地址,建立一个HttpUrlConnection连接它将以流的形式返回页面内容,将流转换成字符串返回
	 * @param myurl
	 * @return
	 * @throws IOException
	 */
	private String downloadUrl(String myurl) throws IOException {
		InputStream is = null;

		try {
			URL url = new URL(myurl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setReadTimeout(10000);  /*读数据超时*/
			conn.setConnectTimeout(15000);/*连接超时*/
			conn.setRequestMethod("GET"); /*请求方式*/
			conn.setDoInput(true);/* 设置允许输入流*/

			conn.connect();
			int response = conn.getResponseCode();
			Log.d(DEBUG_TAG, "The response is: " + response);
			is = conn.getInputStream();

			String contentAsString = readIt(is);
			return contentAsString;

			//关闭InputStream
		} finally {
			if (is != null) {
				is.close();
			}
		}
	}

	/**
	 * 将InputStream转换成String返回
	 * @param stream
	 * @return
	 * @throws IOException
	 * @throws UnsupportedEncodingException
	 */
	public String readIt(InputStream stream) throws IOException,UnsupportedEncodingException {
		Reader reader = new InputStreamReader(stream, "UTF-8");
		// 创建包装流
		BufferedReader br = new BufferedReader(reader);
		// 定义String类型用于储存单行数据
		String line = null;
		// 创建StringBuffer对象用于存储所有数据
		StringBuffer sb = new StringBuffer();
		while ((line = br.readLine()) != null) {
			sb.append(line);
		}

		return sb.toString();

	}

}

请注意,getResponseCode() 会返回连接状态码( status code). 这是一种获知额外网络连接信息的有效方式。status code 是 200 则意味着连接成功.

Convert the InputStream to a String(把InputStream的数据转换为String)
InputStream 是一种可读的byte数据源。如果你获得了一个 InputStream, 通常会进行decode或者转换为制定的数据类型。例如,如果你是在下载一张image数据,你可能需要像下面一下进行decode:

InputStream is = null;
...
Bitmap bitmap = BitmapFactory.decodeStream(is);
ImageView imageView = (ImageView) findViewById(R.id.image_view);
imageView.setImageBitmap(bitmap);

大多数连接网络的Android app会使用HttpURLConnection作为客户端来发送与接受数据。除此之外还可用Apache HttpClient。

HttpClient httpClient = new DefaultHttpClient();
			HttpGet httpGet = new HttpGet(httpUrl);
			HttpResponse response = httpClient.execute(httpGet);

			int statusCode = response.getStatusLine().getStatusCode();
			Logs.v("statusCode >>> :" + statusCode);

			if (statusCode == HttpURLConnection.HTTP_OK) {
				InputStream ins = response.getEntity().getContent();

				BufferedReader br = new BufferedReader(new InputStreamReader(ins,"utf-8"));

				StringBuilder sb = new StringBuilder();
				String line = null;
				while ((line = br.readLine()) != null) {
					sb.append(line);
				}

			}
转载请注明来源:Http网络连接处理
回复 取消