Android应用程序线程消息循环模型分析(4)
16lz
2022-04-24
接下来我们再看看应用程序的配置文件AndroidManifest.xml:
再接下来,就是运行模拟器来运行我们的例子了。关于如何在Android源代码工程中运行模拟器,请参考 在Ubuntu上下载、编译和安装Android最新源代码 一文。 执行以下命令启动模拟器:
AsyncTask类定义在frameworks/base/core/java/android/os/AsyncTask.java文件中:
这个配置文件很简单,我们就不介绍了。 再来看应用程序的界面文件,它定义在res/layout/main.xml文件中:
- <?xmlversion="1.0"encoding="utf-8"?>
- <manifestxmlns:android="http://schemas.android.com/apk/res/android"
- package="shy.luo.counter"
- android:versionCode="1"
- android:versionName="1.0">
- <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
- <activityandroid:name=".Counter"
- android:label="@string/app_name">
- <intent-filter>
- <actionandroid:name="android.intent.action.MAIN"/>
- <categoryandroid:name="android.intent.category.LAUNCHER"/>
- </intent-filter>
- </activity>
- </application>
- </manifest>
这个界面配置文件也很简单,等一下我们在模拟器把这个应用程序启动起来后,就可以看到它的截图了。 应用程序用到的字符串资源文件位于res/values/strings.xml文件中:
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns: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>
最后,我们还要在工程目录下放置一个编译脚本文件Android.mk:
- <?xmlversion="1.0"encoding="utf-8"?>
- <resources>
- <stringname="app_name">Counter</string>
- <stringname="counter">Counter:</string>
- <stringname="start">StartCounter</string>
- <stringname="stop">StopCounter</string>
- </resources>
接下来就要编译了。有关如何单独编译Android源代码工程的模块,以及如何打包system.img,请参考 如何单独编译Android源代码中的模块 一文。 执行以下命令进行编译和打包:
- LOCAL_PATH:=$(callmy-dir)
- include$(CLEAR_VARS)
- LOCAL_MODULE_TAGS:=optional
- LOCAL_SRC_FILES:=$(callall-subdir-java-files)
- LOCAL_PACKAGE_NAME:=Counter
- include$(BUILD_PACKAGE)
这样,打包好的Android系统镜像文件system.img就包含我们前面创建的Counter应用程序了。
- USER-NAME@MACHINE-NAME:~/Android$mmmpackages/experimental/Counter
- USER-NAME@MACHINE-NAME:~/Android$makesnod
再接下来,就是运行模拟器来运行我们的例子了。关于如何在Android源代码工程中运行模拟器,请参考 在Ubuntu上下载、编译和安装Android最新源代码 一文。 执行以下命令启动模拟器:
最后我们就可以在Launcher中找到Counter应用程序图标,把它启动起来,点击Start按钮,就会看到应用程序界面上的计数器跑起来了: 这样,使用AsyncTask的例子就介绍完了,下面,我们就要根据上面对AsyncTask的使用情况来重点分析它的实现了。
- USER-NAME@MACHINE-NAME:~/Android$emulator
AsyncTask类定义在frameworks/base/core/java/android/os/AsyncTask.java文件中:
- publicabstractclassAsyncTask<Params,Progress,Result>{
- ......
- privatestaticfinalBlockingQueue<Runnable>sWorkQueue=
- newLinkedBlockingQueue<Runnable>(10);
- privatestaticfinalThreadFactorysThreadFactory=newThreadFactory(){
- privatefinalAtomicIntegermCount=newAtomicInteger(1);
- publicThreadnewThread(Runnabler){
- returnnewThread(r,"AsyncTask#"+mCount.getAndIncrement());
- }
- };
- ......
- privatestaticfinalThreadPoolExecutorsExecutor=newThreadPoolExecutor(CORE_POOL_SIZE,
- MAXIMUM_POOL_SIZE,KEEP_ALIVE,TimeUnit.SECONDS,sWorkQueue,sThreadFactory);
- privatestaticfinalintMESSAGE_POST_RESULT=0x1;
- privatestaticfinalintMESSAGE_POST_PROGRESS=0x2;
- privatestaticfinalintMESSAGE_POST_CANCEL=0x3;
- privatestaticfinalInternalHandlersHandler=newInternalHandler();
- privatefinalWorkerRunnable<Params,Result>mWorker;
- privatefinalFutureTask<Result>mFuture;
- ......
- publicAsyncTask(){
- mWorker=newWorkerRunnable<Params,Result>(){
- publicResultcall()throwsException{
- ......
- returndoInBackground(mParams);
- }
- };
- mFuture=newFutureTask<Result>(mWorker){
- @Override
- protectedvoiddone(){
- Messagemessage;
- Resultresult=null;
- try{
- result=get();
- }catch(InterruptedExceptione){
- android.util.Log.w(LOG_TAG,e);
- }catch(ExecutionExceptione){
- thrownewRuntimeException("AnerroroccuredwhileexecutingdoInBackground()",
- e.getCause());
- }catch(CancellationExceptione){
- message=sHandler.obtainMessage(MESSAGE_POST_CANCEL,
- newAsyncTaskResult<Result>(AsyncTask.this,(Result[])null));
- message.sendToTarget();
- return;
- }catch(Throwablet){
- thrownewRuntimeException("Anerroroccuredwhileexecuting"
- +"doInBackground()",t);
- }
- message=sHandler.obtainMessage(MESSAGE_POST_RESULT,
- newAsyncTaskResult<Result>(AsyncTask.this,result));
- message.sendToTarget();
- }
- };
- }
- ......
- publicfinalResultget()throwsInterruptedException,ExecutionException{
- returnmFuture.get();
- }
- ......
- publicfinalAsyncTask<Params,Progress,Result>execute(Params...params){
- ......
- mWorker.mParams=params;
- sExecutor.execute(mFuture);
- returnthis;
- }
- ......
- protectedfinalvoidpublishProgress(Progress...values){
- sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
- newAsyncTaskResult<Progress>(this,values)).sendToTarget();
- }
- privatevoidfinish(Resultresult){
- ......
- onPostExecute(result);
- ......
- }
- ......
- privatestaticclassInternalHandlerextendsHandler{
- @SuppressWarnings({"unchecked","RawUseOfParameterizedType"})
- @Override
- publicvoidhandleMessage(Messagemsg){
- AsyncTaskResultresult=(AsyncTaskResult)msg.obj;
- switch(msg.what){
- caseMESSAGE_POST_RESULT:
- //Thereisonlyoneresult
- result.mTask.finish(result.mData[0]);
- break;
- caseMESSAGE_POST_PROGRESS:
- result.mTask.onProgressUpdate(result.mData);
- break;
- caseMESSAGE_POST_CANCEL:
- result.mTask.onCancelled();
- break;
- }
- }
- }
- privatestaticabstractclassWorkerRunnable<Params,Result>implementsCallable<Result>{
- Params[]mParams;
- }
- privatestaticclassAsyncTaskResult<Data>{
- finalAsyncTaskmTask;
- finalData[]mData;
- AsyncTaskResult(AsyncTasktask,Data...data){
- mTask=task;
- mData=data;
- }
- }
- }
更多相关文章
- Android打电话,挂电话
- android 用Pull 读取XML
- Android播放ogg声音文件
- Android创建文件夹及文件并写入数据
- 《android用SAX解析xml》
- Android(安卓)7.1 固件预装客户应用时出现: java.lang.Unsatisfie
- R.stamp Error 1
- Android(安卓)应用程序主动请求Vsync
- NPM 和webpack 的基础使用