好久没有更新博客了,这段时间里和我的小伙伴们(”乌索普“、”丁二爷“、”小娜“、‘小雯’‘)参加了一个大学生Android应用软件比赛,利用两个月的课余时间做了一款MFNote(多功能记事本)软件,中间的苦这里就不多说了,大家都懂得~~ 搞IT的熬夜写代码,相信那是每一个有志青年都必须经历的。。。哈哈!
先来几张软件截图:
有兴趣的同学可以下载下来玩玩!软件下载地址:http://apk.hiapk.com/html/2013/10/1874574.html
接下来的几篇博客我将会逐一将整个项目中一些我认为比较好玩的地方分享给大家,当然如果大家下载了这款软件觉得有想要学习的东西,留言给我,我会将其抽取出来与大家分享!
ok! 转入正题,开始我们今天的内容:实用的代码框架。
说到代码框架,对于个人开发者来说,做一款简单的android应用其实也用不到那么多的条条框框,但是如果是一个团队的协作,共同写代码,那就得前期先将代码的框架搭建好,这样才能更好的进行团队分工和编写代码。
一、MainServices类:
主框架类: 统一接收任务消息,处理不同的任务。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
package com.zhf.android_framework01.logic;
import java.util.ArrayList;
import java.util.LinkedList;
import com.zhf.android_framework01.model.Task;
import com.zhf.android_framework01.ui.IActivity;
import android.app.Activity;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
/** * 主框架类: 统一接收任务消息,处理不同的任务
* @author ZHF
*
*/
public class MainServices extends Service implements Runnable{
// 1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 // 2.对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。 // 3.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 private static LinkedList<Task> tasks = new LinkedList<Task>(); //任务队列,记得移除remove
private static ArrayList<Activity> activities = new ArrayList<Activity>(); //存放需要返回数据的 View
private boolean isRun = false ;
@Override
public void onCreate() {
isRun = true ;
Thread thread = new Thread( this );
thread.start();
super .onCreate();
}
/**
* 向集合中添加Activity对象
* @param activity 需要向集合中添加的实例
*/
public static void addActivity(Activity activity) {
activities.add(activity);
}
/**
* 向集合中添加任务
* @param task 任务实例
*/
public static void newTask(Task task) {
tasks.add(task);
}
/**
* 线程不断检测tasks中的任务
*/
@Override
public void run() {
while (isRun) {
Task task = null ;
if (!tasks.isEmpty()) {
task = tasks.poll();
if ( null != task) {
doTask(task); //处理任务
}
}
try {
Thread.sleep( 1000 );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 处理任务(重要)
* @param task 任务实体
*/
private void doTask(Task task) {
Message msg = handler.obtainMessage();
msg.what = task.getTaskId(); //获取任务ID
switch (msg.what) {
case Task.FIRST_LOGIN:
System.out.println( "doTask---->>>first login!" );
msg.obj = "第一次登录成功" ; //传递处理完的数据
break ;
default :
break ;
}
handler.sendMessage(msg);
}
/**
* 处理器
*/
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case Task.FIRST_LOGIN: //登录
IActivity activity = (IActivity) getActivityByName( "LoginActivity" );
activity.refresh(msg.obj);
break ;
//其他任务
}
}
};
/**
* 根据Activity的名字获取集合中对应的Activity
* @param string Activity的名字
* @return
*/
private Activity getActivityByName(String string) {
if (!activities.isEmpty()) {
for (Activity activity : activities) {
if ( null != activity) {
if (activity.getClass().getName().indexOf(string) > 0 ) { //为何不写!=-1,not subString,因为会忽略了单个字母的情况
return activity; //获取对应的Activity实例
}
}
}
}
return null ;
};
//遍历所有Activity并finish
public static void exit() {
for (Activity activity : activities) {
activity.finish();
}
System.exit( 0 );
}
@Override
public IBinder onBind(Intent intent) {
System.out.println( "------->onBind" );
return null ;
}
@Override
public void onStart(Intent intent, int startId) {
System.out.println( "------->onStart" );
super .onStart(intent, startId);
}
@Override
public void onDestroy() {
System.out.println( "------->onDestroy" );
super .onDestroy();
}
} |
这里用到了服务,所以记得在AndroidManifest中注册:
1
|
< serviceandroid:name = ".logic.MainServices" ></ service >
|
二.IActivity接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package com.zhf.android_framework01.ui;
/** * 每个界面需要实现该接口,完成其中的抽象方法
* @author ZHF
*
*/
public interface IActivity {
/**初始化**/
public abstract void init();
/**刷新界面**/
public abstract void refresh( Object ...params);
} |
三.Task类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
package com.zhf.android_framework01.model;
import java.util.Map;
/** * 任务实体: 任务的ID,任务参数taskParams
* @author ZHF
*
*/
public class Task {
public static final int FIRST_LOGIN = 0 ; //登录任务
private int taskId; //任务ID
private Map<String, Object> taskParams; //任务参数
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;
}
} |
四.LoginActivity类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
package com.zhf.android_framework01.ui;
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;
import android.widget.Toast;
import com.zhf.android_framework01.R;
import com.zhf.android_framework01.logic.MainServices;
import com.zhf.android_framework01.model.Task;
/** * 登录界面: 测试框架是否运行正常
* @author ZHF
*
*/
public class LoginActivity extends Activity implements IActivity{
private TextView textView;
private Button btn_login; //登录
private Button btn_exit; //退出
private Intent service;
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//启动软件界面后记得启动后台服务!
service = new Intent( this , MainServices. class ); //别忘了注册!
startService(service); //启动服务
MainServices.addActivity( this ); //将该Activity实例加入到框架中,便于最终软件的退出
this .btn_login = (Button) this .findViewById(R.id.btn_login);
this .btn_login.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View v) {
Task task = new Task(Task.FIRST_LOGIN, null ); //生成任务
MainServices.newTask(task);
}
});
this .btn_exit = (Button) this .findViewById(R.id.btn_exit);
this .btn_exit.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View v) {
//停止服务
stopService(service);
Toast.makeText(LoginActivity. this , "后台服务已停止!" , Toast.LENGTH_SHORT);
MainServices.exit(); //将所有的Activity结束掉
}
});
this .textView = (TextView) this .findViewById(R.id.tv_login);
}
@Override
public void init() {
}
@Override
public void refresh(Object... params) {
//接收传回的数据,刷新UI
this .textView.setText(params[ 0 ].toString());
}
} |
还有一个xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<? 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/tv_login"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text = "TextView" />
< Button
android:id = "@+id/btn_login"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:text = "点击测试框架" />
< Button
android:id = "@+id/btn_exit"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:text = "点击退出程序" />
</ LinearLayout >
|
效果图:
ok! 这里我们就简单的将一款软件的代码框架搭建起来了。以后我们创建Activity时,只需要按照下面这几条模式来添加代码,就十分的方便了!
框架流程:
1.每次创建Activity需实现IActivity接口.
2.在onCreate()中将Activity添加到集合中。
3.每次要进行操作时,可生成一个新的Task,将其添加到任务集合中即可。
4.在主框架代码中根据任务的ID来调用方法处理任务事件--->处理完成之后将结果以obj的形式传递到Handler中----->利用多态调用对应的refresh()来对应传递数据,以达到刷新界面的效果。
5.退出程序时,可以调用主框架类MainServices中的exit()将所有的Activity关闭掉。(这里可以看一下前面的这篇博客:http://smallwoniu.blog.51cto.com/3911954/1248643)