1.1:主类文件(Main.java)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | /** FileName:  Main.java* CopyRight:  Belong to  <XiaoMaGuo Technologies > own* Description:  <description>* Modify By :  XiaoMaGuo ^_^* Modify Date:   2013-10-15* Follow Order No.:  <Follow Order No.>* Modify Order No.:  <Modify Order No.>* Modify Content:  <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<AsyncTaskTest> mTaskList = null;/** 任务是否被取消 */private boolean isCancled = false;/** 是否点击并取消任务标示符 */private boolean isClick = false;/** 线程工厂初始化方式一 */ThreadFactory tf = Executors.defaultThreadFactory();/** 线程工厂初始化方式二 */private static class ThreadFactoryTest implements ThreadFactory{@Overridepublic Thread newThread(Runnable r){Thread thread = new Thread(r);thread.setName("XiaoMaGuo_ThreadFactory");thread.setDaemon(true); // 将用户线程变成守护线程,默认falsereturn 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(){@Overridepublic void run(){Log.i("KKK", "This is the ThreadFactory Test  submit Run! ! ! ");}});};@Overridepublic 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(){@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id){if (position == 0) // 以第一项为例,来测试关闭线程池{/*** 会关闭线程池方式一:但不接收新的Task,关闭后,正在等待 执行的任务不受任何影响,会正常执行,无返回值!*/// allTaskExecutor.shutdown();/*** 会关闭线程池方式二:也不接收新的Task,并停止正等待执行的Task(也就是说, 执行到一半的任务将正常执行下去),最终还会给你返回一个正在等待执行但线程池关闭却没有被执行的Task集合!*/List<Runnable> 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<AsyncTaskTest>(taskCount);}@Overridepublic int getCount(){return mTaskCount;}@Overridepublic Object getItem(int position){return mTaskList.get(position);}@Overridepublic long getItemId(int position){return position;}@Overridepublic 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<Void, Integer, Void>{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);}}@Overrideprotected void onPreExecute(){mTaskItem.setTitle(id);}/*** Overriding methods*/@Overrideprotected void onCancelled(){super.onCancelled();}@Overrideprotected Void doInVoid...  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;}@Overrideprotected void onPostExecute(Void result){}@Overrideprotected void onProgressUpdate(Integer... values){mTaskItem.setProgress(values[0]); // 设置进度}}}/*** @TODO [一个简单的自定义 ListView Item]* @author XiaoMaGuo ^_^* @version [version-code, 2013-10-22]* @since [Product/module]*/classMyListItem extendsLinearLayout{privateTextView mTitle;privateProgressBar mProgress;publicMyListItem(Context context, AttributeSet attrs){super(context, attrs);}publicMyListItem(Context context){super(context);}publicvoidsetTitle(String title){if(mTitle == null){mTitle = (TextView)findViewById(R.id.task_name);}mTitle.setText(title);}publicvoidsetProgress(intprog){if(mProgress == null){mProgress = (ProgressBar)findViewById(R.id.task_progress);}mProgress.setProgress(prog);}} | 
1.2:布局文件
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingLeft="10dip"android:paddingRight="10dip"android:orientation="vertical"><ListViewandroid:id="@+id/task_list"android:layout_width="fill_parent"android:layout_height="wrap_content"android:divider="#cccccc"android:dividerHeight="0.6dip"android:footerDividersEnabled="true"android:headerDividersEnabled="true"/></LinearLayout> | 
方式二(Runnable、ConcurrentLinkedQueue、ConcurrentMap、Future、ExecutorService关联实现的相关文件如下):
2.1:主类文件(MyRunnableActivity.java)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | /** FileName:  MyRunnableActivity.java* CopyRight:  Belong to  <XiaoMaGuo Technologies > own* Description:  <description>* Modify By :  XiaoMaGuo ^_^* Modify Date:   2013-10-21* Follow Order No.:  <Follow Order No.>* Modify Order No.:  <Modify Order No.>* Modify Content:  <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<MyRunnable> taskQueue = null;/*** 正在等待执行或已经完成的任务队列** 备注:Future类,一个用于存储异步任务执行的结果,比如:判断是否取消、是否可以取消、是否正在执行、是否已经完成等** */private ConcurrentMap<Future, MyRunnable> 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*/@Overrideprotected void onCreate(Bundle savedInstanceState){// TODO Auto-generated method stubsuper.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<MyRunnable>();taskMap = new ConcurrentHashMap<Future, MyRunnable>();if (mES == null){mES = Executors.newCachedThreadPool();}// 用于更新ProgressBar进度条mHandler = new Handler(){/*** Overriding methods** @param msg*/@Overridepublic void handleMessage(Message msg){super.handleMessage(msg);pb.setProgress(msg.what);}};}/*** Overriding methods** @param v*/@Overridepublic 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;}}/*** <Summary Description>*/private void addTask(final MyRunnable mr){mHandler.sendEmptyMessage(0);if (mES == null){mES = Executors.newCachedThreadPool();notifyWork();}if (taskQueue == null){taskQueue = new ConcurrentLinkedQueue<MyRunnable>();}if (taskMap == null){taskMap = new ConcurrentHashMap<Future, MyRunnable>();}mES.execute(new Runnable(){@Overridepublic 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();}/*** <Summary Description>*/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<Future, MyRunnable> entry = (Map.Entry<Future, MyRunnable>)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;}/*** <Summary Description>*/private void reload(final MyRunnable mr){mHandler.sendEmptyMessage(0);if (mES == null){mES = Executors.newCachedThreadPool();notifyWork();}if (taskQueue == null){taskQueue = new ConcurrentLinkedQueue<MyRunnable>();}if (taskMap == null){taskMap = new ConcurrentHashMap<Future, MyRunnable>();}mES.execute(new Runnable(){@Overridepublic void run(){/** 插入一个Runnable到任务队列中 */taskQueue.offer(mr);// taskQueue.add(mr);notifyWork();}});mES.execute(new Runnable(){@Overridepublic void run(){if (isRuning){MyRunnable myRunnable = null;synchronized (lock){myRunnable = taskQueue.poll(); // 从线程队列中取出一个Runnable对象来执行,如果此队列为空,则调用poll()方法会返回nullif (myRunnable == null){isNotify = true;}}if (myRunnable != null){taskMap.put(mES.submit(myRunnable), myRunnable);}}}});}/*** <Summary Description>*/private void stop(){Toast.makeText(MyRunnableActivity.this, "任务已被取消!", 0).show();for (MyRunnable runnable : taskMap.values()){runnable.setCancleTaskUnit(true);}}/*** <Summary Description>*/privatevoidstart(){if(mES == null|| taskQueue == null|| taskMap == null){Log.i("KKK", "某资源是不是已经被释放了?");return;}mES.execute(newRunnable(){@Overridepublicvoidrun(){if(isRuning){MyRunnable myRunnable = null;synchronized(lock){myRunnable = taskQueue.poll(); // 从线程队列中取出一个Runnable对象来执行,如果此队列为空,则调用poll()方法会返回nullif(myRunnable == null){isNotify = true;// try// {// myRunnable.wait(500);// }// catch (InterruptedException e)// {// e.printStackTrace();// }}}if(myRunnable != null){taskMap.put(mES.submit(myRunnable), myRunnable);}}}});}privatevoidnotifyWork(){synchronized(lock){if(isNotify){lock.notifyAll();isNotify = !isNotify;}}}} | 
2.2:辅助类(MyRunnable.java)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | /** FileName:  MyRunnable.java* CopyRight:  Belong to  <XiaoMaGuo Technologies > own* Description:  <description>* Modify By :  XiaoMaGuo ^_^* Modify Date:   2013-10-21* Follow Order No.:  <Follow Order No.>* Modify Order No.:  <Modify Order No.>* Modify Content:  <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*/@Overridepublic void run(){Log.i("KKK", "MyRunnable  run() is executed!!! ");runBefore();if (cancleTask == false){running();Log.i("KKK", "调用MyRunnable run()方法");}runAfter();}/*** <Summary Description>*/private void runAfter(){Log.i("KKK", "runAfter()");}/*** <Summary Description>*/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;}}/*** <Summary Description>*/privatevoidrunBefore(){// TODO Auto-generated method stubLog.i("KKK", "runBefore()");}publicvoidsetCancleTaskUnit(booleancancleTask){this.cancleTask = cancleTask;Log.i("KKK", "点击了取消任务按钮 !!!");// mHandler.sendEmptyMessage(0);}} | 
2.3:布局文件
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Buttonandroid:id="@+id/button5"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="添加任务"/><Buttonandroid:id="@+id/button1"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="开始任务"/><Buttonandroid:id="@+id/button2"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="取消任务"/><Buttonandroid:id="@+id/button3"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="重新加载"/><Buttonandroid:id="@+id/button4"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="释放资源"/></LinearLayout><includelayout="@layout/my_runnable_merge"/></LinearLayout> | 
方式一、方式二的全局配置文件AndroidManifest.xml文件的配置如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <?xmlversion="1.0"encoding="utf-8"?><manifestxmlns:android="http://schemas.android.com/apk/res/android"package="com.xiaoma.threadpooltest"android:versionCode="1"android:versionName="1.0"><uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="15"/><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme"><activityandroid:name="Main"android:label="@string/app_name"><!--             <intent-filter> --><!--                 <action android:name="android.intent.action.MAIN" /> --><!--                 <category android:name="android.intent.category.LAUNCHER" /> --><!--             </intent-filter> --></activity><activityandroid:name="MyRunnableActivity"android:label="@string/app_name"><intent-filter><actionandroid:name="android.intent.action.MAIN"/><categoryandroid:name="android.intent.category.LAUNCHER"/></intent-filter></activity></application></manifest> | 
原文:http://www.cnblogs.com/qianyukun/p/6045854.html