Android线程池使用

阅读更多
一:无大小限制的线程池执行效果如下
Android线程池使用_第1张图片
二:限制按顺序来执行任务的线程池效果如下
Android线程池使用_第2张图片
三:一个一个任务的执行线程池效果如下(与按顺序执行效果是一样的,只是内部实现稍有不同)
Android线程池使用_第3张图片
四:按指定个数来执行任务的线程池效果如下
Android线程池使用_第4张图片
五:创建一个可在指定时间里执行任务的线程池,亦可重复执行,不常用,效果与四相同
Android线程池使用_第5张图片
六:按指定工厂模式来执行的线程池,效果与四、五一样,但用方式六创建的线程池都有在工厂中指定的线程属性,
比如:线程名字、是否为用户线程等等属性
Android线程池使用_第6张图片
七:线程池中任务执行时可暂停效果图如下
Android线程池使用_第7张图片
八:用Runnable、ConcurrentLinkedQueue、ConcurrentMap、Future、ExecutorService关联实现的效果图如下
Android线程池使用_第8张图片
哦的了,效果看完了,现在就请大家自行修改AndroidManifest.xml中主Activity的入口来看两种不同方式实现的代码效果吧,首先,先贴一下Main.java类的代码,希望大家详细看里面的注释,一定要详细看,你不会吃亏的,相信我!


方式一(纯ExecutorService、AsyncTask、Runnable关联实现相关文件如下):

1.1:主类文件(Main.java)
/*
 * FileName:  Main.java
 * CopyRight:  Belong to   own 
 * Description:  
 * Modify By :  XiaoMaGuo ^_^ 
 * Modify Date:   2013-10-15
 * Follow Order No.:  
 * Modify Order No.:  
 * Modify Content:  
 */
package com.xiaoma.threadpooltest;
 
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
 
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
 
/**
 * @TODO [The Class File Description]
 * @author XiaoMaGuo ^_^
 * @version [version-code, 2013-10-15]
 * @since [Product/module]
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class Main extends Activity
{
    private static int order = 0;
 
    /** 总共多少任务(根据CPU个数决定创建活动线程的个数,这样取的好处就是可以让手机承受得住) */
    // private static final int count = Runtime.getRuntime().availableProcessors() * 3 + 2;
 
    /** 总共多少任务(我是在模拟器里面跑的,为了效果明显,所以写死了为10个,如果在手机上的话,推荐使用上面的那个count) */
    private static final int count = 10;
 
    /** 每次只执行一个任务的线程池 */
    private static ExecutorService singleTaskExecutor = null;
 
    /** 每次执行限定个数个任务的线程池 */
    private static ExecutorService limitedTaskExecutor = null;
 
    /** 所有任务都一次性开始的线程池 */
    private static ExecutorService allTaskExecutor = null;
 
    /** 创建一个可在指定时间里执行任务的线程池,亦可重复执行 */
    private static ExecutorService scheduledTaskExecutor = null;
 
    /** 创建一个可在指定时间里执行任务的线程池,亦可重复执行(不同之处:使用工程模式) */
    private static ExecutorService scheduledTaskFactoryExecutor = null;
 
    private List mTaskList = null;
 
    /** 任务是否被取消 */
    private boolean isCancled = false;
 
    /** 是否点击并取消任务标示符 */
    private boolean isClick = false;
 
    /** 线程工厂初始化方式一 */
    ThreadFactory tf = Executors.defaultThreadFactory();
 
    /** 线程工厂初始化方式二 */
    private static class ThreadFactoryTest implements ThreadFactory
    {
 
        @Override
        public Thread newThread(Runnable r)
        {
            Thread thread = new Thread(r);
            thread.setName("XiaoMaGuo_ThreadFactory");
            thread.setDaemon(true); // 将用户线程变成守护线程,默认false
            return thread;
        }
    }
 
    static
    {
        singleTaskExecutor = Executors.newSingleThreadExecutor();// 每次只执行一个线程任务的线程池
        limitedTaskExecutor = Executors.newFixedThreadPool(3);// 限制线程池大小为7的线程池
        allTaskExecutor = Executors.newCachedThreadPool(); // 一个没有限制最大线程数的线程池
        scheduledTaskExecutor = Executors.newScheduledThreadPool(3);// 一个可以按指定时间可周期性的执行的线程池
        scheduledTaskFactoryExecutor = Executors.newFixedThreadPool(3, new ThreadFactoryTest());// 按指定工厂模式来执行的线程池
        scheduledTaskFactoryExecutor.submit(new Runnable()
        {
 
            @Override
            public void run()
            {
                Log.i("KKK", "This is the ThreadFactory Test  submit Run! ! ! ");
            }
        });
    };
 
    @Override
    public void onCreate(Bundle icicle)
    {
        super.onCreate(icicle);
        setContentView(R.layout.demo);
        final ListView taskList = (ListView)findViewById(R.id.task_list);
        taskList.setAdapter(new AsyncTaskAdapter(getApplication(), count));
        taskList.setOnItemClickListener(new OnItemClickListener()
        {
 
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id)
            {
                if (position == 0) // 以第一项为例,来测试关闭线程池
                {
                    /**
                     * 会关闭线程池方式一:但不接收新的Task,关闭后,正在等待 执行的任务不受任何影响,会正常执行,无返回值!
                     */
                    // allTaskExecutor.shutdown();
 
                    /**
                     * 会关闭线程池方式二:也不接收新的Task,并停止正等待执行的Task(也就是说, 执行到一半的任务将正常执行下去),最终还会给你返回一个正在等待执行但线程池关闭却没有被执行的Task集合!
                     */
                    List unExecRunn = allTaskExecutor.shutdownNow();
 
                    for (Runnable r : unExecRunn)
                    {
                        Log.i("KKK", "未执行的任务信息:=" + unExecRunn.toString());
                    }
                    Log.i("KKK", "Is shutdown ? = " + String.valueOf(allTaskExecutor.isShutdown()));
                    allTaskExecutor = null;
                }
 
                // 以第二项为例来测试是否取消执行的任务
                AsyncTaskTest sat = mTaskList.get(1);
                if (position == 1)
                {
                    if (!isClick)
                    {
                        sat.cancel(true);
                        isCancled = true;
                        isClick = !isClick;
                    }
                    else
                    {
                        sat.cancel(false);
                        isCancled = false;
                        // isClick = false;
                        isClick = !isClick;
                        if (null != sat && sat.getStatus() == AsyncTask.Status.RUNNING)
                        {
                            if (sat.isCancelled())
                            {
                                sat = new AsyncTaskTest(sat.mTaskItem);
                            }
                            else
                            {
                                Toast.makeText(Main.this, "A task is already running, try later", Toast.LENGTH_SHORT)
                                    .show();
                            }
                        }
 
                        /**
                         * 由于上面测试关闭,在不重新生成allTaskExecutor的同时,会报异常(没有可以使用的线程池,故此处重新生成线程池对象)
                         */
                        if (allTaskExecutor == null)
                        {
                            allTaskExecutor = Executors.newCachedThreadPool();
                        }
                        sat.executeOnExecutor(allTaskExecutor); // The task is already running(这也是个异常哦,小心使用! )
                    }
                }
                else
                {
                    sat.cancel(false);
                    isCancled = false;
                    // sat.execute(sat.mTaskItem);
                    // sat.executeOnExecutor(allTaskExecutor);
                }
 
            }
        });
    }
 
    /**
     * @TODO [ListView Item的条目适配器]
     * @author XiaoMaGuo ^_^
     * @version [version-code, 2013-10-22]
     * @since [Product/module]
     */
    private class AsyncTaskAdapter extends BaseAdapter
    {
        private Context mContext;
 
        private LayoutInflater mFactory;
 
        private int mTaskCount;
 
        public AsyncTaskAdapter(Context context, int taskCount)
        {
            mContext = context;
            mFactory = LayoutInflater.from(mContext);
            mTaskCount = taskCount;
            mTaskList = new ArrayList(taskCount);
        }
 
        @Override
        public int getCount()
        {
            return mTaskCount;
        }
 
        @Override
        public Object getItem(int position)
        {
            return mTaskList.get(position);
        }
 
        @Override
        public long getItemId(int position)
        {
            return position;
        }
 
        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
            if (convertView == null)
            {
                convertView = mFactory.inflate(R.layout.list_view_item, null);
                AsyncTaskTest task = new AsyncTaskTest((MyListItem)convertView);
 
                /**
                 * 下面两种任务执行效果都一样,形变质不变
                 * */
                // task.execute();
                // task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
 
                /**
                 * 下面的方式在小于API 11级时效果是一样的,但在高版本中的稍微有点不同,可以看以下AsyncTask核心变量的定义就知道了使用如下
                 * 方式时,系统会默认的采用五个一组,五个一组的方式来执行我们的任务,定义在:AsyncTask.class中,private static final int CORE_POOL_SIZE = 5;
                 * */
                // use AsyncTask#THREAD_POOL_EXECUTOR is the same to older version #execute() (less than API 11)
                // but different from newer version of #execute()
                // task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
 
                /**
                 * 一个一个执行我们的任务,效果与按顺序执行是一样的(AsyncTask.SERIAL_EXECUTOR)
                 * */
                // task.executeOnExecutor(singleTaskExecutor);
 
                /**
                 * 按我们指定的个数来执行任务的线程池
                 * */
                // task.executeOnExecutor(limitedTaskExecutor);
 
                /**
                 * 不限定指定个数的线程池,也就是说:你往里面放了几个任务,他全部同一时间开始执行, 不管你手机受得了受不了
                 * */
                task.executeOnExecutor(allTaskExecutor);
 
                /**
                 * 创建一个可在指定时间里执行任务的线程池,亦可重复执行
                 * */
                // task.executeOnExecutor(scheduledTaskExecutor);
 
                /**
                 * 创建一个按指定工厂模式来执行任务的线程池,可能比较正规,但也不常用
                 */
                // task.executeOnExecutor(scheduledTaskFactoryExecutor);
                mTaskList.add(task);
            }
            return convertView;
        }
    }
 
    class AsyncTaskTest extends AsyncTask
    {
        private MyListItem mTaskItem;
 
        private String id;
 
        private AsyncTaskTest(MyListItem item)
        {
            mTaskItem = item;
            if (order < count || order == count)
            {
                id = "执行:" + String.valueOf(++order);
            }
            else
            {
                order = 0;
                id = "执行:" + String.valueOf(++order);
            }
        }
 
        @Override
        protected void onPreExecute()
        {
            mTaskItem.setTitle(id);
        }
 
        /**
         * Overriding methods
         */
        @Override
        protected void onCancelled()
        {
            super.onCancelled();
        }
 
        @Override
        protected Void doInBackground(Void... params)
        {
            if (!isCancelled() && isCancled == false) // 这个地方很关键,如果不设置标志位的话,直接setCancel(true)是无效的
            {
                int prog = 0;
 
                /**
                 * 下面的while中,小马写了个分支用来做个假象(任务东西刚开始下载的时候,速度快,快下载完成的时候就突然间慢了下来的效果, 大家可以想象一下,类似
                 * :PP手机助手、91手机助手中或其它手机应用中,几乎都有这个假象,开始快,结束时就下载变慢了,讲白了 就是开发的人不想让你在下载到大于一半的时候,也就是快下载完的时候去点取消,你那样得多浪费
                 * !所以造个假象,让你不想去取消而已)
                 */
                while (prog < 101)
                {
 
                    if ((prog > 0 || prog == 0) && prog < 70) // 小于70%时,加快进度条更新
                    {
                        SystemClock.sleep(100);
                    }
                    else
                    // 大于70%时,减慢进度条更新
                    {
                        SystemClock.sleep(300);
                    }
 
                    publishProgress(prog); // 更新进度条
                    prog++;
                }
            }
            return null;
        }
 
        @Override
        protected void onPostExecute(Void result)
        {
        }
 
        @Override
        protected void onProgressUpdate(Integer... values)
        {
            mTaskItem.setProgress(values[0]); // 设置进度
        }
    }
}
 
/**
 * @TODO [一个简单的自定义 ListView Item]
 * @author XiaoMaGuo ^_^
 * @version [version-code, 2013-10-22]
 * @since [Product/module]
 */
class MyListItem extends LinearLayout
{
    private TextView mTitle;
 
    private ProgressBar mProgress;
 
    public MyListItem(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }
 
    public MyListItem(Context context)
    {
        super(context);
    }
 
    public void setTitle(String title)
    {
        if (mTitle == null)
        {
            mTitle = (TextView)findViewById(R.id.task_name);
        }
        mTitle.setText(title);
    }
 
    public void setProgress(int prog)
    {
        if (mProgress == null)
        {
            mProgress = (ProgressBar)findViewById(R.id.task_progress);
        }
        mProgress.setProgress(prog);
    }
}


1.2:布局文件


    




方式二(Runnable、ConcurrentLinkedQueue、ConcurrentMap、Future、ExecutorService关联实现的相关文件如 下):
2.1:主类文件(MyRunnableActivity.java)
/*
 * FileName:  MyRunnableActivity.java
 * CopyRight:  Belong to   own 
 * Description:  
 * Modify By :  XiaoMaGuo ^_^ 
 * Modify Date:   2013-10-21
 * Follow Order No.:  
 * Modify Order No.:  
 * Modify Content:  
 */
package com.xiaoma.threadpooltest;
 
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
 
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ProgressBar;
import android.widget.Toast;
 
/**
 * @TODO [线程池控制 ]
 * @author XiaoMaGuo ^_^
 * @version [version-code, 2013-10-22]
 * @since [Product/module]
 */
public class MyRunnableActivity extends Activity implements OnClickListener
{
 
    /** 任务执行队列 */
    private ConcurrentLinkedQueue taskQueue = null;
 
    /**
     * 正在等待执行或已经完成的任务队列
     * 
     * 备注:Future类,一个用于存储异步任务执行的结果,比如:判断是否取消、是否可以取消、是否正在执行、是否已经完成等
     * 
     * */
    private ConcurrentMap taskMap = null;
 
    /**
     * 创建一个不限制大小的线程池 此类主要有以下好处 1,以共享的无界队列方式来运行这些线程. 2,执行效率高。 3,在任意点,在大多数 nThreads 线程会处于处理任务的活动状态
     * 4,如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。
     * 
     * */
    private ExecutorService mES = null;
 
    /** 在此类中使用同步锁时使用如下lock对象即可,官方推荐的,不推荐直接使用MyRunnableActivity.this类型的,可以详细读一下/framework/app下面的随便一个项目 */
    private Object lock = new Object();
 
    /** 唤醒标志,是否唤醒线程池工作 */
    private boolean isNotify = true;
 
    /** 线程池是否处于运行状态(即:是否被释放!) */
    private boolean isRuning = true;
 
    /** 任务进度 */
    private ProgressBar pb = null;
 
    /** 用此Handler来更新我们的UI */
    private Handler mHandler = null;
 
    /**
     * Overriding methods
     * 
     * @param savedInstanceState
     */
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_runnable_main);
        init();
    }
 
    public void init()
    {
        pb = (ProgressBar)findViewById(R.id.progressBar1);
        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);
        findViewById(R.id.button3).setOnClickListener(this);
        findViewById(R.id.button4).setOnClickListener(this);
        findViewById(R.id.button5).setOnClickListener(this);
        taskQueue = new ConcurrentLinkedQueue();
        taskMap = new ConcurrentHashMap();
        if (mES == null)
        {
            mES = Executors.newCachedThreadPool();
        }
 
        // 用于更新ProgressBar进度条
        mHandler = new Handler()
        {
            /**
             * Overriding methods
             * 
             * @param msg
             */
            @Override
            public void handleMessage(Message msg)
            {
                super.handleMessage(msg);
                pb.setProgress(msg.what);
            }
 
        };
 
    }
 
    /**
     * Overriding methods
     * 
     * @param v
     */
    @Override
    public void onClick(View v)
    {
        switch (v.getId())
        {
            case R.id.button1:
                start();
                break;
            case R.id.button2:
                stop();
                break;
            case R.id.button3:
                reload(new MyRunnable(mHandler));
                break;
            case R.id.button4:
                release();
                break;
            case R.id.button5:
                addTask(new MyRunnable(mHandler));
                break;
 
            default:
                break;
        }
    }
 
    /**
     * 
     */
    private void addTask(final MyRunnable mr)
    {
 
        mHandler.sendEmptyMessage(0);
 
        if (mES == null)
        {
            mES = Executors.newCachedThreadPool();
            notifyWork();
        }
 
        if (taskQueue == null)
        {
            taskQueue = new ConcurrentLinkedQueue();
        }
 
        if (taskMap == null)
        {
            taskMap = new ConcurrentHashMap();
        }
 
        mES.execute(new Runnable()
        {
 
            @Override
            public void run()
            {
                /**
                 * 插入一个Runnable到任务队列中 这个地方解释一下,offer跟add方法,试了下,效果都一样,没区别,官方的解释如下: 1 offer : Inserts the specified
                 * element at the tail of this queue. As the queue is unbounded, this method will never return
                 * {@code false}. 2 add: Inserts the specified element at the tail of this queue. As the queue is
                 * unbounded, this method will never throw {@link IllegalStateException} or return {@code false}.
                 * 
                 * 
                 * */
                taskQueue.offer(mr);
                // taskQueue.add(mr);
                notifyWork();
            }
        });
 
        Toast.makeText(MyRunnableActivity.this, "已添加一个新任务到线程池中 !", 0).show();
    }
 
    /**
     * 
     */
    private void release()
    {
        Toast.makeText(MyRunnableActivity.this, "释放所有占用的资源!", 0).show();
 
        /** 将ProgressBar进度置为0 */
        mHandler.sendEmptyMessage(0);
        isRuning = false;
 
        Iterator iter = taskMap.entrySet().iterator();
        while (iter.hasNext())
        {
            Map.Entry entry = (Map.Entry)iter.next();
            Future result = entry.getKey();
            if (result == null)
            {
                continue;
            }
            result.cancel(true);
            taskMap.remove(result);
        }
        if (null != mES)
        {
            mES.shutdown();
        }
 
        mES = null;
        taskMap = null;
        taskQueue = null;
 
    }
 
    /**
     * 
     */
    private void reload(final MyRunnable mr)
    {
        mHandler.sendEmptyMessage(0);
        if (mES == null)
        {
            mES = Executors.newCachedThreadPool();
            notifyWork();
        }
 
        if (taskQueue == null)
        {
            taskQueue = new ConcurrentLinkedQueue();
        }
 
        if (taskMap == null)
        {
            taskMap = new ConcurrentHashMap();
        }
 
        mES.execute(new Runnable()
        {
 
            @Override
            public void run()
            {
                /** 插入一个Runnable到任务队列中 */
                taskQueue.offer(mr);
                // taskQueue.add(mr);
                notifyWork();
            }
        });
 
        mES.execute(new Runnable()
        {
            @Override
            public void run()
            {
                if (isRuning)
                {
                    MyRunnable myRunnable = null;
                    synchronized (lock)
                    {
                        myRunnable = taskQueue.poll(); // 从线程队列中取出一个Runnable对象来执行,如果此队列为空,则调用poll()方法会返回null
                        if (myRunnable == null)
                        {
                            isNotify = true;
                        }
                    }
 
                    if (myRunnable != null)
                    {
                        taskMap.put(mES.submit(myRunnable), myRunnable);
                    }
                }
            }
        });
    }
 
    /**
     * 
     */
    private void stop()
    {
 
        Toast.makeText(MyRunnableActivity.this, "任务已被取消!", 0).show();
 
        for (MyRunnable runnable : taskMap.values())
        {
            runnable.setCancleTaskUnit(true);
        }
    }
 
    /**
     * 
     */
    private void start()
    {
 
        if (mES == null || taskQueue == null || taskMap == null)
        {
            Log.i("KKK", "某资源是不是已经被释放了?");
            return;
        }
        mES.execute(new Runnable()
        {
            @Override
            public void run()
            {
                if (isRuning)
                {
                    MyRunnable myRunnable = null;
                    synchronized (lock)
                    {
                        myRunnable = taskQueue.poll(); // 从线程队列中取出一个Runnable对象来执行,如果此队列为空,则调用poll()方法会返回null
                        if (myRunnable == null)
                        {
                            isNotify = true;
                            // try
                            // {
                            // myRunnable.wait(500);
                            // }
                            // catch (InterruptedException e)
                            // {
                            // e.printStackTrace();
                            // }
                        }
                    }
 
                    if (myRunnable != null)
                    {
                        taskMap.put(mES.submit(myRunnable), myRunnable);
                    }
                }
 
            }
        });
    }
 
    private void notifyWork()
    {
        synchronized (lock)
        {
            if (isNotify)
            {
                lock.notifyAll();
                isNotify = !isNotify;
            }
        }
    }
}


2.2:辅助类(MyRunnable.java)
/*
 * FileName:  MyRunnable.java
 * CopyRight:  Belong to   own 
 * Description:  
 * Modify By :  XiaoMaGuo ^_^ 
 * Modify Date:   2013-10-21
 * Follow Order No.:  
 * Modify Order No.:  
 * Modify Content:  
 */
package com.xiaoma.threadpooltest;
 
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
 
/**
 * @TODO [The Class File Description]
 * @author XiaoMaGuo ^_^
 * @version [version-code, 2013-10-21]
 * @since [Product/module]
 */
public class MyRunnable implements Runnable
{
 
    private boolean cancleTask = false;
 
    private boolean cancleException = false;
 
    private Handler mHandler = null;
 
    public MyRunnable(Handler handler)
    {
        mHandler = handler;
    }
 
    /**
     * Overriding methods
     */
    @Override
    public void run()
    {
        Log.i("KKK", "MyRunnable  run() is executed!!! ");
        runBefore();
        if (cancleTask == false)
        {
            running();
            Log.i("KKK", "调用MyRunnable run()方法");
        }
 
        runAfter();
    }
 
    /**
     * 
     */
    private void runAfter()
    {
        Log.i("KKK", "runAfter()");
    }
 
    /**
     * 
     */
    private void running()
    {
        Log.i("KKK", "running()");
        try
        {
            // 做点有可能会出异常的事情!!!
            int prog = 0;
            if (cancleTask == false && cancleException == false)
            {
                while (prog < 101)
                {
                    if ((prog > 0 || prog == 0) && prog < 70)
                    {
                        SystemClock.sleep(100);
                    }
                    else
                    {
                        SystemClock.sleep(300);
                    }
                    if (cancleTask == false)
                    {
                        mHandler.sendEmptyMessage(prog++);
                        Log.i("KKK", "调用 prog++ = " + (prog));
                    }
                }
            }
        }
        catch (Exception e)
        {
            cancleException = true;
        }
    }
 
    /**
     * 
     */
    private void runBefore()
    {
        // TODO Auto-generated method stub
        Log.i("KKK", "runBefore()");
    }
 
    public void setCancleTaskUnit(boolean cancleTask)
    {
        this.cancleTask = cancleTask;
        Log.i("KKK", "点击了取消任务按钮 !!!");
        // mHandler.sendEmptyMessage(0);
    }
 
}


2.3:布局文件


 
    
 
        


方式一、方式二的全局配置文件AndroidManifest.xml文件的配置如下:


 
    
 
    
        


 


        
        
            
                
 
                
            
        
    
 


  • Android线程池使用_第9张图片
  • 大小: 259.6 KB
  • Android线程池使用_第10张图片
  • 大小: 61.3 KB
  • Android线程池使用_第11张图片
  • 大小: 61.3 KB
  • Android线程池使用_第12张图片
  • 大小: 48.3 KB
  • Android线程池使用_第13张图片
  • 大小: 34.6 KB
  • Android线程池使用_第14张图片
  • 大小: 83.8 KB
  • Android线程池使用_第15张图片
  • 大小: 64.2 KB
  • Android线程池使用_第16张图片
  • 大小: 117 KB
  • 查看图片附件

你可能感兴趣的:(Android线程池使用)