1. 程式人生 > >在android上用HttpURLConnection獲取網頁內容

在android上用HttpURLConnection獲取網頁內容

介面效果如下,在編輯框中輸入網址,點選按鈕後,獲取編輯框中的網址,開啟HttpURLConnection連線,並獲取輸入流,將返回的流儲存為html檔案,然後再用WebView將html檔案顯示出來。


主要程式碼GetHtml.java(完整程式碼)

package ckl.gethtml;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;

public class GetHtml extends Activity {
	private EditText mEdit = null;
	private Button mButton = null;
	private WebView mWeb = null;
	
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mEdit = (EditText)findViewById(R.id.myEdit1);
        mButton = (Button)findViewById(R.id.myButton1);
        mWeb = (WebView)findViewById(R.id.myWeb1);
        
        mWeb.getSettings().setJavaScriptEnabled(true);
        mWeb.getSettings().setPluginsEnabled(true);
        
        mButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				String strUrl = mEdit.getText().toString();
				String strFile = "/sdcard/test.html";
				if (!strUrl.startsWith("http://")) {
					strUrl = "http://" + strUrl;
				}
				getStaticPageByBytes(strUrl, strFile);
				mWeb.loadUrl("file://" + strFile);
			}
		});
    }
    
	private void getStaticPageByBytes(String surl, String strFile){
		
		Log.i("getStaticPageByBytes", surl + ", " + strFile);
		
		HttpURLConnection connection = null;
		InputStream is = null;
		
		File file = new File(strFile);
		FileOutputStream fos = null;

		try {
			URL url = new URL(surl);
			connection = (HttpURLConnection)url.openConnection();
			
			int code = connection.getResponseCode();
			if (HttpURLConnection.HTTP_OK == code) {
				connection.connect();
				is = connection.getInputStream();
				fos = new FileOutputStream(file);
				
				int i;
				while((i = is.read()) != -1){
					fos.write(i);  
				}
				
				is.close();
				fos.close();
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (connection != null) {
				connection.disconnect();
			}
		}
	}
}


下面這個網頁上說的方法並不能每次都能獲得正確的網頁內容:

主要是因為受到網頁內容編碼(encoding)的影響,頁面編碼內容的編碼是不確定的,可能不是utf-8。

因為在java內部是使用utf-16來表示字元的,所以在使用String儲存頁面內容時,會被轉換為utf-16來儲存,寫入檔案時在轉換為作業系統中的預設編碼,

這樣導致儲存檔案內容的編碼和html中指定的編碼不一致,導致中文亂碼。

另外關於InputStream.available()解釋如下:

“返回此輸入流方法的下一個呼叫方可以不受阻塞地從此輸入流讀取(或跳過)的位元組數”
如果這是一個Socket的InputStream,那麼它的read方法就可能導致阻塞(即表示read方法可能一直等待對方傳送的資料而不返回)
available根本不是表示這個流有多長的意思,對於Socket之類的InputStream根本無法判斷這個流會有多長。