(点击
上方公众号
,可快速关注)
来源:伯乐在线专栏作者 - 王亟亟
链接:http://android.jobbole.com/84552/
点击 → 了解如何加入专栏作者
这礼拜基本都在忙自己项目上的事,然后之后会“重新整理”后把这部分的功能开源出来,这里@下队友 NeglectedByBoss
本周还是没有停更收纳库,继续安利:https://github.com/ddwhan0123/Useful-Open-Source-Android (把疑难杂症给拆出去了,还剩资料,工具类和自定义控件的细分工作)
本文简单模拟一个读书的业务流程,来谈一下代码拓展性的问题。
建立模型
首先我们得 建立书的对象
public
class
Book
{
public
String
Name
;
//书名
public
int
PageCount
;
//总页数
public
int
NowPage
;
//当前页数
public
T
BookMoreMSG
;
//附加信息
/**
* get set等其他方法省略
*/
因为我们读一本书,肯定有其一些基本信息,这里就 设置了书名,总页数,当然还可以有作者,出版日期等等等,我们只是例子不需要太复杂
NowPage 用来判断读书进展
BookMoreMSG 这是个泛型,也就是我们的补充项,让每一本书的对象更鲜活。而让代码实现也更灵活,增强了我们的拓展性,他可以是一句话 ,可以是一个对象 等等等。
读书状态回调
写的时候其实我没有刻意的要想怎么去假设,怎么去设计也就是写着写着改着改着(这种方式本身不太好,还是建议大家在开始敲代码之前好好的想想怎么做更好)
那既然读书,肯定是要慢条斯理的,而且还肯定要有状态于是我就让这个读书的行为用一个子线程然后让他 .Sleep()下来模拟正在读书的行为
先创建一个读书状态无非是 开始读书,正在读书,读完了 那么我们就用一个接口去实现
public
interface
ReadListener
{
//开始读书
void
start
();
//正在读书
void
doing
(
T
t
);
//读完了
void
finish
(
T
t
);
}
因为我们书有一系列的属性,所以我们把书的状态作为参数传入,又因为这个接口(可能)可以在别的地方复用 所以传入的参数还是用了泛型
填充数据
读书之前我们得有书,所以我们得填充下数据,这本
奥
特曼打怪兽
我们给他一个描述语句 是
神秘的反派角色
,他总共 15页,我们的小宝宝从头开始读
/*
* 模拟数据
* */
private
BookaddBook
()
{
book
=
new
Book
();
book
.
setBookMoreMSG
(
"神秘的反派角色"
);
book
.
setName
(
"奥特曼打怪兽"
);
book
.
setPageCount
(
15
);
book
.
setNowPage
(
0
);
return
book
;
}
读书的实现
读书的状态跟视图(也就是Activity/Fragment)没什么关系,所以为了让
视图
更
视图
让一个类在子线程去读书吧,如果想在页面上展示进度直接用接口传递就好了,So Easy!!
那我们再写个接口,让他作为传播媒介告诉UI好了
public
interface
CommunicateListener
{
void
setMsg
(
Message
msg
);
}
非常简单的一个接口,传递一个Message对象,你想给UI传啥都行了。
既然要实现读书,那肯定要实现读书状态的回调,那我们就来实现他
因为上面确定了,我们图书的附加内容是一句话,那泛型的书就都成了Book类型的Book了
public
class
ReadImp
implements
ReadListener
>
{
Book
book
;
CommunicateListener
communicate
;
public
void
setMessager
(
CommunicateListener
communicate
)
{
this
.
communicate
=
communicate
;
}
public
ReadImp
(
Book
book
)
{
this
.
book
=
book
;
}
@
Override
public
void
start
()
{
Log
.
d
(
"--->"
,
"ReadImp 开始读书"
);
}
@
Override
public
void
doing
(
Book
book
)
{
Log
.
d
(
"--->"
,
"现在读到第 "
+
book
.
getNowPage
()
+
"页"
);
}
@
Override
public
void
finish
(
Book
book
)
{
Log
.
d
(
"--->"
,
"读完了,总共读了 "
+
book
.
getNowPage
()
+
"页"
);
Message
message
=
Message
.
obtain
();
message
.
obj
=
book
.
getBookMoreMSG
();
communicate
.
setMsg
(
message
);
}
}
这里没有让消息一直刷UI就 读书读完了 让他 把他读完的消息发出去。
逻辑实现算是通了,那我们来看下UI咯
主UI
下面还有个TextView,因为一开始宝宝没有读完书,所以没字。
public
class
MainActivity
extends
AppCompatActivity
implements
View
.
OnClickListener
,
CommunicateListener
{
private
Button
read_btn
,
send_text
;
private
ReadImp
readImp
;
private
EditText
edit_baobao
;
private
ReadThread
readThread
;
private
Thread
thread
;
private
volatile Book
book
;
private
ReadBookTextView
read_text
;
@
Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_main
);
init
();
}
private
void
init
()
{
Log
.
d
(
"--->"
,
"主线程的 ID 是 "
+
Thread
.
currentThread
().
getId
());
//给书赋值
addBook
();
readImp
=
new
ReadImp
(
book
);
readImp
.
setMessager
(
this
);
readThread
=
new
ReadThread
(
book
,
readImp
);
thread
=
new
Thread
(
readThread
);
initWidget
();
}
@
Override
protected
void
onStart
()
{
super
.
onStart
();
thread
.
start
();
Log
.
d
(
"--->"
,
"开启的线程 ID 是 "
+
thread
.
getId
());
}
@
Override
protected
void
onStop
()
{
super
.
onStop
();
thread
.
interrupt
();
}
@
Override
protected
void
onDestroy
()
{
super
.
onDestroy
();
thread
=
null
;
readThread
=
null
;
}
private
void
initWidget
()
{
read_text
=
(
ReadBookTextView
)
findViewById
(
R
.
id
.
read_text
);
read_btn
=
(
Button
)
findViewById
(
R
.
id
.
read_btn
);
send_text
=
(
Button
)
findViewById
(
R
.
id
.
send_text
);
edit_baobao
=
(
EditText
)
findViewById
(
R
.
id
.
edit_baobao
);
send_text
.
setOnClickListener
(
this
);
read_btn
.
setOnClickListener
(
this
);
}