android 线程框架
2016-02-16 10:26
525 查看
android 开发中涉及线程的部分主要分为:
常用的线程开发对象与线程池的使用.
常用开发对象:
1 AsynckTask
自定义类,继承此类,就可以做轻量级的Ui更新操作.
主要复写的方法有:
onPreExecute()
doInBackground()
onProgressUpdate()
onPostExecute()
该类底层封装了线程池与handler来处理异步任务的请求.
其中线程池有两个,一个负责任务的排列,一个负责任务的真正执行.
而且,从底层的实现来看,对于同一个主进程而言,其所在的所有的
AsnycTask 默认的执行是串行的.
例如下面代码是 串行的:
如果想要并行的执行:可以使用另外的方法,不过是android 3.0以上才使用.
当Activity配置信息发生改变之后,当前的线程任务可能被销毁.
使用AsyncTask的注意事项:
1 异步任务只能在主线程中调用.
2 一个实例只能执行一次.
3 不能手动执行其内部的执行方法.
AsyncTask使用实例:
android 电话源码 CallLogAsync.java
2 HandlerThread 其本质是一个封装了消息循环的线程,可以将执行的任务放在线程中执行.
这样就可以将handler执行的任务放在子线程中执行.
最后在Activity 销毁的时候,释放消息的循环.
3 IntentService 内部封装了 HandlerThread来处理后台的任务,执行外城之后,其自动的销毁. 在执行任务的时候,其优先级比较高,不容易被后台杀死,而且,其任务的执行也是串行的.
线程池:
线程池的优点:
1 重用线程,避免过分开销
2 控制线程最大的并发数
3 对线程进行简单的管理
代码编写,提供了线程池的操作类:
常用的线程开发对象与线程池的使用.
常用开发对象:
1 AsynckTask
自定义类,继承此类,就可以做轻量级的Ui更新操作.
主要复写的方法有:
onPreExecute()
doInBackground()
onProgressUpdate()
onPostExecute()
该类底层封装了线程池与handler来处理异步任务的请求.
其中线程池有两个,一个负责任务的排列,一个负责任务的真正执行.
而且,从底层的实现来看,对于同一个主进程而言,其所在的所有的
AsnycTask 默认的执行是串行的.
例如下面代码是 串行的:
new MyAsyncTask("AsnyckTask#1").execute(""); new MyAsyncTask("AsnyckTask#2").execute(""); new MyAsyncTask("AsnyckTask#3").execute(""); new MyAsyncTask("AsnyckTask#4").execute("");
如果想要并行的执行:可以使用另外的方法,不过是android 3.0以上才使用.
new MyAsyncTask("AsnyckTask#1"). executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "");
当Activity配置信息发生改变之后,当前的线程任务可能被销毁.
使用AsyncTask的注意事项:
1 异步任务只能在主线程中调用.
2 一个实例只能执行一次.
3 不能手动执行其内部的执行方法.
AsyncTask使用实例:
android 电话源码 CallLogAsync.java
/** * AsyncTask to save calls in the DB. */ @SuppressLint("NewApi") private class AddCallTask extends AsyncTask<AddCallArgs, Void, Uri[]> { @Override protected Uri[] doInBackground(AddCallArgs... callList) { int count = callList.length; Uri[] result = new Uri[count]; for (int i = 0; i < count; i++) { AddCallArgs c = callList[i]; try { // May block. result[i] = Calls.addCall( c.ci, c.context, c.number, c.presentation, c.callType, c.timestamp, c.durationInSec, c.callToken, c.fromDevice); } catch (Exception e) { // This must be very rare but may happen in legitimate cases. // e.g. If the phone is encrypted and thus write request fails, it may // cause some kind of Exception (right now it is IllegalArgumentException, but // might change). // // We don't want to crash the whole process just because of that. // Let's just ignore it and leave logs instead. Log.e(TAG, "Exception raised during adding CallLog entry: " + e); result[i] = null; } } return result; } // Perform a simple sanity check to make sure the call was // written in the database. Typically there is only one result // per call so it is easy to identify which one failed. @Override protected void onPostExecute(Uri[] result) { for (Uri uri : result) { if (uri == null) { Log.e(TAG, "Failed to write call to the log."); } } } } 异步任务只能在主线程中调用: /** * Non blocking version of CallLog.addCall(...) */ public AsyncTask addCall(AddCallArgs args) { assertUiThread(); return new AddCallTask().execute(args); } private void assertUiThread() { if (!Looper.getMainLooper().equals(Looper.myLooper())) { throw new RuntimeException("Not on the UI thread!"); } }
2 HandlerThread 其本质是一个封装了消息循环的线程,可以将执行的任务放在线程中执行.
handlerthread=new HandlerThread("handlerThread"); private Handler handler=new Handler(handlerthread.getLooper()){ public void handleMessage(android.os.Message msg) { switch(msg.what){ } }; };
这样就可以将handler执行的任务放在子线程中执行.
最后在Activity 销毁的时候,释放消息的循环.
@Override protected void onDestroy() { // TODO 自动生成的方法存根 super.onDestroy(); //释放循环 handlerthread.quitSafely(); }
3 IntentService 内部封装了 HandlerThread来处理后台的任务,执行外城之后,其自动的销毁. 在执行任务的时候,其优先级比较高,不容易被后台杀死,而且,其任务的执行也是串行的.
public class LocalIntentService extends IntentService { public LocalIntentService(String name) { super(name); // TODO 自动生成的构造函数存根 } @Override protected void onHandleIntent(Intent intent) { // TODO 自动生成的方法存根 String action=intent.getStringExtra("task_action"); SystemClock.sleep(3000); Log.v("tag","执行完毕."); } }
线程池:
线程池的优点:
1 重用线程,避免过分开销
2 控制线程最大的并发数
3 对线程进行简单的管理
代码编写,提供了线程池的操作类:
public class ThreadPoolUtil { private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); private static final int CORE_POOL_SIZE = CPU_COUNT + 1; private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; private static final int KEEP_ALIVE = 1; private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); public Thread newThread(Runnable r) { return new Thread(r, "ThreadPool #" + mCount.getAndIncrement()); } }; private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128); /** * CORE_POOL_SIZE 核心线程数 * MAXIMUM_POOL_SIZE 最大线程数 * KEEP_ALIVE 非核心线程数的超时时间 * TimeUnit.SECONDS 时间的计量单位 * sPoolWorkQueue 线程队列 * sThreadFactory 生成线程的工厂 */ public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); public static ExecutorService fixedThreadPool; public static ExecutorService cachedThreadPool; public static ScheduledExecutorService scheduledThreadPool; public static ExecutorService singleThreadPool; //线程的种类 public enum Type{ defaulted,fixed,cached,scheduled,single } /** * 执行任务 */ public static void execute(Type type,int count,Runnable runnable){ switch(type){ case fixed: fixedThreadPool(count).execute(runnable); break; case cached: cachedThreadPool().execute(runnable); case single: singleThreadPool().execute(runnable); break; default : getDefaultPool().execute(runnable); break; } } /** * * @param count * @param delaytime * @param ratime 小于0 表示不用重复执行 * @param runnable */ public static void execute(int count,int delaytime,int ratime,Runnable runnable){ ScheduledExecutorService service=scheduledThreadPool(count); if(ratime<=0){ service.schedule(runnable,delaytime,TimeUnit.MILLISECONDS); }else{ service.scheduleAtFixedRate(runnable, delaytime, ratime, TimeUnit.MILLISECONDS); } } /** * 获取默认的线程池 * @return */ public static Executor getDefaultPool(){ return THREAD_POOL_EXECUTOR; } /** * 只有指定的核心线程数,所以,特定是反映速度非常快 * @param nThreads * @return */ public static ExecutorService fixedThreadPool(int nThreads){ if(fixedThreadPool==null){ synchronized (ThreadPoolUtil.class) { if(fixedThreadPool==null){ fixedThreadPool=Executors.newFixedThreadPool(nThreads); } } } return fixedThreadPool; } /** * 适合执行大量的,耗时较少的任务 */ public static ExecutorService cachedThreadPool(){ if(cachedThreadPool==null){ synchronized (ThreadPoolUtil.class) { if(cachedThreadPool==null){ cachedThreadPool=Executors.newCachedThreadPool(); } } } return cachedThreadPool; } /** * 执行定时任务与具有固定周期的重复任务 * @param nThreadCount * @return */ public static ScheduledExecutorService scheduledThreadPool(int nThreadCount){ if(scheduledThreadPool==null){ synchronized (ThreadPoolUtil.class) { if(scheduledThreadPool==null){ scheduledThreadPool=Executors.newScheduledThreadPool(nThreadCount); } } } return scheduledThreadPool; } /** * 保证所有的任务在同一个线程中顺序执行 * @return */ public static ExecutorService singleThreadPool(){ if(singleThreadPool==null){ synchronized (ThreadPoolUtil.class) { if(singleThreadPool==null){ singleThreadPool=Executors.newSingleThreadExecutor(); } } } return singleThreadPool; } }
相关文章推荐
- Android4.0.x Home键事件拦截监听的方法
- android 使用内容提供者获取手机联系人
- Can not perform this action after onSaveInstanceState
- [Android] AS 中 Gradle 配置运行浅析
- 认清Android Studio下的Gradle是什么
- Android Studio ADB响应失败 Waiting for adb
- Mac OS下Android开发环境配置详解
- Android Studio新建工程时SDK缺少extra-android-m2repository解决办法
- Android电源管理-休眠简要分析
- Android获取屏幕或View宽度和高度的方法
- 优化布局在Android–减少过度渲染
- Android蓝牙4.0BLE
- 查看android api的网址,速度非常快
- android安全添加新版本中的代码
- 2016_完整的Android课程
- Android快速开发(2)
- 干货分享:分析Android应用使用的技术框架和开源库
- 刮刮卡的实现
- Android Studio系列教程四--Gradle基础
- Android 下的EXIF