0%

Android网络编程实例

这次简单的通过使用okhttpnode.js来实现Android与服务端交互。
使用node.js作为服务端是因为其配置和开发都比较简便,在windows平台上也能很快搭建起环境;
在开发Android应用时,这种快速构建的“后端”,可以用来在真正的服务端开发完成前,Mock后端数据,来验证应用网络接口的正确性。

node.js的安装过程很简单,在此就略过了,直接进入代码编写^_^

首先来写“后端”的程序逻辑,在这里我们假设3个不同的请求响应:
1.返回一端普通文本
2.返回json数据
3.异常资源返回404错误
testServer.js文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
var http = require("http")
var url = require("url")

// 将请求资源封装在这个对象中,来简化不同url资源访问逻辑
// 借鉴自这篇教程:http://www.nodebeginner.org/index-zh-cn.html
var handle = {}
handle["/"] = mainResponse
handle["/getexample"] = getExampleResponse
handle["/getjsonexample"] = getJsonResponse

// 整个后端逻辑封装到一个函数中
function start() {
function onRequest(request, response) {
var pathname = url.parse(request.url).pathname
console.log("pathname is: " + pathname)


if (pathname == "/favicon.ico") { // 用浏览器调试时忽略掉favicon.ico图标的请求
return
} else if (typeof handle[pathname] === "function") { // 请求url与handle配置相同时,执行相应函数
handle[pathname](response)
} else { // 未知url资源返回404页面
response.writeHead(404, {"Content-Type": "text/plain"})
response.write("404 page not found")
response.end()
}
}

http.createServer(onRequest).listen(80)
console.log("testServer has started");

function mainResponse(response) {
response.writeHead(200, {"Content-Type": "text/plain"})
response.write("main response from server")
response.end()
}

// 访问"/getexample"时的处理
function getExampleResponse(response) {
response.writeHead(200, {"Content-Type": "text/plain"})
response.write("getExample response from server")
response.end()
}

// 请求json时的处理
function getJsonResponse(response) {
var testJson = "{" +
"\"name\":\"看不见的森林\"," +
"\"author\":\"乔治 哈斯凯尔\"," +
"\"isbn\":\"9787100104685\"," +
"\"price\":\"46\"" +
"}"
response.writeHead(200, {"Content-Type": "application/json;charset=utf-8"})
response.write(testJson)
response.end()
}
// 启动服务
start()

启动Node后端,在命令行输入命令:

1
node testServer.js

接下来编写Android app,在界面中简单添加三个按钮,分别对应“请求文本”,“请求json”,“404”三个操作。
在这里,网络请求使用了okhttp,通过asynctask来处理网络请求,用Gson来解析json对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
public class MainActivity extends Activity {

private Button mButton;
private Button getJsonButton;
private Button get404Button;

private TextView mText;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

initViews();
}

// 初始化视图绑定点击事件
private void initViews() {
mButton = (Button) findViewById(R.id.test_button);
getJsonButton = (Button) findViewById(R.id.get_json_button);
get404Button = (Button) findViewById(R.id.get_404_button);
mText = (TextView) findViewById(R.id.test_text);

mButton.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// 点击事件中启用后台线程发起请求,下同
new MyAsyncTask().execute("http://172.22.177.97/getexample", "text");
}
});

getJsonButton.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
new MyAsyncTask().execute("http://172.22.177.97/getjsonexample", "json");
}
});

get404Button.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
new MyAsyncTask().execute("http://172.22.177.97/404", "text");
}
});
}

// 自定义的AsyncTask类,来处理网络请求
class MyAsyncTask extends AsyncTask<String, Integer, String> {

@Override
protected String doInBackground(String... params) {
// 初始化OkHttpClient以及Resquest对象,url是传递进来的String
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(params[0])
.build();

try {
String extra;
Response res = client.newCall(request).execute();

String bodyString = res.body().string();

if (res.code() == 404) { // 404页面
return bodyString;
} else if (res.code() == 200) {
if(params[1].equals("json")) { // 当请求json时,通过Gson来生成json对象
Gson gson = new Gson();
Book book = gson.fromJson(bodyString, Book.class);
Log.i("20160905", book.toString());
extra = bodyString + "\nobject: " + book.toString();
return extra;
}
return bodyString;
}
return "response unkown";
} catch (IOException e) {
e.printStackTrace();
return "response exception";
}
}

@Override
protected void onPostExecute(String result) {
mText.setText(result);
mText.setTextColor(Color.BLACK);
if (result.startsWith("404")) { // 如果是404页面,将textView字符设定成红色
mText.setTextColor(Color.RED);
}
}

}
}

对应json的Book类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.example.nettest;

public class Book {

private String name = "";
private String author = "";
private String isbn = "";
private float price = 0.0f;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}

@Override
public String toString() {
return name + ", " + author + ", " + isbn + ", " + price;
}
}

后续一些其他的样例可以在此基础上进行扩展。