Android应用与服务器的桥梁-HttpUrlConnection
1. 实例化URL对象
首先第一步实例化一个URL对象,传入参数为请求的数据的网址。
URL url = new URL("http://www.imooc.com/api/teacher?type=3&cid=1");
2. 获取HttpURLConnection对象
调用URL对象的openConnection方法将返回一个URLConnection对象,而URLConnection类为HttpURLConnection类的父类,可强制转换为我们需要的HttpURLConnection对象。
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
3. 设置请求连接属性
可通过第二步获取的HttpURLConnection对象设置连接的属性,例如setRequestMethod设置连接类型“GET”或“POST”、setReadTimeout设置读取超时时限等等。
conn.setRequestMethod("GET");
conn.setReadTimeout(6000);
4. 获取响应码
响应码用于确认是否连接结果,若返回值为HttpURLConnection.HTTP_OK(200)则连接成功。
conn.getResponesCode();
5. 读取并解析输入流
通过HttpURLConnection对象可以获取到一个输入流,选取适当的方式将输入流的内容读取到本地,再进行解析。
可以直接用JSONObject进行解析,也可以用第三方框架,推荐使用gson。
if (conn.getResponesCode() == 200) {
InputStream in = conn.getInputStream();
byte[] b = new byte[1024 * 512];
int len = 0;
//建立缓存流,保存所读取的字节数组
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((len = in.read(b)) > -1) {
baos.write(b, 0, len);
}
String msg = baos.toString();
//解析数据
JSONObject obj = new JSONObject(msg);
JSONObject data = obj.getJSONObject("data");
String title = data.getString("title");
String author = data.getString("author");
String content = data.getString("content");
}
gson解析数据简单介绍:
(1)gson解析普通json对象:gson的使用依赖于JSONObject,通过JSONObject对象的getString方法,以字符串形式获取相应数据,而后将其解析为指定类。
String data = obj.getString("data");//obj为JSONObject对象
Gson gson = new Gson();
Essay e = gson.fromJson(data, Essay.class);//第一个参数为json对象形式的字符串,第二个参数为自定义的类,需要将json对象解析成什么类型,就传入相应的类
(2)gson解析数组形式数据:
解析数组形式的数据,步骤与普通json对象基本一致,不同的是,这里fromJson方法的第一个参数为满足json数组形式的字符串,第二个参数则为一个Type对象,而Type对象需通过TypeToken对象的getType方法获取。
获取Type对象:new TypeToken<ArrayList
String data = new JSONObject(result).getString("data");//result为未解析的json字符串
Gson gson = new Gson();
Type listType = new TypeToken<ArrayList<Essay>>(){}.getType();
ArrayList<Essay> e = gson.fromJson(data, listType);
6. 将数据传递回主线程
由于网络操作不能在主线程中进行,而子线程又不允许对UI进行操作,因此需要将解析的数据传递回主线程。
通过使用Handler和Message进行线程之间的通信,代码请看下方完整例子。
7. 完整案例
布局xml:
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context="com.studying.network.DetailActivity">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:gravity="center"
android:textSize="24sp" />
<TextView
android:id="@+id/author"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:gravity="right"
android:paddingRight="10dp"
android:textSize="20sp" />
<TextView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:layout_marginTop="15dp"
android:layout_weight="1"
android:lineSpacingMultiplier="1.5"
android:textSize="20sp" />
</LinearLayout>
Activity:
public class DetailActivity extends Activity {
private TextView titleView, authorView, contentView;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Essay essay = (Essay) msg.obj;
titleView.setText(essay.getTitle());
authorView.setText(essay.getAuthor());
contentView.setText(essay.getContent());
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
initView();
initData();
}
public void initView() {
titleView = (TextView) findViewById(R.id.title);
authorView = (TextView) findViewById(R.id.author);
contentView = (TextView) findViewById(R.id.content);
}
public void initData() {
//网络操作不能在主线程中进行
new Thread(){
@Override
public void run() {
try {
URL url = new URL("http://www.imooc.com/api/teacher?type=3&cid=1");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(6000);
//获取响应码的同时会连接网络
if (conn.getResponseCode() == 200) {
InputStream in = conn.getInputStream();
byte[] b = new byte[512 * 1024];
int len = 0;
//将输入流的内容转存到字节数组流中
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((len = in.read(b)) > -1){
baos.write(b, 0, len);
}
String result = baos.toString();
//解析数据
JSONObject obj = new JSONObject(result);
JSONObject data = obj.getJSONObject("data");
String title = data.getString("title");
String author = data.getString("author");
String content = data.getString("content");
//通过Message将数据传递回主线程
Message message = handler.obtainMessage();
Essay essay = new Essay(title, author, content);//Essay为自定义类,用于传递多个值
message.obj = essay;
handler.sendMessage(message);//调用这个方法,会触发主线程中Handler对象里的handleMessage方法
conn.disconnect();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}.start();
}
}
Essay:
public class Essay {
private String title, author, content;
public Essay(String title, String author, String content) {
this.title = title;
this.author = author;
this.content = content;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
本文作学习交流用,如有错误,欢迎指正!