文档章节

android使用HttpClient和URLConnection获取网页内容

幸子
 幸子
发布于 2014/03/27 14:42
字数 1112
阅读 2534
收藏 6

今天开始android网络编程,平时做的android整机开发这块,基本上不大需要接触android网络变成这块知识,还是得熟悉熟悉。

本文要讲的是使用URLConnection对象和HttpClient组件访问网络以及获取 网页内容的方法。

Android对HTTP(超文本传输协议)提供了很好的支持,这里包括两种接口:

1、标准Java接口(java.net) ----HttpURLConnection,可以实现简单的基于URL请求、响应功能;

2、Apache接口(org.appache.http)----HttpClient,使用起来更方面更强大。一般来说,用这种接口。不过本文还是把第一种接口过一下。

任何一种接口,无外乎四个基本功能:访问网页、下载图片或文件、上传文件.本文示范的是访问网页和下载图片。HttpURLConnection继承自URLConnection类,用它可以发送和接口任何类型和长度的数据,且预先不用知道数据流的长度,可以设置请求方式get或post、超时时间。

先直接上代码吧:

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,访问网络,记得添加权限

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

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网络下经常下不到数据。





© 著作权归作者所有

幸子
粉丝 4
博文 4
码字总数 2934
作品 0
徐汇
高级程序员
私信 提问
加载中

评论(1)

程_
程_
我想问下为什么我复制了你的代码进来,有错误,在47和78行的错误是
...
package com.cheng.english;

import android.view.View;
public final class R {
...
public static final class layout {
public static final int activity_main=0x7f030000;
public static View webdata;
}
...

该怎么修改?
android中网络操作使用总结(http)

Android是作为智能手机的操作系统,我们开发的应用,大多数也都需要连接网络,通过网络发送数据、获取数据,因此作为一个应用开发者必须熟悉怎么进行网络访问与连接。通常android中进行网络连...

码农明明
2014/05/22
3K
6
Android下的网络编程 & 代理的使用

1. 使用 标准Java接口: 设计的类: java.net.* 基本步骤: 1) 创建 URL 以及 URLConnection / HttpURLConnection 对象 2) 设置连接参数 3) 连接到服务器 4) 向服务器写数据 5)从服务器读取数据...

小编辑
2010/08/12
5.5K
2
android下的android.os.StrictMode$AndroidBlockGuardPo

try { URL url = new URL(path); //path图片的网络地址 HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); if(httpURLConnection.getResponseCode() == Ht......

Carl_
2015/01/07
216
0
Android也架构之三:简单工厂模式优化网络请求

很悲催,我们在《Android也架构之二:单例模式访问网络》 用httpConnect的方式去访问网络,而且能够正常获取数据了,可是老板能,技术出生,他要求我重新用httpClient去获取获取网络数据,童...

理工男海哥
2012/08/21
1K
0
Android 浅谈HttpClient工具类

在Android开发中我们经常会用到网络连接功能与服务器进行数据的交互,为此Android的SDK提供了Apache的HttpClient来方便我们使用各种Http服务。你可以把HttpClient想象成一个浏览器,通过它的...

Jonson
2013/07/25
714
3

没有更多内容

加载失败,请刷新页面

加载更多

Java 文件类操作API与IO编程基础知识

阅读目录: https://www.w3cschool.cn/java/java-io-file.html Java 文件 Java 文件 Java 文件操作 Java 输入流 Java 输入流 Java 文件输入流 Java 缓冲输入流 Java 推回输入流 Java 数据输入...

boonya
15分钟前
2
0
SDKMAN推荐一个好

是在大多数基于Unix的系统上管理多个软件开发工具包的并行版本的工具。它提供了一个方便的命令行界面(CLI)和API来安装,切换,删除和列出sdk相关信息。以下是一些特性: By Developers, fo...

hotsmile
40分钟前
8
0
什么是 HDFS

是什么? HDFS 是基于 Java 的分布式文件系统,允许您在 Hadoop 集群中的多个节点上存储大量数据。 起源: 单机容量往往无法存储大量数据,需要跨机器存储。统一管理分布在集群上的文件系统称...

Garphy
43分钟前
5
0
一起来学Java8(四)——复合Lambda

在一起来学Java8(二)——Lambda表达式中我们学习了Lambda表达式的基本用法,现在来了解下复合Lambda。 Lambda表达式的的书写离不开函数式接口,复合Lambda的意思是在使用Lambda表达式实现函...

猿敲月下码
今天
10
0
debian10使用putty配置交换机console口

前言:Linux的推广普及,需要配合解决实际应用方能有成效! 最近强迫自己用linux进行实际工作,过程很痛苦,还好通过网络一一解决,感谢各位无私网友博客的帮助! 系统:debian10 桌面:xfc...

W_Lu
今天
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部