http请求是耗时操作,如果把它放到主线程上,会造成UI线程阻塞,android在API8以后不允许开发者将网络耗时操作放到主线程上进行.对于开子线程进行http请求,从服务器返回的数据,需要主线程来处理,并更新UI,子线程不能更新UI,所以这里涉及到子线程和主线程的通信.android提供handler消息处理机制来实现线程通信,子线程将网络返回结果通过发送消息的形式通知主线程,主线程接收消息,处理数据,并进行UI操作,这样就实现了整个客户端向服务器发送请求并接收请求,处理请求的过程.对于子线程设计,这里建议采取线程模板设计的方式.步骤如下

首先,自定义模板线程,继承线程类,把它设置成抽象类,作为具体线程的父类

public abstract class BaseThread extends Thread {


protected String requestURL;

protected Map resultMap;

protected Map requestParams;

protected List resultList;

protected Handler mHandler;

protected Message msg;

protected String stateId;


/**

* handler是关于主线程的交互类

* stateId是与主线程的message的标识号

*

* @param mHandler

* @param stateId

*/

stateID用以作为message的标签

public BaseThread(Handler mHandler, String stateId) {

this.mHandler = mHandler;

this.stateId = stateId;

}

其次,设计一个方法,用以初始化http具体请求的url,和请求参数

/**

* 设置POST表单的参数和请求主机的位置

*

* @param requestURL

* @param requestParams

*/

public void setRequestPrepare(String requestURL, Map requestParams) {

this.requestURL = requestURL;

this.requestParams = requestParams;

}

然后,设计一个方法,用来获取从服务器得到的字符串经过处理后的Map表,此方法为主线程服务.


/**

* 获取返回结果,结果为Map形式的

*

* @return

*/

public Map getResultMap() {

if (this.resultMap != null) {

return (this.resultMap);

} else {

this.resultMap = new HashMap();

return (this.resultMap);

}


}

设计一个方法,用以判断请求成功与否

/**

* 根据httpUtils类返回的字符串来确定请求成功与否

* @param str

* @return

*/

protected boolean dealRequestState(String str) {


if (str != null) {

if (str.equals("paramsException")) {

return (false);

} else if (str.equals("singleTonException")) {

return (false);

} else if (str.equals("InterNetException")) {

return (false);

} else if (str.equals("switchException")) {

return (false);

} else {

return (true);

}

} else {

Log.i("lzw","null");

return (false);

}

}

随后,设计一个方法,用来存放网络状态的消息

/**

* 通知主线程加载的状态

*

* @param key

* @param state

*/

protected void setLoadState(String key, int state) {

this.msg = new Message();

Bundle bd = new Bundle();

bd.putInt(key, state);

this.msg.setData(bd);

}

该方法用以检查请求参数

protected void checkRequestMap()

{

Iterator it=this.requestParams.entrySet().iterator();

while(it.hasNext())

{

Map.Entry<String,String> entry=(Map.Entry<String,String>)it.next();

Log.i("lzw",entry.getKey());

Log.i("lzw",entry.getValue());

}

}

最后,来实现run方法

/**

* 主要的线程体方法,先是请求服务器,

* 将服务器的返回的结果(字符)交给子类的实例化的方法来

*/

public void run() {

this.checkRequestMap();

// Log.i("lzw","URL="+this.requestURL);

try {

//上一篇文章用到的用以实现发送http请求httputils

//实现发送请求方法,请求参数和路径由主线程通过调用setRequestPrepare方法初始化

//HttpUtils执行requestHttpSever方法,得到返回字符串存放在变量responseStr中

String responseStr =

HttpUtils.requestHttpServer(this.requestURL, this.requestParams,

ComParameter.ENCODE_UTF_8, ComParameter.ENCODE_UTF_8);

//通过调用dealRequestState函数来判断服务器连接状态,传入参数为服务器返回字符串

if (!this.dealRequestState(responseStr)) {

//没有返回成功,保存错误消息

this.setLoadState(this.stateId, ComParameter.STATE_ERROR);

//将错误消息发送给主线程,交给主线程handler处理

this.mHandler.sendMessage(this.msg);


return;

}

//若果返回的字符串正常,处理返回字符,以map的形式存放,这个方法为抽象方法,放在子类中进行

this.dealReponseString(responseStr);

//告诉主线程,返回成功

this.setLoadState(this.stateId, ComParameter.STATE_RIGHT);

this.mHandler.sendMessage(this.msg);

} catch (Exception e) {

this.setLoadState(this.stateId, ComParameter.STATE_ERROR);

this.mHandler.sendMessage(this.msg);

e.printStackTrace();

}

}

将处理返回字符串的方法,作为抽象方法,因为不同的请求返回的字符串可能不一样,放在子类处理

protected abstract void dealReponseString(String responseString) throws Exception;


下面写一个子类用来继承线程模板,处理返回字符串的示例

public class FirstLoginRequestThread extends BaseThread {


public FirstLoginRequestThread(Handler mHandler, String stateId) {

super(mHandler, stateId);

}


protected void dealReponseString(String responseString) throws Exception{

//这里的resultMap是父类属性,这个方法用来处理服务器返回字符串,向父类的Map添加内容,为主线程得到返回参数服务

this.resultMap = new HashMap<String, String>();

String tmpArrStr[] = responseString.split(":");

if (tmpArrStr[1].equals("login")) {

String tmpArrStr1[]=tmpArrStr[2].split("[+]");


this.resultMap.put(tmpArrStr[0], tmpArrStr[1]);

this.resultMap.put("type", tmpArrStr1[0]);

this.resultMap.put("dataBaseId", tmpArrStr[3]);



} else if (tmpArrStr[1].equals("unlogin")) {

this.resultMap.put(tmpArrStr[0], tmpArrStr[1]);

this.resultMap.put("failReason", tmpArrStr[2]);

}


Log.i("lzw",responseString);



}

}



更多相关文章

  1. 【边做项目边学Android】异常处理:android.os.NetworkOnMainThrea
  2. Android中Math取整的三个方法
  3. Android Studio启动时卡在Fetching Android SDK 以及导入Eclipse
  4. 总结线程交互
  5. Google 菜市场(Android Market)上不去的解决方法

随机推荐

  1. Android上通过gcc编译普通的C程序
  2. 分析android的usb-gadget
  3. Android ​自定义RadioButton或CheckBox
  4. Google 2018 更新内容
  5. Android SDK安装失败处理办法
  6. 一张图看明白 Android Handler 消息机制
  7. Android4.1 关于Rotation相关的Configura
  8. Android中WARNING: Application does not
  9. Android 判断Intent是否存在
  10. Android(安卓)Gradle 看这一篇就够了