由于接触了javaweb编程,对于程序设计也变得敏感,在写五子棋对战的程序时有意引入了struts框架的控制器的概念,让Android socket变的不是那么混乱。
首先我先规定了通信都使用json格式 而json中必包含一个key=“name” 方便获取请求的类型
例如一个登陆请求
{"name":"login","username":"xiaoming","password":"123456"}
通过一个简单的json解析函数可以获得请求类型,方便console进行进一步的调度
接下来是控制器
控制器需要存储所有的Activity组件,因为一旦控制器获得了请求相关的操作必须要在Activity上执行。这里使用一个ActivityMap来存储,在Activity Oncreate()的时候执行addActivity(),在Activity Onpause 或者 OnDestory的时候执行RemoveActivity()【具体是在Onpause 还是OnDestory要根据这个Activity在Onpause 的时候会不会别Console调用】。
当Client收到请求时会调用Console的get()方法,Console根据请求类型调用相应Activity的相应方法
当Activity需要向服务器发送请求时调用Console的send方法,传入一个bean和一个指令名称
如下是Console的代码 以login为例
public class Console {
private static Map<String,Object> ActivityMap = new HashMap<>();
static void get(String line){
String name = getName(line);
if(name==null) return;
if(name.equals("login_successful")){
if(ActivityMap.containsKey("LoginActivity"))
((LoginActivity)ActivityMap.get("LoginActivity")).Login_Successful();
}
else if(name.equals("login_failed")){
if(ActivityMap.containsKey("LoginActivity"))
((LoginActivity)ActivityMap.get("LoginActivity")).Login_Failed();
}
public static void send(Object bean,String ActionName){
if(ActionName == null) return;
if(ActionName.equals("login")){
UserBean userBean = (UserBean) bean;
Client.out(userBean.login_json());
}
public static void addActivity(String name,Object activity){
ActivityMap.put(name,activity);
}
public static void RemoveActivity(String name){
ActivityMap.remove(name);
}
private static String getName(String json) {
try {
JSONObject job = new JSONObject(json);
return job.getString("name");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
接下来是Client Socket的必备组件
public class Client extends Thread {
static Socket socket ;
String IpAddress = "";
// String IpAddress = "127.0.0.1";
int Port = 12340;
public void init(){
this.start();
}
public static void out(String s){
s = s + "\n";
try {
socket.getOutputStream().write(s.getBytes("utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
try {
socket = new Socket(IpAddress,Port);
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf-8"));
String line = null;
while((line = br.readLine())!=null){
System.out.println(line);
Console.get(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
可以看出在获得请求时调用了Console的get方法
总结:在这次联机五子棋的小项目中采用了Console来调度任务确实简化了程序的编写难度,但由于项目太小就没有用反射来简化框架的复杂度,并且Client中的Console.get
方法也应该用一个Thread包起来,不然如果同时收到两个请求就会遗漏掉另一个(这个只是怀疑,没法实验),希望高人能指点迷津。