Android架构: MVC 模式加载数据 前台显示

openkk 12年前

由于项目的需要,最近研究了一下需要连接网络项目的MVC架构,参考了一下一个新浪微博的开发架构

大体描述如下

需求:项目中接口很多,联网操作在Activity中处理会非常浩大且那一维护

解决方案:将数据提供层和表现层分开,数据层请求接口的数据 , Activity只处理从数据层来的数据,

 

那我们看一下Activity的实现:

首先定义了一个接口用于规范将来的activty中的方法

package com.testaijialogic;    public interface IAijiaActivity {     void init();// 初始化数据     void initView();// 初始化界面控件     void refresh(Object... param);// 刷新 内容 不知道可变参数的可以再去学习下coreJva    }

然后是Activity

package com.testaijialogic;    /**   * MVC   * M 提供数据   * V 显示给用户   * C 把M的数据显示到视图   */  import java.util.HashMap;  import java.util.List;    import com.testaijialogic.domain.PersonEntity;  import com.testaijialogic.widget.PersonAdapter;    import android.app.Activity;  import android.app.ProgressDialog;    import android.content.Context;  import android.content.Intent;  import android.os.Bundle;  import android.util.Log;  import android.view.View;  import android.widget.Button;  import android.widget.ListView;    public class TestAijiaLogicActivity extends Activity implements IAijiaActivity {   private Context context;   private ListView listView;   private ProgressDialog progressDialog;   private Button button;   private ListView listView2;     public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);    context = TestAijiaLogicActivity.this;    Intent intent = new Intent("com.testaijialogic.MainService");// 在首个Activity开启服务    startService(intent);    initView();    init();    Log.i("Create", "=====");     }     protected void onPause() {      super.onPause();    Log.i("onPause", "=====");   }     protected void onResume() {      super.onResume();    Log.i("onResume", "=====");   }     protected void onDestroy() {      super.onDestroy();    android.os.Process.killProcess(android.os.Process.myPid());     }     @Override   public void init() {// 初始化list的数据    @SuppressWarnings("rawtypes")    HashMap param = new HashMap();    param.put("product", "testTask");    // 加载搜索页面微博信息的任务    MainService.addActivity(TestAijiaLogicActivity.this);    Task task = new Task(Task.GETPRODUCT, param, context);    MainService.newTask(task);// 添加新任务    progressDialog.show();     }     @Override   public void refresh(Object... param) {    @SuppressWarnings("unchecked")    HashMap map = (HashMap) param[0];// 获取map的数据      List<PersonEntity> personlist = (List<PersonEntity>) map.get("product");    PersonAdapter personAdapter = new PersonAdapter(context, personlist);    listView.setAdapter(personAdapter);      List<PersonEntity> subpersonlist = (List<PersonEntity>) map// 加载第二个listview      .get("subproduct");    PersonAdapter subpersonAdapter = new PersonAdapter(context,      subpersonlist);    listView2.setAdapter(subpersonAdapter);    progressDialog.dismiss();    Log.i("测试", "setadapter");     }     public void initView() {    listView = (ListView) findViewById(R.id.listView1);    listView2 = (ListView) findViewById(R.id.listView2);    button = (Button) findViewById(R.id.button1);    button.setOnClickListener(new View.OnClickListener() {       @Override     public void onClick(View v) {      init();     }    });    progressDialog = new ProgressDialog(this);    progressDialog.setMessage("正在获取数据");     }  }

可以看到,表现层只是把数据展示到xml中,没有牵扯到请求接口

 

下面是数据请求层

 

package com.testaijialogic;  /**   * 任务实体,由于储存认为信息   */  import java.util.HashMap;    import android.content.Context;    public class Task {     public static final int GETPRODUCT = 1;   public static final int GETPRODUCT2 = 5;   public static final int MSGACTIVITY = 4;   public static final int NEWWEIBO = 7;   public static final int HOMEREFRESH = 3;   public static final int VIEWWEIBO = 8;   private int taskId;   private HashMap taskParams;   private Context ctx;     public Task(int taskId, HashMap taskParams, Context ctx) {    super();    this.taskId = taskId;    this.taskParams = taskParams;    this.ctx = ctx;     }     public int getTaskId() {    return taskId;   }     public void setTaskId(int taskId) {    this.taskId = taskId;   }     public HashMap getTaskParams() {    return taskParams;   }     public void setTaskParams(HashMap taskParams) {    this.taskParams = taskParams;   }     public Context getCtx() {    return ctx;   }     public void setCtx(Context ctx) {    this.ctx = ctx;   }  }

Person实体,储存人员信息

package com.testaijialogic.domain;    public class PersonEntity {   // {"amount":100,"id":1,"name":"itcastliming"}   private int id;   private String name;   private String amount;     public PersonEntity(int id, String name, String amount) {    setId(id);    setAmount(amount);    setName(name);   }     /**    * @return the id    */   public int getId() {    return id;   }     /**    * @param id    *            the id to set    */   public void setId(int id) {    this.id = id;   }     /**    * @return the name    */   public String getName() {    return name;   }     /**    * @param name    *            the name to set    */   public void setName(String name) {    this.name = name;   }     /**    * @return the amount    */   public String getAmount() {    return amount;   }     /**    * @param amount    *            the amount to set    */   public void setAmount(String amount) {    this.amount = amount;   }    }

核心网络服务,请求项目的所有接口数据

package com.testaijialogic;    /*   * 获取服务器信息服务   *  */    import java.util.ArrayList;  import java.util.HashMap;  import java.util.List;    import org.json.JSONArray;  import org.json.JSONException;  import org.json.JSONObject;    import com.testaijialogic.domain.PersonEntity;  import com.testaijialogic.util.WebSender;    import android.app.Activity;  import android.app.AlertDialog;  import android.app.Service;  import android.content.Context;  import android.content.DialogInterface;  import android.content.Intent;  import android.content.DialogInterface.OnClickListener;  import android.os.Handler;  import android.os.IBinder;  import android.os.Message;  import android.util.Log;    public class MainService extends Service implements Runnable {     private static ArrayList<IAijiaActivity> allActivity = new ArrayList<IAijiaActivity>();   private static ArrayList<Task> allTasks = new ArrayList<Task>();   List<String> p = new ArrayList<String>();// post的参数 注意设置成全局变量后只能一次放松一个Post了   List<String> v = new ArrayList<String>();// post的数值   public static boolean isRun = false;     public static void newTask(Task t) {    allTasks.add(t);   }     public static void addActivity(IAijiaActivity iw) {    allActivity.add(iw);   }     public static void removeActivity(IAijiaActivity iw) {    allActivity.remove(iw);   }     public static IAijiaActivity getActivityByName(String name) {    for (IAijiaActivity iw : allActivity) {     if (iw.getClass().getName().indexOf(name) >= 0) {      return iw;     }    }    return null;   }     @Override   public void onCreate() {    // TODO Auto-generated method stub    super.onCreate();      isRun = true;    new Thread(this).start();    Log.e("=============================", "MainService    onCreate()");   }     @Override   public void onDestroy() {    isRun = false;    stopSelf();    super.onDestroy();     }     @Override   public void run() {    // TODO Auto-generated method stub    while (isRun) {     try {      if (allTasks.size() > 0) {       // 执行任务,可以遍历执行多个任务       // doTask(allTasks.get(0));       for (Task task : allTasks) {        doTask(task);       }        } else {       try {        Thread.sleep(1000);       } catch (Exception e) {       }        }     } catch (Exception e) {      if (allTasks.size() > 0)       allTasks.remove(allTasks.get(0));      Log.d("error", "------------------" + e);     }    }   }     private Handler handler = new Handler() {      @Override    public void handleMessage(Message msg) {     // TODO Auto-generated method stub     super.handleMessage(msg);       switch (msg.what) {     case Task.GETPRODUCT:      MainService.getActivityByName("TestAijiaLogicActivity")        .refresh(msg.obj);// 调用TestAijiaLogicActivity的方法刷新控件        break;     case Task.GETPRODUCT2:// 个人资料        break;     case Task.MSGACTIVITY:        break;     case Task.NEWWEIBO:        break;     case Task.VIEWWEIBO:        break;     default:      break;     }    }     };     @SuppressWarnings("unchecked")   private void doTask(Task task) throws JSONException {    // TODO Auto-generated method stub    Message msg = handler.obtainMessage();    msg.what = task.getTaskId();      switch (task.getTaskId()) {    case Task.GETPRODUCT:// 获取产品信息     Log.i("有任务执行", "MainS" + task.getTaskId());     String urlStr = "http://10.1.49.230/test/testjson.php";     p.add("product");// 增加post的参数名     v.add((String) task.getTaskParams().get("product"));// 增加post的参数的值     String result = WebSender.httpClientSendPost(urlStr, p, v);// 发送httppost请求       List<PersonEntity> personEntities = new ArrayList<PersonEntity>();     JSONArray jsonArray = new JSONArray(result);     for (int i = 0; i < jsonArray.length(); i++) {        JSONObject jsonObject = jsonArray.getJSONObject(i);      PersonEntity personEntity = new PersonEntity(        jsonObject.getInt("id"), jsonObject.getString("name"),        jsonObject.getString("amount"));      personEntities.add(personEntity);       }     /**      * 第二次请求联网,返回list , 也可以使用多任务处理,但是当前项目中界面的listview特别多所以使用这样      */     String suburlStr = "http://10.1.49.230/test/testsubjson.php";     p.add("product");// 增加post的参数名     v.add((String) task.getTaskParams().get("product"));// 增加post的参数的值     String subresult = WebSender.httpClientSendPost(suburlStr, p, v);// 发送httppost请求       List<PersonEntity> subpersonEntities = new ArrayList<PersonEntity>();     JSONArray subjsonArray = new JSONArray(subresult);     for (int i = 0; i < jsonArray.length(); i++) {        JSONObject jsonObject = subjsonArray.getJSONObject(i);      PersonEntity personEntity = new PersonEntity(        jsonObject.getInt("id"), jsonObject.getString("name"),        jsonObject.getString("amount"));      subpersonEntities.add(personEntity);       }       @SuppressWarnings("rawtypes")     HashMap map = new HashMap();     map.put("product", personEntities);     map.put("subproduct", subpersonEntities);     msg.obj = map;     // msg.obj = personEntities;//如果只需要一个list那用这个就可以     break;      default:     break;    }    allTasks.remove(task);    // 通知主线程更新UI    handler.sendMessage(msg);   }     @Override   public IBinder onBind(Intent intent) {    // TODO Auto-generated method stub    return null;   }     /**    * 退出应用程序    *     * @param context    */   public static void exitAPP(Context context) {    Intent it = new Intent("weibo4android.logic.util.MainService");    context.stopService(it);// 停止服务    // 杀死进程 我感觉这种方式最直接了当    android.os.Process.killProcess(android.os.Process.myPid());     }     public static void finshall() {      for (IAijiaActivity activity : allActivity) {// 遍历所有activity 一个一个删除     ((Activity) activity).finish();    }   }     /**    * 网络连接异常    *     * @param context    */   public static void AlertNetError(final Context context) {    AlertDialog.Builder alerError = new AlertDialog.Builder(context);    alerError.setTitle("网络错误");    alerError.setMessage("请检查网络");    alerError.setNegativeButton("退出", new OnClickListener() {     @Override     public void onClick(DialogInterface dialog, int which) {      dialog.dismiss();      exitAPP(context);     }    });    alerError.setPositiveButton("确定", new OnClickListener() {     @Override     public void onClick(DialogInterface dialog, int which) {      dialog.dismiss();      context.startActivity(new Intent(        android.provider.Settings.ACTION_WIRELESS_SETTINGS));     }    });    alerError.create().show();   }    }
网络工具类
package com.testaijialogic.util;    /**   *网络通信类(已优化)   * */    import java.io.BufferedReader;  import java.io.DataOutputStream;  import java.io.InputStream;  import java.io.InputStreamReader;  import java.io.PrintWriter;  import java.net.HttpURLConnection;  import java.net.URL;  import java.util.ArrayList;  import java.util.List;    import org.apache.http.HttpEntity;  import org.apache.http.HttpResponse;  import org.apache.http.HttpStatus;  import org.apache.http.NameValuePair;  import org.apache.http.client.HttpClient;  import org.apache.http.client.ResponseHandler;  import org.apache.http.client.entity.UrlEncodedFormEntity;  import org.apache.http.client.methods.HttpGet;  import org.apache.http.client.methods.HttpPost;  import org.apache.http.impl.client.BasicResponseHandler;  import org.apache.http.impl.client.DefaultHttpClient;  import org.apache.http.message.BasicNameValuePair;  import org.apache.http.util.EntityUtils;    import android.util.Log;    public class WebSender {     /*    * 比较原始的 POST Cookies    */   public static String[] sendPost(String urlStr, String[] param,     String[] value, String cookies) {    String[] result = { "", "" };    String paramValue = "";    StringBuffer buffer = null;    HttpURLConnection con = null;      try {     URL url = new URL(urlStr);     con = (HttpURLConnection) url.openConnection();     con.setRequestMethod("POST");     con.setRequestProperty("Connection", "Keep-Alive");     con.setRequestProperty("Charset", "UTF-8");     // con.setRequestProperty("Content-Type", "text/html");       // set cookies     if (QHFlag.isNotEmpty(cookies)) {      con.setRequestProperty("cookie", cookies);     }       paramValue = WebSender.getParamStr(param, value);       con.setDoOutput(true);     con.setDoInput(true);     con.setUseCaches(false);     con.setConnectTimeout(50000);// 设置连接主机超时(单位:毫秒)     con.setReadTimeout(50000);// 设置从主机读取数据超时(单位:毫秒)       con.connect();// connect open       PrintWriter out = new PrintWriter(con.getOutputStream());// 发送数据     out.print(paramValue);     out.flush();     out.close();       // get cookies     String cks = con.getHeaderField("set-cookie");     if (cks != "" && cks != null)      result[1] = cks;       // get status     int res = 0;     res = con.getResponseCode();       // get info response     if (res == 200 || res == 302) {      BufferedReader in = new BufferedReader(new InputStreamReader(        con.getInputStream(), "UTF-8"));      buffer = new StringBuffer();      String line = "";      while ((line = in.readLine()) != null) {       buffer.append(line);      }     } else {      QHFlag.e("Web Response:" + res);     }       con.disconnect();// Connect Close!    } catch (Exception e) {     // e.printStackTrace();    }      if (buffer.length() != 0 && buffer != null) {     result[0] = buffer.toString();    }    return result;   }     /*    * 使用HttpClient对象发送GET请求    */   public static String httpClientSendGet(String webUrl) {    String content = null;    // DefaultHttpClient    DefaultHttpClient httpclient = new DefaultHttpClient();    // HttpGet    HttpGet httpget = new HttpGet(webUrl);    // ResponseHandler    ResponseHandler<String> responseHandler = new BasicResponseHandler();    try {     content = httpclient.execute(httpget, responseHandler);    } catch (Exception e) {     e.printStackTrace();    }    httpclient.getConnectionManager().shutdown();    return content;   }     /*    * 使用HttpClient对象发送有cookie的GET请求    */   public static String httpClientSendGet(String urlStr, String Cookies) {    String httpUrl = urlStr;    HttpGet httpGet = new HttpGet(httpUrl);    try {     HttpClient httpClient = new DefaultHttpClient();     httpGet.setHeader("cookie", Cookies);     // 请求HttpClient,取得HttpResponse     HttpResponse httpResponse = httpClient.execute(httpGet);       // 请求成功     if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {      // 取得返回的字符串      String strResult = EntityUtils.toString(httpResponse        .getEntity());      return strResult;     }    } catch (Exception e) {    }    return "0";   }     /*    * 使用HttpClient对象发送POST请求    */   public static String httpClientSendPost(String urlStr,     List<String> paraName, List<String> val) {    String httpUrl = urlStr;    // HttpPost对象    HttpPost httpPost = new HttpPost(httpUrl);      // 使用NameValuePair来保存要传递的Post参数    List<NameValuePair> params = new ArrayList<NameValuePair>();      // 添加要传递的参数    System.out.println("====================================");    for (int i = 0; i < paraName.size(); i++) {     params.add(new BasicNameValuePair(paraName.get(i), val.get(i)));     System.out.println(paraName.get(i) + "->" + val.get(i));    }    System.out.println("====================================");      try {     // 设置字符集     HttpEntity httpEntity = new UrlEncodedFormEntity(params, "utf-8");     httpPost.setEntity(httpEntity);       // httpClient对象     HttpClient httpClient = new DefaultHttpClient();       // 请求HttpClient,取得HttpResponse     HttpResponse httpResponse = httpClient.execute(httpPost);       // 请求成功     if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {      // 取得返回的字符串      String strResult = EntityUtils.toString(httpResponse        .getEntity());      System.out.println(strResult);      return strResult;     }    } catch (Exception e) {    }    return "";   }     /*    * 使用HttpClient对象发送POST请求    */   public static String httpClientSendPost(String urlStr,     List<String> paraName, List<String> val, String Cookies) {    String httpUrl = urlStr;    // HttpPost对象    HttpPost httpPost = new HttpPost(httpUrl);      // 使用NameValuePair来保存要传递的Post参数    List<NameValuePair> params = new ArrayList<NameValuePair>();      // 添加要传递的参数    System.out.println("====================================");    for (int i = 0; i < paraName.size(); i++) {     params.add(new BasicNameValuePair(paraName.get(i), val.get(i)));     System.out.println(paraName.get(i) + "->" + val.get(i));    }    System.out.println("====================================");      try {     // 设置字符集     HttpEntity httpEntity = new UrlEncodedFormEntity(params, "utf-8");     httpPost.setEntity(httpEntity);     httpPost.setHeader("cookie", Cookies);     // httpClient对象     HttpClient httpClient = new DefaultHttpClient();       // 请求HttpClient,取得HttpResponse     HttpResponse httpResponse = httpClient.execute(httpPost);       // 请求成功     if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {      // 取得返回的字符串      String strResult = EntityUtils.toString(httpResponse        .getEntity());      System.out.println(strResult);      return strResult;     }    } catch (Exception e) {    }    return "";   }     public static String uploadBitmap1(String urlString, byte[] imageBytes,     String cookie) {    // String boundary = "*****";    try {     URL url = new URL(urlString);     final HttpURLConnection con = (HttpURLConnection) url       .openConnection();     // 允许input、Output,不使用Cache     con.setDoInput(true);     con.setDoOutput(true);     con.setUseCaches(false);       // 设置传送的method=POST     con.setRequestMethod("POST");     // setRequestProperty     con.setRequestProperty("Connection", "Keep-Alive");     con.setRequestProperty("Charset", "UTF-8");     con.setRequestProperty("Content-Type", "text/html");     if (cookie != null && cookie != "") {      Log.i("myEvent", "send cookies value is:" + cookie);      con.setRequestProperty("cookie", cookie);     }     // 从主机读取数据的超时时间(单位:毫秒)     con.setReadTimeout(50000);     // 设置连接主机的超时时间(单位:毫秒)     con.setConnectTimeout(50000);     // System.out.println(con.getResponseCode());     // 设置DataOutputStream     DataOutputStream dsDataOutputStream = new DataOutputStream(       con.getOutputStream());     // dsDataOutputStream.writeBytes(twoHyphen + boundary + endString);     // dsDataOutputStream.writeBytes("Content-Disposition:form-data;"     // + "name=\"file1\";filename=\"" + "11.jpg\"" + endString);     // dsDataOutputStream.writeBytes(endString);       dsDataOutputStream.write(imageBytes, 0, imageBytes.length);     // dsDataOutputStream.writeBytes(endString);     // dsDataOutputStream.writeBytes(twoHyphen + boundary + twoHyphen     // + endString);     dsDataOutputStream.close();     int cah = con.getResponseCode();     if (cah == 200) {      InputStream isInputStream = con.getInputStream();      int ch;      StringBuffer buffer = new StringBuffer();      while ((ch = isInputStream.read()) != -1) {       buffer.append((char) ch);      }      return buffer.toString();     } else {      return "false";     }    } catch (Exception e) {     e.printStackTrace();     return "false";    }     }     /**    * 请求字符串    * */   public static String getParamStr(String[] param, String[] value) {    String res = "";    if (param.length == value.length) {     for (int i = 0; i < param.length; i++) {      res += param[i] + "=" + toUTF8(value[i]) + "&";     }    }    return res.substring(0, res.length() - 1);   }     public static String toUTF8(String str) {    String u = str;    try {     u = java.net.URLEncoder.encode(u, "UTF-8");    } catch (Exception e) {      }    return u;   }    }