AsyncActivity异步加载网页

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.zip.GZIPInputStream;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionRequest;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.util.EntityUtils;

import com.example.com.test.R;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class AsyncActivity extends Activity {

	private Button satrtButton;
	private Button cancelButton;
	private ProgressBar progressBar;
	private TextView textView;
	private DownLoaderAsyncTask downLoaderAsyncTask;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.act_test06_async);
		initView();
	}

	public void initView() {
		satrtButton = (Button) findViewById(R.id.startButton);
		cancelButton = (Button) findViewById(R.id.cancelButton);
		satrtButton.setOnClickListener(new ButtonOnClickListener());
		cancelButton.setOnClickListener(new ButtonOnClickListener());
		progressBar = (ProgressBar) findViewById(R.id.progressBar);
		textView = (TextView) findViewById(R.id.textView);
	}

	private class ButtonOnClickListener implements View.OnClickListener {
		public void onClick(View v) {
			switch (v.getId()) {
			case R.id.startButton:
				// 注意:
				// 1 每次需new一个实例,新建的任务只能执行一次,否则会出现异常
				// 2 异步任务的实例必须在UI线程中创建
				// 3 execute()方法必须在UI线程中调用。
				downLoaderAsyncTask = new DownLoaderAsyncTask();
				downLoaderAsyncTask.execute("http://cn.jarfire.org");
				break;
			case R.id.cancelButton:
				// 取消一个正在执行的任务,onCancelled()方法将会被调用
				downLoaderAsyncTask.cancel(true);
				break;
			default:
				break;
			}
		}

	}

	// 构造函数AsyncTask<Params, Progress, Result>参数说明:
	// Params 启动任务执行的输入参数
	// Progress 后台任务执行的进度
	// Result 后台计算结果的类型
	private class DownLoaderAsyncTask extends AsyncTask<String, Integer, String> {
		
		// onPreExecute()方法用于在执行异步任务前,主线程做一些准备工作
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			textView.setText("调用onPreExecute()方法--->准备开始执行异步任务");
			System.out.println("调用onPreExecute()方法--->准备开始执行异步任务");
		}

		// doInBackground()方法用于在执行异步任务,不可以更改主线程中UI
		@Override
		protected String doInBackground(String... params) {
			System.out.println("调用doInBackground()方法--->开始执行异步任务");
			try {
				return doHttpClient(params[0]);
			} catch (Exception e) {
				return null;
			}
		}

		// onPostExecute()方法用于异步任务执行完成后,在主线程中执行的操作
		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);
			Toast.makeText(getApplicationContext(),
					"调用onPostExecute()方法--->异步任务执行完毕", 0).show();
			// textView显示网络请求结果
			textView.setText(result);
			System.out.println("调用onPostExecute()方法--->异步任务执行完毕");
		}

		// onProgressUpdate()方法用于更新异步执行中,在主线程中处理异步任务的执行信息
		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			// 更改进度条
			progressBar.setProgress(values[0]);
			// 更改TextView
			textView.setText("已经加载" + values[0] + "%");
		}

		// onCancelled()方法用于异步任务被取消时,在主线程中执行相关的操作
		@Override
		protected void onCancelled() {
			super.onCancelled();
			// 更改进度条进度为0
			progressBar.setProgress(0);
			// 更改TextView
			textView.setText("调用onCancelled()方法--->异步任务被取消");
			System.out.println("调用onCancelled()方法--->异步任务被取消");
		}
		
		// 获取url的数据-------------------可以正常使用
		private String doHttpClient(String urlString) throws ClientProtocolException, IOException, InterruptedException {
			BasicHttpParams httpParams = new BasicHttpParams();
			HttpConnectionParams.setConnectionTimeout(httpParams, 6 * 1000);
			HttpConnectionParams.setSoTimeout(httpParams, 6 * 1000);
			HttpClient client = new DefaultHttpClient(httpParams);// 老方法
			HttpGet get = new HttpGet(urlString);
			HttpResponse response = client.execute(get);
			System.out.println("-----------------------");
			System.out.println(response.getStatusLine());
			if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				
				HttpEntity entity = response.getEntity();
				
				//-----------------------------测试
				String webContent = "";
				if (entity !=null) {
					entity = new BufferedHttpEntity(entity);// 在一些情况下可能会不止一次的读取实体。此时实体内容必须以某种方式在内存或磁盘上被缓冲起来。最简单的方法是通过使用BufferedHttpEntity类来包装源实体完成。这会引起源实体内容被读取到内存的缓冲区中。在其它所有方式中,实体包装器将会得到源实体。
					webContent = EntityUtils.toString(entity);
					System.out.println("Response getContentLength: "+ entity.getContentLength());
					System.out.println("Response toString() length: "+ webContent.length());
				}
				System.out.println(response.toString()); //显示HTTP请求header
				System.out.println("----------------------------------------");
				//--------------------------------
				
				InputStream is = entity.getContent();
				long total = 0;
				total = entity.getContentLength();
				Log.v("AC", "total="+total);
				ByteArrayOutputStream bos = new ByteArrayOutputStream();
				byte[] buffer = new byte[1024];
				int count = 0;
				int length = -1;
				while ((length = is.read(buffer)) != -1) {
					bos.write(buffer, 0, length);
					count += length;
					// publishProgress()为AsyncTask类中的方法
					// 常在doInBackground()中调用此方法
					// 用于通知主线程,后台任务的执行情况.
					// 此时会触发AsyncTask中的onProgressUpdate()方法
					Log.v("AC", "count/total="+count+"/"+total);
					publishProgress((int) ((count / (float) total + 0.005f) * 100));
					// 为了演示进度,休眠1000毫秒
					Thread.sleep(1000);
				}
				is.close();
				return new String(bos.toByteArray(), "UTF-8");
			}
			get.abort();
			client.getConnectionManager().shutdown();
			return null;
		}
		
		// 开启http下载
		private InputStream openHttpConnection(String urlString) throws IOException {// 压缩了的文件
			InputStream in = null;
			int response = -1;
			URL url = new URL(urlString);
			URLConnection conn = url.openConnection();
			if (!(conn instanceof HttpURLConnection)) {
				throw new IOException("It is not an HTTP connection");
			}
			try {
				HttpURLConnection httpConn = (HttpURLConnection) conn;
				httpConn.setConnectTimeout(5*1000);
				httpConn.setReadTimeout(5*1000);
				httpConn.setAllowUserInteraction(false);
				httpConn.setInstanceFollowRedirects(true);
				httpConn.setRequestMethod("GET");
				// 在诸多的网站中,特别是大型的网站,设置了必须是浏览器的请求才会回应。之所以这样设置,就是为了防止我们这种项目给他产生无意义的请求(往往这种请求都是大批量,对其服务器产生负荷)。那为了解决这个问题,我们需要在http请求中,添加属性。
				httpConn.setRequestProperty("Charset", "UTF-8");
				httpConn.setRequestProperty("Accept-Encoding", "identity");
				httpConn.setRequestProperty("Accept-Encoding", "gzip");//为什么没有deflate呢?至于为什么要设置 gzip,而又不设置deflate,原因如下,有些网站他不管你能接受什么压缩格式,统统也会压缩网页内容传给你。当然IE,FF能处理好这些内容。所以我们通过浏览器查看的时候完全正常。一般gzip的压缩可以将一个33K的文件压缩成7K,这样会节约不少带宽,但服务器的负荷并没有减轻,因为他要压缩文件呀。至于为什么不用deflate,是由于绝大多数网站的压缩方式是用gzip,而在有些网站中,明明是用的gzip却返回deflate的压缩标识。这有什么意义呢,所以干脆就告诉服务器,我不接受deflate,因为他太丑了,又长,哪像gzip这么潮呀。呵呵,对于浏览量大的静态网页服务器,这样做很是必要。100M的独享服务器,他也只有100M呀。
				httpConn.setRequestProperty("Connection", "Keep-Alive");//keep-Alive,有什么用呢,你不是在访问网站,你是在采集。嘿嘿。减轻别人的压力,也是减轻自己。
				httpConn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)");//这样就设置好了,你可以随意设置你的操作系统值,浏览器值,版本,只要正确就OK了。这样就可以正常有效地访问其网站了。他可不知道你是不是浏览器。你即使是条狗,他也不知道。
				httpConn.setUseCaches(false);//不要用cache,用了也没有什么用,因为我们不会经常对一个链接频繁访问。(针对程序)
				httpConn.connect();
				response = httpConn.getResponseCode();
				Log.v("AC", "response:"+response);
				if (response == HttpURLConnection.HTTP_OK) {
					in = httpConn.getInputStream();
					long x = httpConn.getContentLength();
					Log.v("AC", "总长度:"+x);
				}
			} catch (Exception ex) {
				Log.v("Networking", ex.getLocalizedMessage());
				throw new IOException("Error connecting");
			}
			return in;

		}
	}
	
	/**
	 * 
	 * @param urlConn
	 * @param charset
	 * @return
	 */
	public static String getContentFromIn(HttpURLConnection urlConn, String charset) {
		
		BufferedReader br = null;
		StringBuilder content = new StringBuilder(200);
		InputStream in = null;
		try {
			if (null == urlConn) {
				return "";
			}
			if (isNotEmpty(urlConn.getContentEncoding())) {
				String encode = urlConn.getContentEncoding().toLowerCase();
				if (isNotEmpty(encode)
						&& encode.indexOf("gzip") >= 0) {
					in = new GZIPInputStream(urlConn.getInputStream());
				}
			}

			if (null == in) {
				in = urlConn.getInputStream();
			}
			if (null != in) {
				br = new BufferedReader(new InputStreamReader(in, charset));
				String line = "";
				while ((line = br.readLine()) != null) {
					content.append(line);
				}
			}

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (null != in) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				in = null;
			}
			if (null != br) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				in = null;
			}
		}
		return content.toString();
	}
	
	private static boolean isNotEmpty(String str) {
		if(str.length() > 0) {
			return true;
		}
		return false;
	}
}

 

posted @ 2015-12-04 18:26  swalka`x  阅读(221)  评论(0编辑  收藏  举报