android使用HttpClient和URLConnection獲取網頁內容

今天開始android網絡編程,平時作的android整機開發這塊,基本上不大須要接觸android網絡變成這塊知識,仍是得熟悉熟悉。php

本文要講的是使用URLConnection對象和HttpClient組件訪問網絡以及獲取 網頁內容的方法。html

Android對HTTP(超文本傳輸協議)提供了很好的支持,這裏包括兩種接口:java

一、標準Java接口(java.net) ----HttpURLConnection,能夠實現簡單的基於URL請求、響應功能;android

二、Apache接口(org.appache.http)----HttpClient,使用起來更方面更強大。通常來講,用這種接口。不過本文仍是把第一種接口過一下。web

任何一種接口,無外乎四個基本功能:訪問網頁、下載圖片或文件、上傳文件.本文示範的是訪問網頁和下載圖片。HttpURLConnection繼承自URLConnection類,用它能夠發送和接口任何類型和長度的數據,且預先不用知道數據流的長度,能夠設置請求方式get或post、超時時間。apache

先直接上代碼吧:

編程

package com.example.webdatashow;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

import android.R.string;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;




public class MainActivity extends Activity implements OnClickListener{
	private String TAG = "webdatashow";
	private Button urlConnection;
	private Button httpClient;
	private TextView webDataShow;
	private String pediyUrl = "http://bbs.pediy.com/forumdisplay.php?f=161";
	
	private static final int MSG_SUCCESS = 0;
	private static final int MSG_FAILURE = 1;
	private Handler mHandler = null;
	private Thread mThread;
	private Thread httpClientThread;	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.webdata);
		urlConnection = (Button)findViewById(R.id.urlConnection);
		httpClient = (Button)findViewById(R.id.httpClient);
		webDataShow = (TextView)findViewById(R.id.webDataShow);
		urlConnection.setOnClickListener(this);
		httpClient.setOnClickListener(this);
		mHandler = new Handler()
		{

			@Override
			public void handleMessage(Message msg) {
				
				switch (msg.what) {
				case MSG_SUCCESS:
					Toast.makeText(getApplicationContext(), "URLConnection 鏈接成功", Toast.LENGTH_SHORT).show();	
					webDataShow.setText((String)msg.obj);
					break;
				case MSG_FAILURE:	
					Toast.makeText(getApplicationContext(), "URLConnection 鏈接失敗", Toast.LENGTH_SHORT).show();
				default:
					break;
				}
			}
			
		};
		
		
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

	@Override
	public void onClick(View view) {
		switch (view.getId()) {
		case R.id.urlConnection:
			if(mThread == null)
			{				
				mThread = new Thread(urlConnRunnable);
				mThread.start();
			}						
			break;
		case R.id.httpClient:
			if(httpClientThread == null)
			{
				httpClientThread = new Thread(httpClientRunnable);
				httpClientThread.start();
			}
			break;
		default:
			break;
		}
		
		
	}

	Runnable httpClientRunnable = new Runnable() {
		
		@Override
		public void run() {
			
			httpClientWebData();
			
		}
	};
	
	
	Runnable urlConnRunnable = new Runnable() {
		
		@Override
		public void run() {
			
			try {
				urlConGetWebData();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	};
	
	
	private void urlConGetWebData() throws IOException {
		URL url = new URL(pediyUrl);
		HttpURLConnection httpConn = (HttpURLConnection)url.openConnection();
		if(httpConn.getResponseCode() == HttpURLConnection.HTTP_OK)
		{		
			Log.d("TAG", "---into-----urlConnection---success--");
			
			InputStreamReader isr = new InputStreamReader(httpConn.getInputStream(), "utf-8");
			int i;
			String content = "";
			while((i = isr.read()) != -1)
			{
				content = content + (char)i;
			}
			mHandler.obtainMessage(MSG_SUCCESS,content).sendToTarget();
			isr.close();
			httpConn.disconnect();
		}else
		{
			Log.d("TAG", "---into-----urlConnection---fail--");
			
		}
		
	}

	protected void httpClientWebData() {
		DefaultHttpClient httpClinet = new DefaultHttpClient();
		HttpGet httpGet = new HttpGet(pediyUrl);
		ResponseHandler<String> responseHandler = new BasicResponseHandler();
		try {
			String content = httpClinet.execute(httpGet, responseHandler);
			mHandler.obtainMessage(MSG_SUCCESS,content).sendToTarget();
		} catch (ClientProtocolException e) {
			
			e.printStackTrace();
		} catch (IOException e) {
			
			e.printStackTrace();
		}
	}
	
	
	
	

}

<?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" >

    <Button 
       android:id="@+id/urlConnection"
       android:layout_width="fill_parent"
       android:layout_height="60dip"
       android:text="urlConnection"
        />
    <Button 
       android:id="@+id/httpClient"
       android:layout_width="fill_parent"
       android:layout_height="60dip"
       android:text="httpClient"
        />

    
    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        >
	    <TextView
	        android:id="@+id/webDataShow"
	        android:layout_width="fill_parent"
	        android:layout_height="wrap_content" 
	        />        
    </ScrollView>
    
    
    

    
</LinearLayout>

作這個須要注意幾點:網絡

1,訪問網絡,記得添加權限
app

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

2,使用Http協議錯誤:java.net.MalformedURLException: no protocol:

錯誤緣由就是這是http請求,須要在請求地址上加入 http://協議

3,android.os.NetworkOnMainThreadException

這個異常大概意思是在主線程訪問網絡時出的異常。 Android在4.0以前的版本 支持在主線程中訪問網絡,可是在4.0之後對這部分程序進行了優化,也就是說訪問網絡的代碼不能寫在主線程中了。

4,android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

每一個Android應用程序都運行在一個dalvik虛擬機進程中,進程開始的時候會啓動一個主線程(MainThread),主線程負責處理和ui相關的事件,所以主線程一般又叫UI線程。而因爲Android採用UI單線程模型,因此只能在主線程中對UI元素進行操做。若是在非UI線程直接對UI進行了操做,則會報錯:
CalledFromWrongThreadException:only the original thread that created a view hierarchy can touch its views

Android爲咱們提供了消息循環的機制,咱們能夠利用這個機制來實現線程間的通訊。那麼,咱們就能夠在非UI線程發送消息到UI線程,最終讓Ui線程來進行ui的操做。
對於運算量較大的操做和IO操做,咱們須要新開線程來處理這些繁重的工做,以避免阻塞ui線程

備註:

這兩種方法分別採用HttpClient和URLConnection,好像是HttpClient方式比較穩定,通常都能下載到,可是URLConnection在EDGE網絡下常常下不到數據。

相關文章
相關標籤/搜索