一、介绍生产者消费者模式(移动架构--9.生产者消费者模式)
二、传统的线程继承自Thread或实现Runnable接口,线程的执行没有返回值,引出FutureTask、Callable、Excutor。Callable在子线程中执行,因为被FutureTask给包装了,FutureTask实现了Runnable接口。FutureTask称为异步任务,返回值通过get方法调用,get是阻塞的,只有当FutureTask的done方法执行完才能拿到。FutureTask的执行是被丢到线程池中的,通过线程池的execute方法执行。
简单的FutureTask,Callable,Excutor例子
public class Client{
//异步任务的执行
static class Task implements Callable{
@Override
public Integer call() throws Exception {
int i = 0;
for (; i < 10; i++) {
try {
System.out.println(Thread.currentThread().getName() + "_"+i);
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return i;
}
}
public static void main(String[] args) {
Task work = new Task();
FutureTask future = new FutureTask(work){
@Override
protected void done() {
try {
System.out.println("done:"+get());
} catch (Exception e) {
e.printStackTrace();
}
}
};
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(future);
}
}
Callable为异步任务提供了返回值,FutureTask包装了异步任务,丢给线程池去执行。
三、介绍二是为了能看懂AsyncTask的源码
3.1在构造方法中:
mWorker = new WorkerRunnable()
private static abstract class
WorkerRunnable implements Callable
mFuture = new FutureTask(mWorker)
protected void done()---->postResultIfNotInvoked(get());
// 主线程的looper
// public InternalHandler() {
// super(Looper.getMainLooper());
// }
3.2执行execute方法其实是调用线程池执行的
executeOnExecutor(sDefaultExecutor, params)
SerialExecutor implements Executor
因此当有很多异步任务,会造成异常,就是线程池的线程已经达到最大值,并且异步任务队列已经慢的情况下。
Executors.newScheduledThreadPool(25)
异步任务也会造成内存泄漏
class MyTask extends AsyncTask{
int i = 0;
@Override
protected Void doInBackground(Void... params) {
while(!isCancelled()){//在此判断异步任务是否取消
}
return null;
}
}
//Activity onDestory的时候
task.cancel(true);
四、HandlerThread
HandlerThred=Handler+Thread;
子线程返回的结果通过Handler发送消息给主线程的Looper增加了主线程的压力,因此HandlerThread内部有自己的looper,减小主线程的压力。
简单使用
HandlerThread handThread = new HandlerThread("this is handthread");
Handler subHandler = new Handler(handThread.getLooper());
//这样通过subHandler发送的消息会交给子线的Looper处理
//在子线程更新UI的方法
//1.runOnUiThread(new Runnable(){@Override void run(){代码}})
//2.Handler hand = new Handler(getMainLooper()).
// .post(new Runnable(){@Override void run(){代码})
HandThread中主要介绍打开相机,与回调相机采集的数据,一个线程执行两个任务
用AsyncTask实现,其实一个在子线程一个在主线程
class MyTask extends AsyncTask implements PreviewCallback{
//doInBackground子线程
//onPreviewFrame主线程
}
//原因分析
public class Task extends Thread{
@Override
void run(){
System.out.println(Thread.currentThread().getName() + "_run");
}
void dosomething(){
System.out.println(Thread.currentThread().getName() + "_dosomething");
}
}
//调用
Task task = new Task();
task.start();
task.dosomething();
利用HandlerThread可以实现打开相机和回调预览
//1.创建HandlerThread
HandlerThread mHandlerThread = new HandlerThread("my_handlerthread");
//2.具体要做的事情打开相机+回调显示
class MyTask implements Runnable, PreviewCallback{……}
//3.调用实现一个线程两个任务
mHandlerThread.start();
subHandler = new Handler(mHandlerThread.getLooper());
subHandler.post(new MyTask());
特殊性,回调的执行源码,有looper的则用子线程的looper否则用主线程的looper因此在一个子线程中两个任务
五、IntentService
IntentService = Intent+HandlerThread+Service
直接在服务中启动一个HandlerThread,提高了子线程的优先级。
public class MyIntentService extends IntentService {
//至少要有一个空的构造方法
public MyIntentService() {
super("MyIntentService");
}
public MyIntentService(String name) {
super(name);
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.d("jason", Thread.currentThread().getName() + "_onStart");
}
//UI线程发送Intent,会在子线程中执行
@Override
protected void onHandleIntent(Intent intent) {
Log.d("jason", Thread.currentThread().getName() +
"_onHandleIntent");
}
}
//调用Intent intent = new Intent(this,MyIntentService.class);
//startService(intent);
六Loader保证子线程与Activity生命周期一致(LoaderManager)
//1.执行Loader回调
private MyLoaderCallback mLoaderCallback = new MyLoaderCallback();
getLoaderManager().initLoader(0, null, mLoaderCallback);
//2.实现LoaderCallbacks
private class MyLoaderCallback
implements
LoaderManager.LoaderCallbacks {
//创建Loader
@Override
public Loader onCreateLoader(int id, Bundle args) {
//加载的过程在子线程中进行
CursorLoader loader = new CursorLoader(MainActivity.this,
CallLog.Calls.CONTENT_URI, CALLLOG_PROJECTION,
null, null, CallLog.Calls.DEFAULT_SORT_ORDER);
Log.d(TAG, "onCreateLoader");
return loader;
}
//Loader检测底层数据,当检测到改变时,
//自动执行新的载入获取最新数据
//Activity/Fragment所需要做的就是初始化Loader,
//并且对任何反馈回来的数据进行响应。
@Override
public void onLoadFinished(Loader loader, Cursor data) {
if (data == null)
return;
mAdapter.swapCursor(data);
Log.d(TAG, "onLoadFinished data count = " + data.getCount());
}
//OnDestroy,自动停止load
@Override
public void onLoaderReset(Loader loader) {
Log.d(TAG, "onLoaderReset");
mAdapter.swapCursor(null);
}
}