編輯:關於Android編程
線程在android是個重要的概念,從用途上講,線程分為主線程和子線程,主線程負責頁面相關,子線程負責耗時操作。在android中除了Thread本身還有 AsyncTask IntentService HandlerThread。
AsyncTask
public abstract class AsyncTask
1 Params 參數類型
2 Progress 執行進度類型
3 Result 返回數據類型
不需要參數可以用Void代替
//異步任務執行之前調用,一般用來執行一些准備操作
@Override
protected void onPreExecute() {
super.onPreExecute();
}
//在線程池調用, 用於執行異步任務
@Override
protected String doInBackground(String... params) {
return null;
}
//異步任務執行之後會調用
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
//主線程中執行,後台任務執行進度發生改變調用
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
注意: 1 AsyncTask類必須在主線程中加載 2 AsyncTask的對象必須在主線程創建 3 execute必須在UI線程調用 4 一個AsyncTask的對象只能執行一次,即只調用一次execute方法
public final AsyncTask execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
execute 方法會調用 executeOnExecutor 方法;看一下 executeOnExecutor 方法:
public final AsyncTask executeOnExecutor(Executor exec,
Params... params) {
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
throw new IllegalStateException("Cannot execute task:"
+ " the task is already running.");
case FINISHED:
throw new IllegalStateException("Cannot execute task:"
+ " the task has already been executed "
+ "(a task can be executed only once)");
}
}
mStatus = Status.RUNNING;
onPreExecute();
mWorker.mParams = params;
exec.execute(mFuture);
return this;
}
可以看出封裝了一個線程池,接著找我發現了
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static class SerialExecutor implements Executor {
final ArrayDeque mTasks = new ArrayDeque();
Runnable mActive;
public synchronized void execute(final Runnable r) {
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (mActive == null) {
scheduleNext();
}
}
從SerialExecutor 看出AsyncTask是排隊執行的過程。
系統首先會把AsyncTask的參數Params 封裝為FutureTask對象,接著會把FutureTask交給SerialExecutor的execute處理,
execute方法把FutureTask交給mTasks任務隊列中,如果這時沒有AsyncTask任務,SerialExecutor會 scheduleNext()來執行下一個任務。當一個任務執行完以後,SerialExecutor才會執行其他任務,可以看出AsyncTask是串 行的。
AsyncTask構造函數有這樣一段代碼:
mWorker = new WorkerRunnable() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
return postResult(doInBackground(mParams));
}
};
再看FutureTask的run方法:
派生到我的代碼片
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
發現FutureTask的run方法是執行了mWorker的call的,所以call也會在線程池中執行。
mWorker的call中將mTaskInvoked.set(true);表示當前任務已經調用然後執行AsyncTask的doInBackground方法接著將
返回值傳給postResult方法;
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult(this, result));
message.sendToTarget();
return result;
}
可以看出postResult通過一個Handler發送一個MESSAGE_POST_RESULT消息
private static Handler getHandler() {
synchronized (AsyncTask.class) {
if (sHandler == null) {
sHandler = new InternalHandler();
}
return sHandler;
}
}
private static class InternalHandler extends Handler {
public InternalHandler() {
super(Looper.getMainLooper());
}
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult result = (AsyncTaskResult) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
當這個Handler收到MESSAGE_POST_RESULT消息之後,會調用finish方法了
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
如果取消執行就 onCancelled 了,否則就調用onPostExecute這個方法。
Android實現帶列表的地圖POI周邊搜索功能
先看效果圖:(以公司附近的國貿為中心點)上面是地圖,下面是地理位置列表,有的只有地理位置列表(QQ動態的位置),這是個很常見的功能。它有個專門的叫法:POI周邊搜索。實現
深入剖析Android消息機制原理
在Android中,線程內部或者線程之間進行信息交互時經常會使用消息,這些基礎的東西如果我們熟悉其內部的原理,將會使我們容易、更好地架構系統,避免一些低級的錯誤。在學習A
Android圖形庫Skia(一)-基本測試生成PNG圖片
基於淺談 Google Skia 圖形處理引擎和Skia Demo Build。 Skia是一個跨平台的圖形庫,目前使用在Android中,同樣也有PC版本,這裡測試一下
Android Content Provider在應用程序之間共享數據的原理分析
本文參考Android應用程序組件Content Provider在應用程序之間共享數據的原理分析http://blog.csdn.net/luoshengyang/ar