Android线程池使用

来源:互联网 发布:服务器上的java 编辑:程序博客网 时间:2024/05/28 06:04

一:无大小限制的线程池执行效果如下


1.gif


二:限制按顺序来执行任务的线程池效果如下


2.gif


三:一个一个任务的执行线程池效果如下(与按顺序执行效果是一样的,只是内部实现稍有不同)


3.gif


四:按指定个数来执行任务的线程池效果如下


4.gif


五:创建一个可在指定时间里执行任务的线程池,亦可重复执行,不常用,效果与四相同


5.gif


六:按指定工厂模式来执行的线程池,效果与四、五一样,但用方式六创建的线程池都有在工厂中指定的线程属性,
比如:线程名字、是否为用户线程等等属性


6.gif


七:线程池中任务执行时可暂停效果图如下


7.gif


八:用Runnable、ConcurrentLinkedQueue、ConcurrentMap、Future、ExecutorService关联实现的效果图如下


8.gif


哦的了,效果看完了,现在就请大家自行修改AndroidManifest.xml中主Activity的入口来看两种不同方式实现的代码效果吧,首先,先贴一下Main.java类的代码,希望大家详细看里面的注释,一定要详细看,你不会吃亏的,相信我!

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

1.1:主类文件(Main.java)

/*  * 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      {          @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<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);          }          @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<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);              }          }          @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:布局文件

<?xml version="1.0" encoding="utf-8"?>  <LinearLayout xmlns: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" >      <ListView android: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)

/*  * 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      */      @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<MyRunnable>();          taskMap = new ConcurrentHashMap<Future, MyRunnable>();          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;          }      }      /**      * <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()          {              @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();      }      /**      * <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()          {              @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);                      }                  }              }          });      }      /**      * <Summary Description>      */      private void stop()      {          Toast.makeText(MyRunnableActivity.this, "任务已被取消!", 0).show();          for (MyRunnable runnable : taskMap.values())          {              runnable.setCancleTaskUnit(true);          }      }      /**      * <Summary Description>      */      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  <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      */      @Override      public 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>      */      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:布局文件

<?xml version="1.0" encoding="utf-8"?>  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"      android:layout_width="match_parent"      android:layout_height="match_parent"      android:orientation="vertical" >      <LinearLayout          android:layout_width="match_parent"          android:layout_height="wrap_content"          android:orientation="horizontal" >          <Button              android:id="@+id/button5"              android:layout_width="0dp"              android:layout_height="wrap_content"              android:layout_weight="1"              android:text="添加任务" />          <Button              android:id="@+id/button1"              android:layout_width="0dp"              android:layout_height="wrap_content"              android:layout_weight="1"              android:text="开始任务" />          <Button              android:id="@+id/button2"              android:layout_width="0dp"              android:layout_height="wrap_content"              android:layout_weight="1"              android:text="取消任务" />          <Button              android:id="@+id/button3"              android:layout_width="0dp"              android:layout_height="wrap_content"              android:layout_weight="1"              android:text="重新加载" />          <Button              android:id="@+id/button4"              android:layout_width="0dp"              android:layout_height="wrap_content"              android:layout_weight="1"              android:text="释放资源" />      </LinearLayout>      <include layout="@layout/my_runnable_merge"/>  </LinearLayout>

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

<?xml version="1.0" encoding="utf-8"?>  <manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.xiaoma.threadpooltest"      android:versionCode="1"      android:versionName="1.0" >      <uses-sdk          android:minSdkVersion="8"          android:targetSdkVersion="15" />      <application          android:allowBackup="true"          android:icon="@drawable/ic_launcher"          android:label="@string/app_name"          android:theme="@style/AppTheme" >          <activity              android: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>          <activity              android:name="MyRunnableActivity"              android:label="@string/app_name" >              <intent-filter>                  <action android:name="android.intent.action.MAIN" />                  <category android:name="android.intent.category.LAUNCHER" />              </intent-filter>          </activity>      </application>  </manifest>

原创粉丝点击