现在的位置: 首页 > 综合 > 正文

新浪微博Android客户端学习记录二:系统主框架搭建

2013年04月10日 ⁄ 综合 ⁄ 共 4663字 ⁄ 字号 评论关闭

         在系列视频的二三四讲中讲了搭建主框架中的UI层(主要为微博中的各个窗体)和Logic层(程序的核心控制调度模块,获取UI传递的数据、要执行的任务,调用微博接口,获得网络数据,返回消息,刷新(切换)UI)。

          Eclipse中代码结构如下图:

     

      Logic层的Mainservice

1、完成程序调度 接收任务,完成业务逻辑,返回信息,更新UI
2、在后台运行(继承自Service类)
3、线程(实现Runnable接口)  不断侦听UI传过来任务消息
  流程关系如图:

 

 MainService代码如下:

package haiyang.project.iweibo.logic;

import haiyang.project.iweibo.bean.Task;
import haiyang.project.iweibo.ui.IWeiboActivity;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

import android.app.Activity;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;

public class MainService extends Service implements Runnable {

	//任务队列
	private static Queue<Task> tasks=new LinkedList<Task>();
	
	private static ArrayList<Activity> appActivities=new ArrayList<Activity>();
	
	private boolean isRun;//是否运行线程
	
	Handler handler=new Handler(){
		public void handleMessage(android.os.Message msg){
			switch (msg.what) {
			case Task.WEIBO_LOGIN://用户登录
				//更新UI
				IWeiboActivity activity=(IWeiboActivity) getActivityByName("LoginActivity");
				activity.refresh(msg.obj);
				break;

			default:
				break;
			}
		};
	};
	
	/*
	 * 添加一个Activity对象
	 */
	public static void addActivity(Activity activity){
		appActivities.add(activity);
	}
	
	/**
	 * 根据Activity的Name获取Activity对象
	 * @param name
	 * @return
	 */
	private Activity getActivityByName(String name){
		if(!appActivities.isEmpty()){
			for(Activity activity:appActivities){
				if(activity!=null){
					if(activity.getClass().getName().indexOf(name)>0){
						return activity;
					}
				}
			}
		}
		return null;
	}
	
	/*
	 * 添加任务到任务队列中
	 */
	public static void newTask(Task t){
		tasks.add(t);
	}
	
	@Override
	public void onCreate() {
		
		isRun=true;
		Thread thread=new Thread(this);
		thread.start();
		super.onCreate();
	}
	
	public void run() {
		while(isRun){
			Task task=null;
			if(!tasks.isEmpty()){
				task=tasks.poll();//执行完任务后把该任务从队列中移出(否则会一直循环)
				if(task!=null){
					doTask(task);
				}
			}
			try {
				Thread.sleep(1000);//执行完任务后休息一秒钟
			} catch (Exception e) {

			}
		}
	}
	
	/*
	 * 处理任务,发回更新消息给主线程
	 */
	private void doTask(Task t){
		
		Message msg=handler.obtainMessage();
		msg.what=t.getTaskId();
		switch(t.getTaskId()){
		case Task.WEIBO_LOGIN:
			System.out.println("doTask >>>>>>>  user login");
			msg.obj="登录成功";
			break;
			default:
				break;
		}
		handler.sendMessage(msg);
	}

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

}

Logic层的Task 程序中的任务

package haiyang.project.iweibo.bean;

import java.util.*;

public class Task {

	//任务Id
	private int taskId;
	//参数
	private Map<String,Object> tasKParams;
	
	//登录
	public static final int WEIBO_LOGIN=1;
	
	public Task(int taskId,Map<String,Object> taskParams){
		this.taskId=taskId;
		this.tasKParams=taskParams;
	}

	public int getTaskId() {
		return taskId;
	}

	public void setTaskId(int taskId) {
		this.taskId = taskId;
	}

	public Map<String, Object> getTasKParams() {
		return tasKParams;
	}

	public void setTasKParams(Map<String, Object> tasKParams) {
		this.tasKParams = tasKParams;
	}
	
}

  IWeiboActivity

 所有的Activity都实现它
  init()  初始化数据
  refresh()刷新UI

package haiyang.project.iweibo.ui;

/*
 * Activity接口
 */
public interface IWeiboActivity {

	/*
	 * 初始化数据
	 */
	void init();
	
	/*
	 * 刷新UI
	 */
	void refresh(Object... params);
}

    此代码实现了由Logo界面到登录的过程,LoginActivity在前面的基础上有变化

package haiyang.project.iweibo.ui;

import haiyang.project.iweibo.R;
import haiyang.project.iweibo.bean.Task;
import haiyang.project.iweibo.logic.MainService;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class LoginActivity extends Activity implements IWeiboActivity{
	
	private Button btnLogin;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.main);
		
		//启动服务
		Intent intent=new Intent(this,MainService.class);
		startService(intent);
		
		btnLogin=(Button) this.findViewById(R.id.btn_login);
		btnLogin.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				Task task=new Task(Task.WEIBO_LOGIN,null);
				MainService.newTask(task);
			}
			
		});
		//把自己放到Activity集合里面
		MainService.addActivity(this);
	}

	public void init() {
		
	}

	public void refresh(Object... params) {
		TextView txtResult=(TextView) this.findViewById(R.id.txt_result);
		txtResult.setText(params[0].toString());
	}
}

  此外还需更改布局文件main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

  <TextView android:id="@+id/txt_result"
 			android:layout_width="fill_parent" 
    		android:layout_height="wrap_content" 
    		android:text="Test ADD Method" />
    		
  <Button android:id="@+id/btn_login"
    		android:layout_width="fill_parent" 
    		android:layout_height="wrap_content" 
    		android:text="get"/>

</LinearLayout>

        对了,补充一个小问题,由于此视频讲解者是在用的SDK2.2,如果你的SDK版本高于2.2,且要运行视频中打包的代码时,即android api level由上向下兼容时,要修改一个参数,才能使在较低SDK版本下编写的代码在高版本上编译运行,具体做法:把project.properties最后一行target=android-i 中的i修改为你所用的版本平台。

抱歉!评论已关闭.