1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 最老程序员创业开发实训13---Android---网络请求与异步任务

最老程序员创业开发实训13---Android---网络请求与异步任务

时间:2021-11-20 12:07:53

相关推荐

最老程序员创业开发实训13---Android---网络请求与异步任务

在完成了用户注册和登录页面的界面设计工作之后,我们就需要让我们的程序向后台发起请求,请求后台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;}

需要注意的是,我们将JysRegisterLoginHandler声明为静态的内部类,因为如果只声明为内部类,有出现内存泄露的可能性。

在Activity的onCreate函数中,初始化这个Hanlder对象。

handler = new JysRegisterLoginHandler(this);

我们在用户点击注册按钮时,调用异步任务发起网络请求,请求PHP程序完成用户注册功能。

/*** 点击注册/登录按钮* 【闫涛 .09.16】初始版本*/protected void setRegisterOrLoginImgvOnClickListener() {registerOrLoginImgv.setOnClickListener(new View.OnClickListener() {@Overridepublic 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,另一个是Json格式的请求数据。

在这里顺便提一下编程规范的问题,大家看请求的URL是定义在WkyConstants里的一个常量,而不是直接写字符串,这样便于日后的代码维护。我们在代码中要尽量避免在代码中直接写数字和字符串,因为我们在维护时可能会忘记数字的含义,字符串容易在不同的地方写得不一致,造成比较难于调试的BUG。

下面是具体的异步任务类:

/*** 异步任务开始前的回调函数* 【闫涛 .09.24】初始版本*/@Overrideprotected void onPreExecute() {Log.e("wky", "WkyRegisterAsyncTask.onPreExecute 1");}/*** 具体异步任务执行函数* 【闫涛 .09.24】初始版本*/@Overrideprotected String doInBackground(String... params) {String urlStr = params[0];String body = params[1];return WkyHttpClient.doPost(urlStr, body);}/*** 更新异步任务状态信息(在显示进度条时会用到)* 【闫涛 .09.24】初始版本*/@Overrideprotected void onProgressUpdate(Integer... progress) {}/*** 异步任务结束时要调用的方法,通知页面进行更新* 【闫涛 .09.24】初始版本*/@Overrideprotected 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);}

从上面的代码中可以看出,在doInBackground中调用网络POST请求方法,发送POST请求。这里重点是在onPostExecute方法中,生成一个Message对象,将POST响应字符串,添加到Message对象中,然后向Handler对象发送消息。在前面Handler类的代码中,接收到这个消息,就会调用相相应的方法来处理响应结果了。代码如下所示:

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 blocke.printStackTrace();}}

在这里我们什么也没做,只是把响应结果变为json对象,从中取出status和userId等项目,在实际的代码中,我们需要记录下用户的信息,然后转到应用首页中去。

下面是具体发起网络请求的类:

/*** 普通POST请求,窗体形式,没有文件上传操作* @param urlStr* @param data 以JSON格式存在* @return 响应字符串* 【闫涛 .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@

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。