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

由于项目的需要,最近研究了一下需要连接网络项目的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;
	}

}




posted @ 2012-08-12 15:25  sfshine  阅读(467)  评论(0编辑  收藏  举报