在系列视频的二三四讲中讲了搭建主框架中的UI层(主要为微博中的各个窗体)和Logic层(程序的核心控制调度模块,获取UI传递的数据、要执行的任务,调用微博接口,获得网络数据,返回消息,刷新(切换)UI)。
Eclipse中代码结构如下图:
Logic层的Mainservice
1、完成程序调度 接收任务,完成业务逻辑,返回信息,更新UI
2、在后台运行(继承自Service类)
3、线程(实现Runnable接口) 不断侦听UI传过来任务消息
流程关系如图:
MainService代码如下
提前声明的是,我是按照Ivan的这套教程学下来的。
首先,对于任何应用我们都需要建立一套消息处理机制,就是当用户在UI界面上点击了什么,你应该做出什么样的处理,处理完成之后又要将结果 反馈给用户,显示在UI界面上。简而言之:主框架在这里主要是搭建起一个异步消息处理机制,UI线程中发送消息,service处理消息,处理完了调用UI线程实例更新UI界面。先看看这里是怎么处理的,如下图:
解析:在程序启动时开启MainService,MainService中新开个线程来不断循环的监听Tasks中是否有任务。当UI界面的主线程接收到用户的某个操作时,就会调用MainService.newTask()将这个任务放进Tasks中,并且把Activity放进Activities。这样在MainService中的第二线程就会监听到这个任务,就会调用MainService.doTask(),当做完处理后MainService第二线程就会向MainService主线程发送Handler消息,将处理得一些数据发送到Acitivity中,然后调用的Activity.refresh()就能刷新页面了。这里要强调的是UI层的Activity都要实现IWeiboActivity这样一个接口,实现他的refresh(),init()两个抽象方法。
MainService.java
1 package com.fangjie.weibo.logic; 2 3 import java.util.ArrayList; 4 import java.util.LinkedList; 5 import java.util.List; 6 import java.util.Queue; 7 8 import android.app.Activity; 9 import android.app.Service; 10 import android.content.Intent; 11 import android.os.Handler; 12 import android.os.IBinder; 13 import android.os.Message; 14 import android.util.Log; 15 16 import com.fangjie.weibo.bean.*; 17 import com.fangjie.weibo.db.DBUserInfo; 18 import com.fangjie.weibo.ui.IWeiboAcitivity; 19 import com.fangjie.weibo.util.GetUserInfo; 20 import com.weibo.sdk.android.Oauth2AccessToken; 21 22 public class MainService extends Service implements Runnable{ 23 24 private static Queue<Task> tasks=new LinkedList<Task>(); 25 private static ArrayList<Activity> appActivities=new ArrayList<Activity>(); 26 27 private boolean isRun; 28 private Handler handler; 29 30 @Override 31 public void onCreate() { 32 // TODO Auto-generated method stub 33 /** 34 * 在MainService中开启第二线程来处理任务 35 * 主要是不断监听Tasks堆栈,从Tasks中处理task 36 */ 37 isRun=true; 38 Thread thread =new Thread(this); 39 thread.start(); 40 super.onCreate(); 41 42 /** 43 * 主要是获取从MainService第二线程(doTask)中获取处理完任务的数据 44 * 并通知更新UI界面 45 */ 46 handler =new Handler(){ 47 public void handleMessage(Message msg) 48 { 49 IWeiboAcitivity activity=null; 50 switch(msg.what) 51 { 52 case Task.WEIBO_LOGIN: 53 activity=(IWeiboAcitivity)getActivityByName("LoginActivity"); 54 activity.refresh(Task.WEIBO_LOGIN,msg.obj); 55 break; 56 case Task.GET_USERINFO_BY_TOKEN: 57 58 break; 59 case Task.GET_USERINFO_IN_LOGIN: 60 61 break; 62 default: 63 break; 64 } 65 } 66 }; 67 68 } 69 70 @Override 71 public void run() { 72 // TODO Auto-generated method stub 73 while(isRun) 74 { 75 if(!tasks.isEmpty()) 76 { 77 doTask(tasks.poll()); 78 } 79 } 80 } 81 82 /** 83 * UI层向MainService中发送任务task 84 * UI层调用,所以static 85 * @param task 86 */ 87 public static void newTask(Task task) 88 { 89 tasks.add(task); 90 } 91 92 /** 93 * UI层向MainService中发送任务的同时,同样要发送自己Activity, 94 * 以便在MainService中调用refresh(); 95 * @param task 96 */ 97 public static void addActivty(Activity activity) 98 { 99 appActivities.add(activity); 100 } 101 /** 102 * UI层中有向MainService中传递Activity,在任务结束后(refresh),应去除该Activity,防止混淆! 103 * @param activity 104 */ 105 public static void reMoveActivty(Activity activity) 106 { 107 appActivities.remove(activity); 108 } 109 110 /** 111 * 通过name获取新开任务时传递过来的Activity实例 112 * @param name 113 * @return 114 */ 115 public Activity getActivityByName(String name) 116 { 117 if(!appActivities.isEmpty()) 118 { 119 for(Activity activity:appActivities) 120 { 121 if(activity.getClass().getName().indexOf(name)>0) 122 { 123 return activity; 124 } 125 } 126 } 127 return null; 128 } 129 130 /** 131 * 处理Tasks堆栈中的task 132 * @param task 133 */ 134 public void doTask(Task task) 135 { 136 Message msg=handler.obtainMessage(); 137 msg.what=task.getTaskID(); 138 139 switch(task.getTaskID()) 140 { 141 //登录操作 142 case Task.WEIBO_LOGIN: 143 System.out.println("login successful"); 144 msg.obj="登录成功"; 145 break; 146 147 //通过access_token获取用户信息,并保存到数据库操作 148 case Task.GET_USERINFO_BY_TOKEN: 149 msg.obj="成功"; 150 break; 151 152 //登录界面获取用户信息显示操作 153 case Task.GET_USERINFO_IN_LOGIN: 154 msg.obj="成功"; 155 break; 156 default : 157 break; 158 } 159 handler.sendMessage(msg); 160 } 161 162 163 @Override 164 public IBinder onBind(Intent intent) { 165 // TODO Auto-generated method stub 166 return null; 167 } 168 }
再看看我的工程文件架构,如下图:
Task.java是任务的实体类,包含任务的ID,任务的参数成员变量,IWeiboActivity就是所有Activity要实现的接口。