在完成了用户注册和登录页面的界面设计工作之后,我们就需要让我们的程序向后台发起请求,请求后台PHP程序实际进行用户注册操作。在新版本的Android系统中,所有的网络请求必须以异步的方式来进行,我们既可以通过线程方式也可以通过Android系统为我们提供的异步任务方式来完成,我们在这里选择采用异步任务的方式来进行网络操作。
根据异步任务的原理,当应用调用异步任务时,异步任务会在后台完成相应的网络操作,在完成之后,在onPostExecute方法中通知界面,更新操作状态。有两种方法可以完成这项任务,一种是将Activity对象放到异步任务类中,当需要更新界面时,直接调用该Activity对象的方法即可,另一种方式是传入Activity对象的Handler对象,当异步任务完成网络操作时,向Handler对象发送消息,由Handler对象来更新界面。从上面的分析可以看出,第一种方法使Activity和异步任务之间产生了紧耦合,是软件开发中不太提倡的,因此我们采用第二种方式,即采用Handler对象,异步任务通过发送消息通知Activity更新界面状态。我们首先在JysRegisterLoginActivity类中,定义与异步任务交互的Handler:
static protected class JysRegisterLoginHandler extends WkyRegisterLoginHandler {
public JysRegisterLoginHandler(JysRegisterLoginActivity activity) {
this.activity = activity;
}
public void handleMessage(Message msg) {
super.handleMessage(msg);
// 自己额外的处理
switch (msg.what) {
case WkyConstants.MSG_REGISTER_USER:
activity.processRegisterUserResult(msg);
break;
}
}
private JysRegisterLoginActivity activity = null;
}
在Activity的onCreate函数中,初始化这个Hanlder对象。
handler = new JysRegisterLoginHandler(this);
我们在用户点击注册按钮时,调用异步任务发起网络请求,请求PHP程序完成用户注册功能。
/**
* 点击注册/登录按钮
* 【闫涛 2015.09.16】初始版本
*/
protected void setRegisterOrLoginImgvOnClickListener() {
registerOrLoginImgv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("wky", "register or login to the system...");
if (wkyRegisterLoginModel.getState() == WkyRegisterLoginModel.STATE_REGISTER) {
registerUser();
} else if (wkyRegisterLoginModel.getState() == WkyRegisterLoginModel.STATE_LOGIN) {
Log.e("wky", "login the user");
}
}
});
}
protected void registerUser() {
Log.e("wky", "Regisger the user");
if (null == registerTask) {
registerTask = new WkyRegisterAsyncTask(this, handler);
String urlStr = WkyConstants.CMD_REGISTER_USER;
Log.e("wky", "url=" + urlStr + "!");
String body = prepareRegisterReqBody();
registerTask.execute(urlStr, body);
}
}
在这里顺便提一下编程规范的问题,大家看请求的URL是定义在WkyConstants里的一个常量,而不是直接写字符串,这样便于日后的代码维护。我们在代码中要尽量避免在代码中直接写数字和字符串,因为我们在维护时可能会忘记数字的含义,字符串容易在不同的地方写得不一致,造成比较难于调试的BUG。
下面是具体的异步任务类:
/**
* 异步任务开始前的回调函数
* 【闫涛 2015.09.24】初始版本
*/
@Override
protected void onPreExecute() {
Log.e("wky", "WkyRegisterAsyncTask.onPreExecute 1");
}
/**
* 具体异步任务执行函数
* 【闫涛 2015.09.24】初始版本
*/
@Override
protected String doInBackground(String... params) {
String urlStr = params[0];
String body = params[1];
return WkyHttpClient.doPost(urlStr, body);
}
/**
* 更新异步任务状态信息(在显示进度条时会用到)
* 【闫涛 2015.09.24】初始版本
*/
@Override
protected void onProgressUpdate(Integer... progress) {
}
/**
* 异步任务结束时要调用的方法,通知页面进行更新
* 【闫涛 2015.09.24】初始版本
*/
@Override
protected void onPostExecute(String result) {
Log.e("wky", "new:" + result);
Message msg = handler.obtainMessage();
msg.what = WkyConstants.MSG_REGISTER_USER;
Bundle params = new Bundle();
params.putString(WkyConstants.MSG_DATA_NAME, result);
msg.setData(params);
handler.dispatchMessage(msg);
}
public void processRegisterUserResult(Message msg) {
String jsonStr = msg.getData().getString(WkyConstants.MSG_DATA_NAME);
JSONObject json = null;
String status = null;
long userId = 0;
try {
json = new JSONObject(jsonStr);
status = json.getString("status");
userId = json.getLong("userId");
Log.e("wky", "^_^ registerUser:" + status + "; u=" + userId + "!");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
下面是具体发起网络请求的类:
/**
* 普通POST请求,窗体形式,没有文件上传操作
* @param urlStr
* @param data 以JSON格式存在
* @return 响应字符串
* 【闫涛 2015.09.23】初始版本
*/
public static String doPost(String urlStr, String data) {
HttpURLConnection conn = null;
OutputStreamWriter outStream = null;
StringBuilder result = new StringBuilder();
try {
URL url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestProperty("charset", "utf-8");
conn.setRequestMethod(POST);
conn.setRequestProperty("Content-type",
"application/x-www-form-urlencoded");
conn.setConnectTimeout(TIMEOUT);
conn.setReadTimeout(TIMEOUT);
conn.connect();
outStream = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
if (data != null) {
outStream.write(data);
}
outStream.flush();
outStream.close();
// }
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
result.append(readAsString(conn.getInputStream(), "UTF-8"));
}else{
Log.e("wky","ResponseCode:" + conn.getResponseCode());
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result.toString();
}
由于我们的网络请求处理比较简单,因此直接采用了Java的方法来进行网络请求。
华丽的分隔线
******************************************************************************************************************************************************************************
希望大家多支持,有大家的支持,我才能走得更远,谢谢!
银行账号:622202 0200 1078 56128 闫涛
我的支付宝:yt7589@hotmail.com