Android设计模式——模板模式
1.模板模式定义2.模板使用场景3.源码中用到的模板设计模式3.1 Activity的生命周期采用了模板设计模式3.2 AsyncTask也采用了模板设计模式3.3 AsyncTask简单使用3.4 AsyncTask源码简单分析
4.线程池介绍5.常用的BaseActivity模板模式6.UML图
1.模板模式定义
定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类不改变一个算法的结构即可重定义该算法的某些特定步骤。说白了就是必须得有继承,父类一般都是流程和通用部分的封装,子类一般都是实现父类的方法,然后实现自己具体的功能;
2.模板使用场景
1.多个子类有公共的方法,并且逻辑进本相同 2.重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数来约束其行为。
3.源码中用到的模板设计模式
3.1 Activity的生命周期采用了模板设计模式
都是继承自Activity ,内部封装一套具体的流程,onCreate – onStart – onResume… 只需要我们继承Activity,可以自己设置自己的布局,自己实现具体的逻辑代码。
3.2 AsyncTask也采用了模板设计模式
AsyncTask实现原理:线程池 + Handler 早期我们使用网络请求都是AsyncTask,它内部也是一套具体的流程,onPreExecute – doInBackground – onPostExecute … 只需我们继承AsyncTask,可以自己实现网络请求耗时操作。
3.3 AsyncTask简单使用
public class AsyncTaskActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState
) {
super.onCreate(savedInstanceState
);
setContentView(R.layout
.activity_async_task
);
new Task().execute();
}
public class Task extends AsyncTask<Void
,Void
,Void
> {
@Override
protected void onPreExecute() {
Log
.e("TAG","onPreExecute");
Log
.e("onPreExecute",Thread
.currentThread()+"");
super.onPreExecute();
}
@Override
protected Void
doInBackground(Void
... voids
) {
Log
.e("TAG","doInBackground");
Log
.e("doInBackground",Thread
.currentThread()+"");
return null;
}
@Override
protected void onPostExecute(Void aVoid
) {
Log
.e("TAG","onPostExecute");
Log
.e("onPostExecute",Thread
.currentThread()+"");
super.onPostExecute(aVoid
);
}
}
}
3.4 AsyncTask源码简单分析
public final AsyncTask
<Params
, Progress
, Result
> executeOnExecutor(Executor exec
,
Params
... params
) {
if (mStatus
!= Status
.PENDING) {
switch (mStatus
) {
case RUNNING:
throw new IllegalStateException("Cannot execute task:"
+ " the task is already running.");
case FINISHED:
throw new IllegalStateException("Cannot execute task:"
+ " the task has already been executed "
+ "(a task can be executed only once)");
}
}
mStatus
= Status
.RUNNING;
onPreExecute();
mWorker
.mParams
= params
;
exec
.execute(mFuture
);
return this;
}
public AsyncTask(@Nullable Looper callbackLooper
) {
mHandler
= callbackLooper
== null || callbackLooper
== Looper
.getMainLooper()
? getMainHandler()
: new Handler(callbackLooper
);
mWorker
= new WorkerRunnable<Params
, Result
>() {
public Result
call() throws Exception
{
Result result
= null;
try {
result
= doInBackground(mParams
);
} finally {
postResult(result
);
}
return result
;
}
};
mFuture
= new FutureTask<Result
>(mWorker
) {
@Override
protected void done() {
....
}
};
}
private Result
postResult(Result result
) {
@
SuppressWarnings("unchecked")
Message message
= getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result
>(this, result
));
message
.sendToTarget();
return result
;
}
private static class InternalHandler extends Handler {
@Override
public void handleMessage(Message msg
) {
AsyncTaskResult
<?> result
= (AsyncTaskResult
<?>) msg
.obj
;
switch (msg
.what
) {
case MESSAGE_POST_RESULT:
result
.mTask
.finish(result
.mData
[0]);
break;
case MESSAGE_POST_PROGRESS:
result
.mTask
.onProgressUpdate(result
.mData
);
break;
}
}
}
private void finish(Result result
) {
if (isCancelled()) {
onCancelled(result
);
} else {
onPostExecute(result
);
}
mStatus
= Status
.FINISHED;
}
4.线程池介绍
线程执行时间:t = t1(线程的创建时间) + t2(run方法执行时间) + t3(线程的销毁时间),所有当我们需要反复创建线程就可以使用线程池。
线程池作用:线程池是去解决线程反复的创建和销毁,解决线程反复的使用。
public class AsyncTaskTest {
private static ThreadPoolExecutor threadPoolExecutor
;
private static final BlockingQueue
<Runnable
> sPoolWorkQueue
=
new LinkedBlockingQueue<Runnable
>(40);
static {
threadPoolExecutor
= new ThreadPoolExecutor(
5,
10,
30,
TimeUnit
.SECONDS,
sPoolWorkQueue
,
new ThreadFactory() {
@Override
public Thread
newThread(Runnable r
) {
Thread thread
= new Thread(r
,"自己线程的名字");
thread
.setDaemon(false);
return new Thread(r
);
}
});
}
public static void main(String
[] args
){
for (int i
= 0; i
< 30; i
++) {
Runnable runnable
= new Runnable() {
@Override
public void run() {
try {
Thread
.sleep(2000);
System
.out
.println("下载完成"+Thread
.currentThread().getName());
} catch (Exception e
) {
e
.printStackTrace();
}
}
};
threadPoolExecutor
.execute(runnable
);
}
}
}
执行结果: 每隔2秒都会执行5个线程任务
可能会疑问 “线程池核心数量” 和 “线程池最大数量” 有什么区别。我们修改一下缓存队列数量。修改为10,看下执行结果。 解析: 1.线程池中最大核心数是5 2.线程池最大线程数量是10 3.缓存队列数量为10 4.要执行的Runnable为30
报错原因:首先要执行的Runnabler为30个,30个都要放到队列中,而缓存队列中最多只能存放10个,还有20个没法放,这个时候最大线程数是10,非核心线程数也是5,此时就会拿5个Runnabler来执行,会创建5个非核心线程,目前线程池中达到了10个线程,但是还有20个没法存放,也就意味着20个Runnable没办法执行,此时就会报错。
常用的缓存池: BlockingQueue:先进先出的一个队列。 SynchronousQueue:线程安全队列,他里面没有固定的缓存的(okhttp使用的) PriorityBlockingQueue:无序的根据优先级进行排序,执行对象要实现Comparable 作比较
5.常用的BaseActivity模板模式
public abstract
class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState
) {
super.onCreate(savedInstanceState
);
setContentView();
initView();
initTitle();
initData(savedInstanceState
);
}
protected abstract
void initData(Bundle savedInstanceState
);
protected abstract
void initTitle();
protected abstract
void initView();
protected abstract
void setContentView();
public void startActivity(Class
<? extends BaseActivity> clazz
){
Intent intent
= new Intent(this,clazz
);
startActivity(intent
);
}
...
}
6.UML图