天天看點

Android應用程式線程消息循環模型分析(4)

接下來我們再看看應用程式的配置檔案AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>   

<manifest xmlns:android="http://schemas.android.com/apk/res/android"   

      package="shy.luo.counter"   

      android:versionCode="1"   

      android:versionName="1.0">   

    <application android:icon="@drawable/icon" android:label="@string/app_name">   

        <activity android:name=".Counter"   

                  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>   

這個配置檔案很簡單,我們就不介紹了。

再來看應用程式的界面檔案,它定義在res/layout/main.xml檔案中:

<?xml version="1.0" encoding="utf-8"?>     

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     

    android:orientation="vertical"     

    android:layout_width="fill_parent"     

    android:layout_height="fill_parent"      

    android:gravity="center">     

    <LinearLayout     

        android:layout_width="fill_parent"     

        android:layout_height="wrap_content"     

        android:layout_marginBottom="10px"     

        android:orientation="horizontal"      

        android:gravity="center">     

        <TextView       

        android:layout_width="wrap_content"      

            android:layout_height="wrap_content"      

            android:layout_marginRight="4px"     

            android:gravity="center"     

            android:text="@string/counter">     

        </TextView>     

            android:id="@+id/textview_counter"     

            android:text="0">     

    </LinearLayout>     

        <Button      

            android:id="@+id/button_start"     

            android:layout_width="wrap_content"     

            android:layout_height="wrap_content"     

            android:text="@string/start">     

        </Button>     

            android:id="@+id/button_stop"     

            android:text="@string/stop" >     

     </LinearLayout>       

</LinearLayout>    

這個界面配置檔案也很簡單,等一下我們在模拟器把這個應用程式啟動起來後,就可以看到它的截圖了。應用程式用到的字元串資源檔案位于res/values/strings.xml檔案中:

<resources>     

    <string name="app_name">Counter</string>     

    <string name="counter">Counter: </string>     

    <string name="start">Start Counter</string>     

    <string name="stop">Stop Counter</string>     

</resources>    

最後,我們還要在工程目錄下放置一個編譯腳本檔案Android.mk:

LOCAL_PATH:= $(call my-dir)           

include $(CLEAR_VARS)           

LOCAL_MODULE_TAGS := optional           

LOCAL_SRC_FILES := $(call all-subdir-java-files)           

LOCAL_PACKAGE_NAME := Counter           

include $(BUILD_PACKAGE)     

執行以下指令進行編譯和打包:

USER-NAME@MACHINE-NAME:~/Android$ mmm packages/experimental/Counter             

USER-NAME@MACHINE-NAME:~/Android$ make snod   

這樣,打包好的Android系統鏡像檔案system.img就包含我們前面建立的Counter應用程式了。

       執行以下指令啟動模拟器:

USER-NAME@MACHINE-NAME:~/Android$ emulator    

 這樣,使用AsyncTask的例子就介紹完了,下面,我們就要根據上面對AsyncTask的使用情況來重點分析它的實作了。

AsyncTask類定義在frameworks/base/core/java/android/os/AsyncTask.java檔案中:

public abstract class AsyncTask<Params, Progress, Result> {   

    ......   

    private static final BlockingQueue<Runnable> sWorkQueue =   

            new LinkedBlockingQueue<Runnable>(10);   

    private static final ThreadFactory sThreadFactory = new ThreadFactory() {   

        private final AtomicInteger mCount = new AtomicInteger(1);   

        public Thread newThread(Runnable r) {   

            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());   

        }   

    };   

    private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,   

        MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);   

    private static final int MESSAGE_POST_RESULT = 0x1;   

    private static final int MESSAGE_POST_PROGRESS = 0x2;   

    private static final int MESSAGE_POST_CANCEL = 0x3;   

    private static final InternalHandler sHandler = new InternalHandler();   

    private final WorkerRunnable<Params, Result> mWorker;   

    private final FutureTask<Result> mFuture;   

    public AsyncTask() {   

        mWorker = new WorkerRunnable<Params, Result>() {   

            public Result call() throws Exception {   

                ......   

                return doInBackground(mParams);   

            }   

        };   

        mFuture = new FutureTask<Result>(mWorker) {   

            @Override   

            protected void done() {   

                Message message;   

                Result result = null;   

                try {   

                    result = get();   

                } catch (InterruptedException e) {   

                    android.util.Log.w(LOG_TAG, e);   

                } catch (ExecutionException e) {   

                    throw new RuntimeException("An error occured while executing doInBackground()",   

                        e.getCause());   

                } catch (CancellationException e) {   

                    message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,   

                        new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));   

                    message.sendToTarget();   

                    return;   

                } catch (Throwable t) {   

                    throw new RuntimeException("An error occured while executing "   

                        + "doInBackground()", t);   

                }   

                message = sHandler.obtainMessage(MESSAGE_POST_RESULT,   

                    new AsyncTaskResult<Result>(AsyncTask.this, result));   

                message.sendToTarget();   

    }   

    public final Result get() throws InterruptedException, ExecutionException {   

        return mFuture.get();   

    public final AsyncTask<Params, Progress, Result> execute(Params... params) {   

        ......   

        mWorker.mParams = params;   

        sExecutor.execute(mFuture);   

        return this;   

    protected final void publishProgress(Progress... values) {   

        sHandler.obtainMessage(MESSAGE_POST_PROGRESS,   

            new AsyncTaskResult<Progress>(this, values)).sendToTarget();   

        private void finish(Result result) {   

                onPostExecute(result);   

    private static class InternalHandler extends Handler {   

        @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);   

                case MESSAGE_POST_CANCEL:   

                 result.mTask.onCancelled();   

    private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {   

        Params[] mParams;   

    private static class AsyncTaskResult<Data> {   

        final AsyncTask mTask;   

        final Data[] mData;   

        AsyncTaskResult(AsyncTask task, Data... data) {   

            mTask = task;   

            mData = data;   

}   

本文轉自 Luoshengyang 51CTO部落格,原文連結:http://blog.51cto.com/shyluo/966885,如需轉載請自行聯系原作者

繼續閱讀