您的位置:首页 > 移动开发 > Android开发

android 线程框架

2016-02-16 10:26 525 查看
android 开发中涉及线程的部分主要分为:

常用的线程开发对象与线程池的使用.

常用开发对象:

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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: