在平时的开发中,经常把所有的操作都写在activity中,是不是感觉很不爽,那么怎么实现把部分的逻辑分离开呢?这里使用监听器模式实现一个把网络请求或者数据库操作等的逻辑分离的方式(观察者方式实现也是一样的)
首先看看我们的action
package com.test.action;
import java.util.Map;
import android.content.Context;
import com.example.okhttpdemo.HttpUtils;
import com.example.okhttpdemo.HttpUtils.HttpCallback;
import com.test.model.Msg;
public abstract class BaseAction {
public Context context;
public ActionListener l;
public HttpUtils httpUtils=new HttpUtils();
public BaseAction(Context c,ActionListener l) {
// TODO Auto-generated constructor stub
this.context=c;
this.l=l;
}
/**
* post请求 map为参数
* @param requestType 请求的类型type
* @param url 请求的url
* @param map 请求参数
*/
public void postMap(int requestType,String url, Map<String, Object> map){
httpUtils.postMap(url, map, new HttpCallback() {
@Override
public void onError(int requestType, String msg) {
// TODO Auto-generated method stub
super.onError(requestType, msg);
notifyError(requestType,msg);
}
@Override
public void onSuccess(int requestType, String response) {
// TODO Auto-generated method stub
notifySuccess(requestType, response);
}
},requestType);
}
public abstract void onSuccess(int requestType,Msg msg, String data);
public abstract void onError(int requestType, Msg msg,String data);
/**
* 成功时通知更新
* @param requestType
* @param data
*/
public void notifySuccess(int requestType,String data){
Msg msg=new Msg();
onSuccess(requestType,msg, data);
notifyData(msg, requestType, true);
}
/**
* 错误时通知更新
* @param requestType
* @param data
*/
public void notifyError(int requestType,String data){
Msg msg=new Msg();
onError(requestType,msg, data);
notifyData(msg, requestType, false);
}
/**
* 更新数据
* @param msg
* @param requestType
* @param isSuccess
*/
public void notifyData(Msg msg,int requestType,boolean isSuccess){
msg.setRequestType(requestType);
msg.setSuccess(isSuccess);
if(null != l){
if(isSuccess){
l.onSuccess(msg);
}else{
l.onError(msg);
}
}
}
/**
* action回调
* @author Flyjun
*
*/
public static interface ActionListener{
public void onSuccess(Msg msg);
public void onError(Msg msg);
}
}
HttpUtils为上篇中的网络请求工具类,postMap为简单的post请求,更多的可以自己封装,notifySuccess为请求成功时的回调,notifyError为失败时的回调,notifyData是更新数据到activity界面上的操作,不过我们在操作的时候不用手动调用,下面看看TestAction
package com.test.action;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import com.test.model.Msg;
public class TestAction extends BaseAction{
public TestAction(Context c, ActionListener l) {
super(c, l);
// TODO Auto-generated constructor stub
}
public void test(String url){
postMap(1000, url, null);
}
@Override
public void onSuccess(int requestType, Msg msg, String data) {
// TODO Auto-generated method stub
switch (requestType) {
case 1000:
try {
JSONObject json=new JSONObject(data);
String date=json.getString("date");
msg.setData(date);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
default:
break;
}
}
@Override
public void onError(int requestType, Msg msg, String data) {
// TODO Auto-generated method stub
}
}
这时候请求回来后我们直接在onSuccess或者onError上操作就ok了,这里有个Msg类,这个是我们封装的存放数据的类,可以根据需求进行修改,这时我们只需要解析的数据放到msg上就ok了,这样是不是简单了许多。下面来看看怎么使用
package com.test.activity;
import android.app.Activity;
import android.os.Bundle;
import com.test.action.BaseAction.ActionListener;
public abstract class BaseActivity extends Activity implements ActionListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
}
package com.test.activity;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import android.os.Bundle;
import com.test.action.TestAction;
import com.test.model.Msg;
public class TestActivity extends BaseActivity{
String url;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
String cityName="广州";
try {
url="http://api.map.baidu.com/telematics/v3/weather?location="+URLEncoder.encode(cityName, "utf-8")+"&output=json&ak=GuZriL3rkm1MUnyTyfsNGvTC";
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
TestAction ta=new TestAction(this, this);
ta.test(url);
}
@Override
public void onSuccess(Msg msg) {
// TODO Auto-generated method stub
System.out.println(""+msg.getRequestType());
System.out.println(""+msg.getData());
}
@Override
public void onError(Msg msg) {
// TODO Auto-generated method stub
}
}
同意的在activity上我们只要在onSuccess上更新ui就ok!
附上Msg类
package com.test.model;
import android.os.Parcel;
import android.os.Parcelable;
public class Msg implements android.os.Parcelable{
/**
* 请求type
*/
public int requestType;
/**
* 请求是否成功
*/
public boolean isSuccess;
/**
* code
*/
public int code;
/**
* 封装的数据
*/
public Object data;
/**
* 捆绑的数据
*/
public Object bundle;
/**
* 其它的数据
*/
public Object other;
public int getRequestType() {
return requestType;
}
public void setRequestType(int requestType) {
this.requestType = requestType;
}
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Object getBundle() {
return bundle;
}
public void setBundle(Object bundle) {
this.bundle = bundle;
}
public Object getOther() {
return other;
}
public void setOther(Object other) {
this.other = other;
}
public Msg() {
// TODO Auto-generated constructor stub
}
public Msg(Parcel parcel) {
// 按变量定义的顺序读取
requestType=parcel.readInt();
code=parcel.readInt();
data=parcel.readValue(Object.class.getClassLoader());
bundle=parcel.readValue(Object.class.getClassLoader());
other=parcel.readValue(Object.class.getClassLoader());
}
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
// TODO Auto-generated method stub
dest.writeInt(requestType);
dest.writeInt(code);
dest.writeValue(data);
dest.writeValue(bundle);
dest.writeValue(other);
}
public static final Parcelable.Creator<Msg> CREATOR = new Parcelable.Creator<Msg>() {
@Override
public Msg createFromParcel(Parcel source) {
return new Msg(source);
}
@Override
public Msg[] newArray(int size) {
return new Msg[size];
}
};
@Override
public String toString() {
return "Msg [requestType=" + requestType + ", isSuccess=" + isSuccess
+ ", code=" + code + ", data=" + data + ", bundle=" + bundle
+ ", other=" + other + "]";
}
}
这样操作,代码是不是简明了许多!