Android开发之基础------------------网络编程(一)
2015-10-03 15:56
585 查看
一、获取请求网页的响应源码(网页源码查看器)
步骤:
1.写布局文件 布局文件说明:文本输入框用于输入请求的地址 设置按钮用于点击获取网页源码 显示在文本域中 文本域设置为带滚动条
逻辑部分:1.获取控件 设置按钮点击事件(获取源码) 使用handler处理UI更新操作(将获取的源码显示到文本域中)
工具类:将字节流转换成字符串
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界面的显示
代码体现:
做个努力奋斗的男子汉,实现自己一个又一个梦想吧,走在实现梦想的路上,浑身充满了能量!加油吧,越努力越幸运。
2015-10-3 北京市海淀区
步骤:
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 北京市海淀区
相关文章推荐
- 采用tcpdump攫Android网络数据包
- 孤儿进程组http://blog.chinaunix.net/uid-27767798-id-3711413.html
- Lighttpd工作流程
- TCP/IP详解卷1 读书笔记:第九章 IP选路
- linux 技巧:使用 screen 管理你的远程会话http://www.ibm.com/developerworks/cn/linux/l-cn-screen/
- UNP v1 第一章:简介
- Linux--进程组、会话、守护进程 http://www.cnblogs.com/forstudy/archive/2012/04/03/2427683.html
- 进程组 http://blog.163.com/li_xiang1102/blog/static/60714076201110294573495/
- 会话、进程组、进程个人理解。http://bbs.chinaunix.net/thread-2176051-1-1.html
- 计算机网络学习笔记——概述
- 动手学习TCP:客户端状态变迁
- 基于Java的Http服务器几种模式演进
- 《深入理解Linux网络技术内幕》阅读笔记(十二)
- Jmeter之HTTP Request Defaults
- android中的HttpClient,Delete请求
- html meta标签中name和http-equiv的区别
- Jmeter之Http Cookie Manager
- 挂起终端 http://www.educity.cn/linux/1590402.html
- http协议、http事务、URL、http请求的方式、响应码信息、http1.0和1.1区别
- 数据库中DDL、DML、DCL和TCP概念