Android应用程序线程消息循环模型分析(4)
2011-10-31 01:01
309 查看
接下来我们再看看应用程序的配置文件AndroidManifest.xml:
这个配置文件很简单,我们就不介绍了。
再来看应用程序的界面文件,它定义在res/layout/main.xml文件中:
这个界面配置文件也很简单,等一下我们在模拟器把这个应用程序启动起来后,就可以看到它的截图了。应用程序用到的字符串资源文件位于res/values/strings.xml文件中:
最后,我们还要在工程目录下放置一个编译脚本文件Android.mk:
接下来就要编译了。有关如何单独编译Android源代码工程的模块,以及如何打包system.img,请参考如何单独编译Android源代码中的模块一文。
执行以下命令进行编译和打包:
这样,打包好的Android系统镜像文件system.img就包含我们前面创建的Counter应用程序了。
再接下来,就是运行模拟器来运行我们的例子了。关于如何在Android源代码工程中运行模拟器,请参考在Ubuntu上下载、编译和安装Android最新源代码一文。
执行以下命令启动模拟器:
最后我们就可以在Launcher中找到Counter应用程序图标,把它启动起来,点击Start按钮,就会看到应用程序界面上的计数器跑起来了:
这样,使用AsyncTask的例子就介绍完了,下面,我们就要根据上面对AsyncTask的使用情况来重点分析它的实现了。
AsyncTask类定义在frameworks/base/core/java/android/os/AsyncTask.java文件中:
<?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> <TextView android:id="@+id/textview_counter" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="0"> </TextView> </LinearLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center"> <Button android:id="@+id/button_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="@string/start"> </Button> <Button android:id="@+id/button_stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="@string/stop" > </Button> </LinearLayout> </LinearLayout>
这个界面配置文件也很简单,等一下我们在模拟器把这个应用程序启动起来后,就可以看到它的截图了。应用程序用到的字符串资源文件位于res/values/strings.xml文件中:
<?xml version="1.0" encoding="utf-8"?> <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)
接下来就要编译了。有关如何单独编译Android源代码工程的模块,以及如何打包system.img,请参考如何单独编译Android源代码中的模块一文。
执行以下命令进行编译和打包:
USER-NAME@MACHINE-NAME:~/Android$ mmm packages/experimental/Counter USER-NAME@MACHINE-NAME:~/Android$ make snod
这样,打包好的Android系统镜像文件system.img就包含我们前面创建的Counter应用程序了。
再接下来,就是运行模拟器来运行我们的例子了。关于如何在Android源代码工程中运行模拟器,请参考在Ubuntu上下载、编译和安装Android最新源代码一文。
执行以下命令启动模拟器:
USER-NAME@MACHINE-NAME:~/Android$ emulator
最后我们就可以在Launcher中找到Counter应用程序图标,把它启动起来,点击Start按钮,就会看到应用程序界面上的计数器跑起来了:
这样,使用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); break; case MESSAGE_POST_CANCEL: result.mTask.onCancelled(); break; } } } 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; } } }
相关文章推荐
- Android应用程序线程消息循环模型分析(2)
- Android应用程序线程消息循环模型分析(3)
- Android应用程序线程消息循环模型分析(5)
- Android应用程序线程消息循环模型分析(6)
- Android应用程序线程消息循环模型分析(1)
- Android应用程序线程消息循环模型分析
- Android应用程序线程消息循环模型分析
- Android应用程序线程消息循环模型分析
- Android应用程序线程消息循环模型分析
- Android应用程序线程消息循环模型分析
- Android应用程序线程消息循环模型分析
- Android应用程序线程消息循环模型分析
- Android应用程序线程消息循环模型分析
- Android应用程序线程消息循环模型分析
- Android应用程序线程的消息循环模型
- Android系统源码阅读(16):Android 应用线程的消息循环模型
- Android应用程序模型之应用程序,任务,进程,线程分析
- 《android系统源代码情景分析》学习-第15章 Android应用线程的消息循环模型
- Android应用程序消息循环源码分析
- Android应用程序消息循环源码分析