Android应用程序线程消息循环模型分析(4)

接下来我们再看看应用程序的配置文件AndroidManifest.xml:
 
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"   
  3.       package="shy.luo.counter"   
  4.       android:versionCode="1"   
  5.       android:versionName="1.0">   
  6.     <application android:icon="@drawable/icon" android:label="@string/app_name">   
  7.         <activity android:name=".Counter"   
  8.                   android:label="@string/app_name">   
  9.             <intent-filter>   
  10.                 <action android:name="android.intent.action.MAIN" />   
  11.                 <category android:name="android.intent.category.LAUNCHER" />   
  12.             </intent-filter>   
  13.         </activity>   
  14.     </application>   
  15. </manifest>   
这个配置文件很简单,我们就不介绍了。
再来看应用程序的界面文件,它定义在res/layout/main.xml文件中:
 
  1. <?xml version="1.0" encoding="utf-8"?>     
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     
  3.     android:orientation="vertical"     
  4.     android:layout_width="fill_parent"     
  5.     android:layout_height="fill_parent"      
  6.     android:gravity="center">     
  7.     <LinearLayout     
  8.         android:layout_width="fill_parent"     
  9.         android:layout_height="wrap_content"     
  10.         android:layout_marginBottom="10px"     
  11.         android:orientation="horizontal"      
  12.         android:gravity="center">     
  13.         <TextView       
  14.         android:layout_width="wrap_content"      
  15.             android:layout_height="wrap_content"      
  16.             android:layout_marginRight="4px"     
  17.             android:gravity="center"     
  18.             android:text="@string/counter">     
  19.         </TextView>     
  20.         <TextView       
  21.             android:id="@+id/textview_counter"     
  22.         android:layout_width="wrap_content"      
  23.             android:layout_height="wrap_content"      
  24.             android:gravity="center"     
  25.             android:text="0">     
  26.         </TextView>     
  27.     </LinearLayout>     
  28.     <LinearLayout     
  29.         android:layout_width="fill_parent"     
  30.         android:layout_height="wrap_content"     
  31.         android:orientation="horizontal"      
  32.         android:gravity="center">     
  33.         <Button      
  34.             android:id="@+id/button_start"     
  35.             android:layout_width="wrap_content"     
  36.             android:layout_height="wrap_content"     
  37.             android:gravity="center"     
  38.             android:text="@string/start">     
  39.         </Button>     
  40.         <Button      
  41.             android:id="@+id/button_stop"     
  42.             android:layout_width="wrap_content"     
  43.             android:layout_height="wrap_content"     
  44.             android:gravity="center"     
  45.             android:text="@string/stop" >     
  46.         </Button>     
  47.      </LinearLayout>       
  48. </LinearLayout>    
这个界面配置文件也很简单,等一下我们在模拟器把这个应用程序启动起来后,就可以看到它的截图了。应用程序用到的字符串资源文件位于res/values/strings.xml文件中:
 
  1. <?xml version="1.0" encoding="utf-8"?>     
  2. <resources>     
  3.     <string name="app_name">Counter</string>     
  4.     <string name="counter">Counter: </string>     
  5.     <string name="start">Start Counter</string>     
  6.     <string name="stop">Stop Counter</string>     
  7. </resources>    
最后,我们还要在工程目录下放置一个编译脚本文件Android.mk:
 
  1. LOCAL_PATH:= $(call my-dir)           
  2. include $(CLEAR_VARS)           
  3.            
  4. LOCAL_MODULE_TAGS :optional           
  5.            
  6. LOCAL_SRC_FILES := $(call all-subdir-java-files)           
  7.            
  8. LOCAL_PACKAGE_NAME :Counter           
  9.            
  10. include $(BUILD_PACKAGE)     
接下来就要编译了。有关如何单独编译Android源代码工程的模块,以及如何打包system.img,请参考如何单独编译Android源代码中的模块一文。
执行以下命令进行编译和打包:
 
  1. USER-NAME@MACHINE-NAME:~/Android$ mmm packages/experimental/Counter             
  2. USER-NAME@MACHINE-NAME:~/Android$ make snod   
这样,打包好的Android系统镜像文件system.img就包含我们前面创建的Counter应用程序了。
       再接下来,就是运行模拟器来运行我们的例子了。关于如何在Android源代码工程中运行模拟器,请参考
在Ubuntu上下载、编译和安装Android最新源代码一文。
       执行以下命令启动模拟器:
 
  1. USER-NAME@MACHINE-NAME:~/Android$ emulator    
 最后我们就可以在Launcher中找到Counter应用程序图标,把它启动起来,点击Start按钮,就会看到应用程序界面上的计数器跑起来了:
 这样,使用AsyncTask的例子就介绍完了,下面,我们就要根据上面对AsyncTask的使用情况来重点分析它的实现了。
AsyncTask类定义在frameworks/base/core/java/android/os/AsyncTask.java文件中:
 
  1. public abstract class AsyncTask<Params, Progress, Result> {   
  2.     ......   
  3.    
  4.     private static final BlockingQueue<Runnable> sWorkQueue =   
  5.             new LinkedBlockingQueue<Runnable>(10);   
  6.    
  7.     private static final ThreadFactory sThreadFactory = new ThreadFactory() {   
  8.         private final AtomicInteger mCount = new AtomicInteger(1);   
  9.    
  10.         public Thread newThread(Runnable r) {   
  11.             return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());   
  12.         }   
  13.     };   
  14.    
  15.     ......   
  16.    
  17.     private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,   
  18.         MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);   
  19.    
  20.     private static final int MESSAGE_POST_RESULT = 0x1;   
  21.     private static final int MESSAGE_POST_PROGRESS = 0x2;   
  22.     private static final int MESSAGE_POST_CANCEL = 0x3;   
  23.    
  24.     private static final InternalHandler sHandler = new InternalHandler();   
  25.    
  26.     private final WorkerRunnable<Params, Result> mWorker;   
  27.     private final FutureTask<Result> mFuture;   
  28.    
  29.     ......   
  30.    
  31.     public AsyncTask() {   
  32.         mWorker = new WorkerRunnable<Params, Result>() {   
  33.             public Result call() throws Exception {   
  34.                 ......   
  35.                 return doInBackground(mParams);   
  36.             }   
  37.         };   
  38.    
  39.         mFuture = new FutureTask<Result>(mWorker) {   
  40.             @Override   
  41.             protected void done() {   
  42.                 Message message;   
  43.                 Result result = null;   
  44.    
  45.                 try {   
  46.                     result = get();   
  47.                 } catch (InterruptedException e) {   
  48.                     android.util.Log.w(LOG_TAG, e);   
  49.                 } catch (ExecutionException e) {   
  50.                     throw new RuntimeException("An error occured while executing doInBackground()",   
  51.                         e.getCause());   
  52.                 } catch (CancellationException e) {   
  53.                     message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,   
  54.                         new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));   
  55.                     message.sendToTarget();   
  56.                     return;   
  57.                 } catch (Throwable t) {   
  58.                     throw new RuntimeException("An error occured while executing "   
  59.                         + "doInBackground()", t);   
  60.                 }   
  61.    
  62.                 message = sHandler.obtainMessage(MESSAGE_POST_RESULT,   
  63.                     new AsyncTaskResult<Result>(AsyncTask.this, result));   
  64.                 message.sendToTarget();   
  65.             }   
  66.         };   
  67.     }   
  68.    
  69.     ......   
  70.    
  71.     public final Result get() throws InterruptedException, ExecutionException {   
  72.         return mFuture.get();   
  73.     }   
  74.    
  75.     ......   
  76.    
  77.     public final AsyncTask<Params, Progress, Result> execute(Params... params) {   
  78.         ......   
  79.    
  80.         mWorker.mParams = params;   
  81.         sExecutor.execute(mFuture);   
  82.    
  83.         return this;   
  84.     }   
  85.    
  86.     ......   
  87.    
  88.     protected final void publishProgress(Progress... values) {   
  89.         sHandler.obtainMessage(MESSAGE_POST_PROGRESS,   
  90.             new AsyncTaskResult<Progress>(this, values)).sendToTarget();   
  91.     }   
  92.    
  93.         private void finish(Result result) {   
  94.                 ......   
  95.                 onPostExecute(result);   
  96.                 ......   
  97.         }   
  98.    
  99.     ......   
  100.    
  101.     private static class InternalHandler extends Handler {   
  102.         @SuppressWarnings({"unchecked""RawUseOfParameterizedType"})   
  103.         @Override   
  104.         public void handleMessage(Message msg) {   
  105.             AsyncTaskResult result = (AsyncTaskResult) msg.obj;   
  106.             switch (msg.what) {   
  107.                 case MESSAGE_POST_RESULT:   
  108.                  // There is only one result   
  109.                  result.mTask.finish(result.mData[0]);   
  110.                  break;   
  111.                 case MESSAGE_POST_PROGRESS:   
  112.                  result.mTask.onProgressUpdate(result.mData);   
  113.                  break;   
  114.                 case MESSAGE_POST_CANCEL:   
  115.                  result.mTask.onCancelled();   
  116.                  break;   
  117.             }   
  118.         }   
  119.     }   
  120.    
  121.     private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {   
  122.         Params[] mParams;   
  123.     }   
  124.    
  125.     private static class AsyncTaskResult<Data> {   
  126.         final AsyncTask mTask;   
  127.         final Data[] mData;   
  128.    
  129.         AsyncTaskResult(AsyncTask task, Data... data) {   
  130.             mTask = task;   
  131.             mData = data;   
  132.         }   
  133.     }   
  134. }   




本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966885,如需转载请自行联系原作者

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/286869.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GIS专业核心课程电子教材配套实验数据汇总(持续更新)

本文整合了GIS专业核心课程电子pdf教材,包括地理信息系统、地图学、遥感、摄影测量、遥感数字图像处理、工程测量、施工测量、GPS、数字测图、空间数据库、程序设计等,持续更新。 一、ArcGIS10实验教程(配套实验数据) 二、地理信息系统

7月18日实习日志

今天的上午的工作和昨天一样&#xff0c;上午转发了三十篇&#xff0c;基本上没有遇到什么问题。下午还是转载视频和发稿。 转载于:https://www.cnblogs.com/a1107/p/5706351.html

我抓到bit哥了,嘿嘿嘿(5)

作者简介 作者名&#xff1a;1_bit 简介&#xff1a;CSDN博客专家&#xff0c;2020年博客之星TOP5&#xff0c;蓝桥签约作者。15-16年曾在网上直播&#xff0c;带领一批程序小白走上程序员之路。欢迎各位小白加我咨询我相关信息&#xff0c;迷茫的你会找到答案。 目录 HTML基…

遥感、地理空间数据、全国基础数据下载网站大全汇总

本文收集整理了国内外常用的遥感、GNSS、地理空间数据下载网站,可以下载各种格式的矢量、栅格等数据,主要包括遥感影像、NDVI、太阳辐射、数字高程模型等各种地理空间数据,供GISer学习交流使用。 1. 地理空间数据云 该网站为国内学者使用最多的、数据下载方便的网站,可以…

RPA之基于FlaUI的微信发送消息给某人

本文由网友蓝创精英团队投稿&#xff0c;欢迎转载、分享原文作者&#xff1a;蓝创精英团队原文链接&#xff1a;https://kesshei.blog.csdn.net/article/details/124955177目的一直想实现微信的群发功能&#xff0c;但是&#xff0c;没有实现&#xff0c;原因有一条是怕违法&am…

感受机房管理化繁为简-新款KVM使用心得

感受机房管理化繁为简-新款KVM使用心得 一、 背景 随着网络应用的不断增多&#xff0c;各地机房服务器数量也随之增加&#xff0c;利用多传统主机切换器的方式已经无法满足目前这种区域广、设备多人员紧缺的现状&#xff0c;而且即使是使用了一些远程管理软件&#xff0c;实现的…

我化身保姆为你提供 html 教学服务(6)

作者简介 作者名&#xff1a;1_bit 简介&#xff1a;CSDN博客专家&#xff0c;2020年博客之星TOP5&#xff0c;蓝桥签约作者。15-16年曾在网上直播&#xff0c;带领一批程序小白走上程序员之路。欢迎各位小白加我咨询我相关信息&#xff0c;迷茫的你会找到答案。 目录 HTML基…

那一年,我考入了西北师范大学GIS专业,然而我很迷茫,GISer的职业规划到底是怎样的?

那一年&#xff0c;我考入了西北师范大学&#xff0c;录取专业为地理信息系统&#xff0c;也就是常说的GIS&#xff0c;本科毕业后又考取了GIS专业的研究生&#xff0c;顺利毕业&#xff0c;进入了高校从事GIS教育工作。作为一个GISer&#xff0c;我相信有很多人跟我一样很迷茫…

Android之如何分析手机系统相册图片和视频删除后保存的位置

1 需求 需要获取各种型号手机系统相册图片和视频删除后保存的位置 2 分析 1)我们可以通过在sdcard目录下进行相关查找文件夹关键字,对 "cycle"或者"trash"或者*galle*进行忽略大小写模糊查询都有文件夹 find . -iname *cycle* find . -iname *trash*…

WPF 实现水珠效果按钮组

本文经原作者授权以原创方式二次分享&#xff0c;欢迎转载、分享。原文作者&#xff1a;普通的地球人原文地址&#xff1a;https://www.cnblogs.com/tsliwei/p/8041928.html相关知识这部分基本就是废话,网上都能找到,我只不过是整理了以下.建议先不看,用到的时候可以回来看看贝…

组策略管理——软件限制策略(4)

编写软件限制规则 在前面几篇文章中讲了软件限制规则的基本概念&#xff0c;现在就来学习如何编写自定义软件限制策略。 编写规则应遵循的原则 首先&#xff0c;需要大家注意的是&#xff0c;软件限制策略应本着方便、安全、实用的原则来编写。限制规则灵活方便&#xff0c;自定…

我使用 html 反向输出自己打自己(7)

作者简介 作者名&#xff1a;1_bit 简介&#xff1a;CSDN博客专家&#xff0c;2020年博客之星TOP5&#xff0c;蓝桥签约作者。15-16年曾在网上直播&#xff0c;带领一批程序小白走上程序员之路。欢迎各位小白加我咨询我相关信息&#xff0c;迷茫的你会找到答案。 目录 HTML基…

Castle.DynamicProxy拦截器

在asp.net mvc或asp.net miniapi中&#xff0c;有过滤器&#xff0c;可以在请求前或后增加一层&#xff0c;达到验证&#xff0c;过滤等作用&#xff0c;如果在Service的方法前后加一层呢&#xff1f;这里介绍一下Castle.DynamicProxy的用法。首先引入Castle.Core实现代码相对轻…

Android选项切换条SHSegmentControl

&#xfeff;&#xfeff;Android选项切换条SHSegmentControl SHSegmentControl是github上一个开源的选项切换条&#xff0c;其样式如图所示&#xff1a; SHSegmentControl在github上的项目主页地址&#xff1a;https://github.com/7heaven/SHSegmentControl SHSegmentControl…

从零开始编写自己的C#框架(14)——T4模板在逻辑层中的应用(三)

原本关于T4模板原想分5个章节详细解说的&#xff0c;不过因为最近比较忙&#xff0c;也不想将整个系列时间拉得太长&#xff0c;所以就将它们整合在一块了&#xff0c;可能会有很多细节没有讲到&#xff0c;希望大家自己对着代码与模板去研究。 本章代码量会比较大&#xff0c;…

赶紧3分钟学完15分钟的内容我要出去玩(8)

作者简介 作者名&#xff1a;1_bit 简介&#xff1a;CSDN博客专家&#xff0c;2020年博客之星TOP5&#xff0c;蓝桥签约作者。15-16年曾在网上直播&#xff0c;带领一批程序小白走上程序员之路。欢迎各位小白加我咨询我相关信息&#xff0c;迷茫的你会找到答案。 目录 HTML基…

Hello Playwright:(5)查找元素

操作浏览器归根到底就是和页面进行交互&#xff0c;那么必不可少的操作就是查找页面上的元素。因此我们需要熟练掌握Locator 定位器。在上一节我们讲过&#xff0c;可以使用Page.Locator(selector, options)方法创建定位器&#xff0c;而如何定位到元素则取决于selector 选择器…

RxSwift 之官方文档

RxSwift 官方文档结构 Introduction:SubjectsTransforming ObservablesFiltering ObservablesCombining ObservablesError Handing OperatorsObservable Utility OperatorsConditional and Boolean OperatorsMathematical and Aggregate OperatorsConnectable Observable Opera…

2019年甘肃省普通高等学校高职(专科)升本科考试招生工作实施办法

2019年甘肃省普通高等学校高职&#xff08;专科&#xff09;升本科考试招生工作实施办法 2019年甘肃省普通高等学校高职&#xff08;专科&#xff09;升本科考试招生工作实施办法 根据教育部有关规定及要求&#xff0c;结合我省实际&#xff0c;为确保普通高等学校高职&#x…

HTML基础之bit哥的反客为主之道(9)

作者简介 作者名&#xff1a;1_bit 简介&#xff1a;CSDN博客专家&#xff0c;2020年博客之星TOP5&#xff0c;蓝桥签约作者。15-16年曾在网上直播&#xff0c;带领一批程序小白走上程序员之路。欢迎各位小白加我咨询我相关信息&#xff0c;迷茫的你会找到答案。 目录 HTML基…