Android研究院之應用開發線程池的經典使用

Android線程池使用終結版

有一段時間沒寫博文了,今天抽空總結一下,也希望能通過自己寫的這些文章,加深理解的同時能幫

助在技術方面有疑點的朋友搞清楚個所以然來,由於經常會在網上或羣裏看到有朋友會問線程方面的

東西,就像我一個朋友他們老師講的,J2SE、J2EE裏面使用的線程方面的東西可能不是太多,但是

在Android開發裏面,玩的就是線程(UIThread)!好了,廢話就說這麼多吧,直入正題!今天要講的

東西就是線程池、線程的高效率使用,靈活控制!今天死馬我就用最常用的幾種方式來分別實現應用

中使用的線程方面的知識,(共寫了兩個不同入口的Activity來分開不同的實現方式,大家可以自行注

釋AndroidManifest.xml中的Launch入口或打開註釋)任何發代碼中的具體實現效果,好了,先隨便列

幾個吧,如:AsyncTask、Runnable、Thread、ThreadPool、Executors等等的使用,看我文章的朋

友應該都很清楚小馬的方式啦,果斷先上效果,再一步步分解代碼,來吧,效果圖如下:

一:無大小限制的線程池執行效果如下

二:限制按順序來執行任務的線程池效果如下

222725754.gif

三:一個一個任務的執行線程池效果如下(與按順序執行效果是一樣的,只是內部實現稍有不同)

222657697.gif

四:按指定個數來執行任務的線程池效果如下

222840612.gif

五:創建一個可在指定時間裏執行任務的線程池,亦可重複執行,不常用,效果與四相同

222856182.gif

六:按指定工廠模式來執行的線程池,效果與四、五一樣,但用方式六創建的線程池都有在工廠

中指定的線程屬性,比如:線程名字、是否爲用戶線程等等屬性

222913795.gif

七:線程池中任務執行時可暫停效果圖如下

222933493.gif

八:用Runnable、ConcurrentLinkedQueue、ConcurrentMap、Future、ExecutorService關聯實現的效果圖如下

222950866.gif

哦的了,效果看完了,現在就請大家自行修改AndroidManifest.xml中主Activity的入口來看兩種不同方式實現的代碼效果吧,首先,先貼一下Main.java類的代碼,希望大家詳細看裏面的註釋,一定要詳細看,你不會吃虧的,相信我!(備註:爲了寫文章加註釋還有查找的時候方便,小馬把所有的主類及輔助類以內部類的形式寫到一個.java文件裏面了,如果朋友們覺得看着亂,不爽的話,可以自行將裏面的類抽取到單獨的.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 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;
}
@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>

好了,今天要寫內容,大體就是這些了,項目的源碼大家可以到附件中下載,如果能仔細的將上面的東西都看完並消化的話,線程池方面的東西可能以後並不會太過爲難你啦!呵呵,當然了,小馬這些代碼中寫的都是一些比較簡單的寫法,僅僅是使用了在線程中休眠的方式來模擬網絡下載(還是個假象),如果在實際代碼中使用時,尤其在釋放資源這一塊,不要只是單單釋放了我們自己控制的線程池及其任務,還要將網絡請求的Http也一同銷燬掉哦,這樣纔算做到了完美!急急忙忙寫的,如果文章中有什麼地方寫的不對的,真的很希望Android老鳥、菜鳥都來指點、提問,代碼中若不對的,或不太合理的地方,有朋友發覺了還請及時批評指正!小馬先在此謝謝大家啦!加油,每天進步一點,堅持總會有收穫的!廢話不多說了,大家晚安!…O_O…

一個很幸福的壞人!小馬果、酷_莫名簡單

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章