您的位置:首页 > 理论基础 > 计算机网络

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

2015-10-03 15:56 585 查看
一、获取请求网页的响应源码(网页源码查看器)

步骤:

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 北京市海淀区
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: