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

来源:互联网 发布:优化方案答案物理答案 编辑:程序博客网 时间:2024/05/01 20:26
由于项目的需要,最近研究了一下需要连接网络项目的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());}@Overridepublic 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();}@Overridepublic 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() {@Overridepublic 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;}@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();isRun = true;new Thread(this).start();Log.e("=============================", "MainService    onCreate()");}@Overridepublic void onDestroy() {isRun = false;stopSelf();super.onDestroy();}@Overridepublic void run() {// TODO Auto-generated method stubwhile (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() {@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsuper.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 stubMessage 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);// 通知主线程更新UIhandler.sendMessage(msg);}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn 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() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();exitAPP(context);}});alerError.setPositiveButton("确定", new OnClickListener() {@Overridepublic 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 cookiesif (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 openPrintWriter out = new PrintWriter(con.getOutputStream());// 发送数据out.print(paramValue);out.flush();out.close();// get cookiesString cks = con.getHeaderField("set-cookie");if (cks != "" && cks != null)result[1] = cks;// get statusint res = 0;res = con.getResponseCode();// get info responseif (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;// DefaultHttpClientDefaultHttpClient httpclient = new DefaultHttpClient();// HttpGetHttpGet httpget = new HttpGet(webUrl);// ResponseHandlerResponseHandler<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,取得HttpResponseHttpResponse 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,取得HttpResponseHttpResponse 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,取得HttpResponseHttpResponse 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,不使用Cachecon.setDoInput(true);con.setDoOutput(true);con.setUseCaches(false);// 设置传送的method=POSTcon.setRequestMethod("POST");// setRequestPropertycon.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());// 设置DataOutputStreamDataOutputStream 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;}}


原创粉丝点击