从这节开始我们讲解Android网络通信。计划讲解内容:
- 获取文本数据
- 获取网络图片
- 获取XML
- 获取JSON
- 发送GET请求
- 发送POST请求
- HttpClient发送GET请求
- HttpClient发送POST请求
- 开源项目AsyncHttpClient
- HTTP协议上传文件
- 发送XML,访问WebService
- 多线程断点续传下载器
一、获取文本数据
- 使用URL封装一个地址
- openConnection()得到HttpUrlConnection对象
- getResponseCode()得到响应码
- getInputStream()得到输入流读取数据
访问网络的权限<uses-permission android:name="android.permission.INTERNET" />
注意: 安卓4.0以后联网需要开启新线程, 在新线程中操作界面还需要使用Handler
1.1网络请求
创建网络请求
public class TextService {
public String getText(String path) throws Exception {
URL url = new URL(path); // 把路径封装成URL对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 打开连接对象(还未联网)
conn.setConnectTimeout(5000); // 设置超时时间, 如果连接超过5000毫秒未响应, 就抛出异常
int code = conn.getResponseCode(); // 获取响应码(真正联网)
if (code == 200) { // 如果成功
InputStream in = conn.getInputStream(); // 获取输入流
ByteArrayOutputStream out = new ByteArrayOutputStream(); // 可以写出数据到内存的输出流
byte[] buffer = new byte[8192];
int length;
while ((length = in.read(buffer)) != -1) // 从网络读取数据
out.write(buffer, 0, length); // 向内存写出数据
in.close();
out.close();
conn.disconnect();
byte[] data = out.toByteArray(); // 把写到内存的数据读取出来
String text = new String(data); // 解码为字符串(默认UTF-8)
return text;
}
conn.disconnect();
throw new NetworkErrorException("网络错误: " + code);
}
}
我们的布局
<RelativeLayout 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: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=".ClassicActivity" >
<Button
android:id="@+id/bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:onClick="go"
android:text="GO" />
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/bt"
android:layout_toLeftOf="@id/bt"
android:hint="请输入要访问的地址"
android:inputType="textUri" />
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/et" />
</RelativeLayout>
Activity中开发送网络请求
public class MainActivity extends Activity {
private EditText et;
private TextView tv;
private TextService service;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = (EditText) findViewById(R.id.et);
tv = (TextView) findViewById(R.id.tv);
service = new TextService();
}
public void go(View v) {
new Thread() {
public void run() {
try {
String path = et.getText().toString().trim(); // 从EditText获取地址
final String text = service.getText(path); // 访问网络, 得到文本
handler.post(new Runnable() {
public void run() {
tv.setText(text); // 设置到TextView中
}
});
} catch (Exception e) {
e.printStackTrace();
handler.post(new Runnable(){
public void run() {
Toast.makeText(getApplicationContext(), "服务器忙, 请稍后再试!", Toast.LENGTH_SHORT).show();
}
});
}
}
}.start();
}
}