由于项目的需要,最近研究了一下需要连接网络项目的MVC架构,参考了一下一个新浪微博的开发架构
然后是Activity
可以看到,表现层只是把数据展示到xml中,没有牵扯到请求接口
Person实体,储存人员信息
核心网络服务,请求项目的所有接口数据
大体描述如下
需求:项目中接口很多,联网操作在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;
}
}