• 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;
    	}
    }
    
  • 相关阅读:
    网页表格或div层在网页中被撑开解决之道
    jquery把给定的json自动生成多级下拉框
    jquery理想菜单实现(显示全国省市区分级效果)
    正则表达式记录
    jQuery自定义插件
    js数组及其常用方法
    vue自定义组件
    GET和POST
    可变对象和不可变对象
    js 不同元素的同一属性运动
  • 原文地址:https://www.cnblogs.com/swalka/p/5020174.html
Copyright © 2020-2023  润新知