Android开发之基础------------------网络编程(一)


一、获取请求网页的响应源码(网页源码查看器)

步骤:

1.写布局文件       布局文件说明:文本输入框用于输入请求的地址       设置按钮用于点击获取网页源码     显示在文本域中   文本域设置为带滚动条

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/et_inputurl"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="请输入url" />

    <Button
        android:id="@+id/bt_getsource"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_marginTop="10dp"
        android:text="获取源码" >
    </Button>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/tv_showsource"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>
    </ScrollView>

</LinearLayout>

逻辑部分:1.获取控件   设置按钮点击事件(获取源码)     使用handler处理UI更新操作(将获取的源码显示到文本域中)      

package com.itheima.sourcecode_look;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import com.itheima.sourcecode_look.utils.StreamUtils;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {

	private EditText et_inputurl;
	private Button bt_getsource;
	private TextView tv_showsource;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//找到控件设置点击事件
		et_inputurl = (EditText) findViewById(R.id.et_inputurl);
		bt_getsource = (Button) findViewById(R.id.bt_getsource);
		tv_showsource = (TextView) findViewById(R.id.tv_showsource);
		bt_getsource.setOnClickListener(this);
		System.out.println("oncreate:"+Thread.currentThread().getName());

	}
	
	
	//***1.在主线程创建一个Handler对象
	Handler handler = new Handler(){
		
		//***2.重新handlerMessage方法
		public void handleMessage(android.os.Message msg) {
			//***5.主线程的handler对象中的handleMessage方法接收子线程发来的Message对象,获取message携带的数据,并处理数据
			String result = (String) msg.obj;
			//7.显示到textView上
			tv_showsource.setText(result);
			
		};
		
	};
	
	@Override
	public void onClick(View v) {

		
		
		//获取用户输入的url
		final String url_str = et_inputurl.getText().toString().trim();
		
		//由于4.0之后网络请求需要放到子线程,所以创建子线程执行网络请求
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				
				

				//请求服务器获取源码
				try{	
					//1.获取一个URL对象
					URL url = new URL(url_str);
					//2.通过URL对象得到一个HttpURLConnection对象
					HttpURLConnection openConnection = (HttpURLConnection) url.openConnection();
					//3.设置HttpUrlConnection的一些参数,如:连接的超时时间,请求方式
					openConnection.setRequestMethod("GET");//设置连接的请求方式,类型一定要大写
					openConnection.setConnectTimeout(10*1000);//设置连接的超时时间
					//4.获取服务器响应的状态码,并判断
					int code = openConnection.getResponseCode();
					System.out.println("onclick:"+Thread.currentThread().getName());
					
					if(code == 200){//200 成功 206 请求部分资源成功   300 跳转  400 失败  500 服务器异常
						//5.得到连接的读取流,获取服务返回的内容。
						InputStream inputStream = openConnection.getInputStream();
						String result = StreamUtils.streamToString(inputStream);
						
						//***3.在子线程创建一个Message对象,用来携带子线程处理的结果
						Message msg = new Message();
						msg.obj  =  result;
						//***4.通过主线程创建的Handler来发送message对象到主线程
						handler.sendMessage(msg);
						
						//6.关闭链接 关闭流
						openConnection.disconnect();
						inputStream.close();	
					}
				
				}catch (Exception e) {
					e.printStackTrace();
				}
			}
		}).start();
	}
}
工具类:将字节流转换成字符串

package com.itheima.sourcecode_look.utils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class StreamUtils {

	public static String streamToString(InputStream inputStream) {
		ByteArrayOutputStream  out = null;
		try{

			//创建一个内存写入流
			out = new ByteArrayOutputStream();

			byte[] buffer = new byte[1024];
			int len  = -1;
			while((len = inputStream.read(buffer)) != -1){
				out.write(buffer, 0, len);
				out.flush();
			}

			return out.toString();
		}catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				if(out != null)
					out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

}
注意事项:

1.ANR异常: anr(application not response)  主线程不能做耗时的操作(网络请求,大文件的拷贝,数据库的操作)
09-14 01:46:43.352: E/ActivityManager(858): ANR in com.itheima.sourcecode_look (com.itheima.sourcecode_look/.MainActivity)

2.网络运行在主线程异常。4.0版本之后google强制要求网络请求在子线程执行。
09-14 01:52:48.813: W/System.err(698): android.os.NetworkOnMainThreadException


3. 错误的线程调用异常:子线程不能够修改UI界面
09-14 01:57:06.213: W/System.err(764): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.


结论:主线程不能够做耗时的操作,耗时的操作需要放到子线程做,但是子线程又不能更新UI(改变控件的内容和样式).  使用Handler解决这个问题。
Handler:消息处理机制   用于解决子线程不能更新UI。

写法步骤:

1.在主线程创建一个Handler对象
2.重写handler对象的handlerMessage方法
3.在子线程中创建一个Message对象用来携带子线程处理的结果。
4.使用主线程创建的handler在子线中将message发送到主线程
5.主线程中handler对象的handlerMessage方法接受子线程发送的Message对象,
获取message对象携带的数据,并处理UI界面的显示 

代码体现:

//***1.在主线程创建一个Handler对象
				Handler handler = new Handler(){
					
					//***2.重新handlerMessage方法
					public void handleMessage(android.os.Message msg) {
						//***5.主线程的handler对象中的handleMessage方法接收子线程发来的Message对象,获取message携带的数据,并处理数据
						String result = (String) msg.obj;
						//7.显示到textView上
						tv_showsource.setText(result);
						
					};
					
				};

//***3.在子线程创建一个Message对象,用来携带子线程处理的结果
						Message msg = new Message();
						msg.obj  =  result;
						//***4.通过主线程创建的Handler来发送message对象到主线程
						handler.sendMessage(msg);


做个努力奋斗的男子汉,实现自己一个又一个梦想吧,走在实现梦想的路上,浑身充满了能量!加油吧,越努力越幸运。

2015-10-3  北京市海淀区

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值