• 1. Bob Wang 2013-6-30Android 开发基础
  • 2. 系统架构分析1)应用程序层2)应用程序框架层3)核心运行库层4)Linux内核层应用程序结构分析1、Activity类 及 MainHelloWorld文件浅析2、R文件浅析3、res/layout/main.xml文件浅析 – 布局layout4、AndroidManifest.xml文件浅析5、Android.jar文件浅析Activity生命周期AsynceTaskView
  • 3. Android系统架构分析
  • 4. Android系统架构分析
  • 5. Android系统架构分析 从上图中可以看出,Android系统架构为4层结构,从上层到下层分别是应用程序层、应用程序框架层、系统运行库层以及Linux内核层,分别介绍如下: 1)应用程序层       Android平台不仅仅是操作系统,也包含了许多应用程序,诸如SMS短信客户端程序、电话拨号程序、图片浏览器、Web浏览器等应用程序。     这些应用程序都是用Java语言编写的,并且这些应用程序都是可以被开发人员开发的其他应用程序所替换,这点不同于其他手机操作系统固化在系统内部的系统软件,更加灵活和个性化。
  • 6. Android系统架构分析2)应用程序框架层          应用程序框架层是我们从事Android开发的基础,很多核心应用程序也是通过这一层来实现其核心功能的,该层简化了组件的重用,开发人员可以直接使用其提供的组件来进行快速的应用程序开发,也可以通过继承而实现个性化的拓展。          a) Activity Manager(活动管理器)               管理各个应用程序生命周期以及通常的导航回退功能          b) Window Manager(窗口管理器)               管理所有的窗口程序          c)  Content Provider(内容提供器)               使得不同应用程序之间存取或者分享数据
  • 7. Android系统架构分析         d) View System(视图系统)               构建应用程序的基本组件          e) Notification Manager(通告管理器)               使得应用程序可以在状态栏中显示自定义的提示信息          f) Package Manager(包管理器)                Android系统内的程序管理          g)Telephony Manager(电话管理器)               管理所有的移动设备功能
  • 8. Android系统架构分析         d) View System(视图系统)               构建应用程序的基本组件          e) Notification Manager(通告管理器)               使得应用程序可以在状态栏中显示自定义的提示信息          f) Package Manager(包管理器)                Android系统内的程序管理          g)Telephony Manager(电话管理器)               管理所有的移动设备功能
  • 9. Android系统架构分析         h)Resource Manager(资源管理器)               提供应用程序使用的各种非代码资源,如本地化字符串、图片、布局文件、颜色文件等          i)Location Manager(位置管理器)              提供位置服务          j)XMPP Service(XMPP服务)              提供Google Talk服务 
  • 10. Android系统架构分析    3)核心运行库层          从图中可以看出,系统运行库层可以分成两部分,分别是核心库和Android运行时,分别介绍如下:          a) 核心库         核心库是应用程序框架的支撑,是连接应用程序框架层与Linux内核层的重要纽带。其主要分为如下几个:      Ø  Surface Manager(显示系统管理):                   执行多个应用程序时候,负责管理显示与存取操作间的互动,另外也负责2D绘图与3D绘图进行显示合成。       Ø  Media Framework(媒体框架):                    多媒体库,基于PacketVideo OpenCore;             支持多种常用的音频、视频格式录制和回放,编码格式包括MPEG4、MP3、H.264、AAC、ARM。
  • 11. Android系统架构分析             Ø  SQLite(数据库):                   小型的关系型数据库引擎                Ø  OpenGL|ES(绘图函数库):                   根据OpenGL ES 1.0API标准实现的3D绘图函数库                Ø  FreeType:                   提供点阵字与向量字的描绘与显示                Ø  WebKit:                   一套网页浏览器的软件引擎               Ø  SGL:                   底层的2D图形渲染引擎                Ø  SSL:                   在Andorid上通信过程中实现握手                Ø  Libc(C库):              从BSD继承来的标准C系统函数库,专门为基于embedded linux的设备定制
  • 12. Android系统架构分析         b) Android运行时              Android应用程序时采用Java语言编写,程序在Android运行时中执行,其运行时分为运行时核心库和Dalvik虚拟机两部分。              Ø   运行时核心库                  核心库提供了Java语言API中的大多数功能,同时也包含了Android的一些核心API,如android.os、android.net、android.media等等。              Ø  Dalvik虚拟机                  区别于Java虚拟机的是,每一个Android 应用程序都在它自己的进程中运行,都有一个属于自己的Dalvik 虚拟机,这一点可以让系统在运行时可以达到优化,程序间的影响大大降低。                  Dalvik虚拟机并非运行Java字节码,而是运行自己的字节码。
  • 13. Android系统架构分析    4)Linux内核层          Linux 内核是硬件和软件层之间的抽象层。         Android是基于Linux2.6内核,但是把linux内受GNU协议约束的部分做了取代,这样Android的程序就可以用于商业目的。      其核心系统服务如安全性、内存管理、进程管理、网路协议以及驱动模型都依赖于Linux内核。
  • 14. Android应用程序结构分析
  • 15. Android应用程序结构分析Helloword的程序目录
  • 16. Android应用程序结构分析 1. MainHelloWorld.java文件   2. R.java文件   3. android.jar文件   4. RES、Layout、main.xml文件   5. androidmainfest.xml文件 接下来我们逐个加以讲解:      1、Activity类 及 MainHelloWorld文件浅析
  • 17. Android应用程序结构分析 Activity是Android中的视图部分,负责界面显示。 package android.basic.lesson2.helloworld; import android.app.Activity; import android.os.Bundle; public class MainHelloWorld extends Activity { /** Called when the activity is first created. */ @ Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
  • 18. Android应用程序结构分析2、R文件浅析        我们看到Gen目录下有个R.Java文件,R文件由ADT自动生成,程序员不需要也不要去修改它,R文件负责调用应用程序中的非代码资源。 从R文件中可以看到每一个资源都会有一个整数和它相对应。
  • 19. Android应用程序结构分析
  • 20. Android应用程序结构分析 3、res/layout/main.xml文件浅析 – 布局layout       我们看到有个res目录,也就是resource目录,这个目录下存放资源文件,资源文件的统一管理,也是Android系统的一大特色。现在要注意看的是layout目录下的main.xml。这个文件的内容是有关用户界面布局和设计的。在桌面程序设计领域采用XML也许比较新颖,但是在网页设计领域,这个就很平常了。从以下代码可以看到整个程序界面由一个线性布局控件(LinearLayout)和2个文本框控件(TextView)组成。res的其他目录里的其他文件也都是相关的资源描述
  • 21. Android应用程序结构分析
  • 22. Android应用程序结构分析4、AndroidManifest.xml文件浅析 在每个应用程序的根目录都会有一个AndroidManifest.xml文件,该文件向Android操作系统描述了本程序所包括的组件,所实现的功能,能处理的数据,要请求的资源等等。 我们看到Manifest是根节点,节点属性里有versionCode和versionName来表示应用程序的版本;里面可以包含0个或1个application元素,application可以包含多个activity组件等等,具体的内容我们在接下来的课程里详细讲解。
  • 23. Android应用程序结构分析
  • 24. Android应用程序结构分析5、Android.jar文件浅析        作为一个Java项目,通常情况下都会引入要用到的工具类,也就是Jar包,在Android开发中,绝大部分开发用的工具包都被封装到一个名叫Android.jar的文件里了。        如果我们在Eclipse中展开来看,可以看到j2se中的包,apache项目中的包,还有Android自身的包文件。在这里我们简单了解一下Android的包文件:
  • 25. Android应用程序结构分析     android.app :提供高层的程序模型、提供基本的运行环境     android.content :包含各种的对设备上的数据进行访问和发布的类     android.database :通过内容提供者浏览和操作数据库     android.graphics :底层的图形库,包含画布,颜色过滤,点,矩形,可以将他们直接绘制到屏幕上.     android.location :定位和相关服务的类     android.media :提供一些类管理多种音频、视频的媒体接口     android.net :提供帮助网络访问的类,超过通常的java.net.* 接口
  • 26. Android应用程序结构分析     android.os :提供了系统服务、消息传输、IPC 机制     android.opengl :提供OpenGL 的工具     android.provider :提供类访问Android 的内容提供者     android.telephony :提供与拨打电话相关的API 交互     android.view :提供基础的用户界面接口框架     android.util :涉及工具性的方法,例如时间日期的操作     android.webkit :默认浏览器操作接口     android.widget :包含各种UI 元素(大部分是可见的)在应用程序的屏幕中使用
  • 27. Activity生命周期
  • 28. Activity生命周期Activity其实是继承了ApplicationContext这个类,我们可以重写以下方法,如下代码: public class Activity extends ApplicationContext { protected void onCreate(Bundle savedInstanceState); protected void onStart(); protected void onRestart(); protected void onResume(); protected void onPause(); protected void onStop(); protected void onDestroy(); }
  • 29. Activity生命周期 核心在Logcat视窗里, 打开应用时先后执行了onCreate()->onStart()->onResume三个方法,看一下LogCat视窗如下:
  • 30. Activity生命周期BACK键: 当我们按BACK键时,我们这个应用程序将结束,这时候我们将先后调用onPause()->onStop()->onDestory()三个方法,如下图所示:
  • 31. Activity生命周期HOME键: 当我们打开应用程序时,比如浏览器,我正在浏览NBA新闻,看到一半时,我突然想听歌,这时候我们会选择按HOME键,然后去打开音乐应用程序,而 当我们按HOME的时候,Activity先后执行了onPause()->onStop()这两个方法,这时候应用程序并没有销毁。如下图所示:
  • 32. Activity生命周期而当我们再次启动ActivityDemo应用程序时,则先后分别执行了onRestart()->onStart()->onResume()三个方法,如下图所示:
  • 33. AsynceTaskAsyncTask是抽象类,定义了三种泛型类型 Params,Progress,Result。 Params 启动任务执行的输入参数,比如HTTP请求的URL Progress 后台任务执行的百分比。 Result 后台执行任务最终返回的结果,比如String 用程序调用,开发者需要做的就是实现这些方法。 1) 子类化AsyncTask 2) 实现AsyncTask中定义的下面一个或几个方法
  • 34. AsynceTaskonPreExecute(),该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。 doInBackground(Params…),将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。 onProgressUpdate(Progress…),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。 onPostExecute(Result),在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.
  • 35. AsynceTask为了正确的使用AsyncTask类,以下是几条必须遵守的准则: 1) Task的实例必须在UI thread中创建 2) execute方法必须在UI thread中调用 3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params…), onProgressUpdate(Progress…)这几个方法 4) 该task只能被执行一次,否则多次调用时将会出现异常
  • 36. AsynceTask一、定义 private class MyAsyncTask extern AsyncTask{ } 二、实例化 & 执行 MyAsyncTask task = new MyAsyncTask(); task.excute(); 三、AsyncTask 的生命周期 AsyncTask 会依次执行 onPreExcute()—doInBackground()—[可能执行onCancel()]—onPostExcute().
  • 37. AsynceTask四、注意事项: 1.AsyncTask 的最大上限数量 我没有在SDK的文档中找到具体说明,但开发中已经领教过了,同种类型的 AsyncTask 实例,最大数量为 20 个。 如果超过,则会引发 RejectExcuteException,并 crash 因此,要考虑到用户的操作是否会引发频繁的 AsyncTask 实例化,若存在,则从 UI 上进行改进,比如: 分页机制; 线程池; 生产者-消费者模型。
  • 38. AsynceTask2.取消AsyncTask任务 文档已经说明,cancel()方法不一定能成功,所以 onCancel() 回调方法不一定被调用。 但若一个 AsyncTask 结束,则一定会调用 onPostExcute() 方法。 对于一个 doInBackground()方法中含有 while/for 循环时,最好配置 isCancel标识来 break 循环。
  • 39. AsynceTaskAsyncTask的不足之处 private static final int CORE_POOL_SIZE =5;//5个核心工作线程 private static final int MAXIMUM_POOL_SIZE = 128;//最多128个工作线程 private static final int KEEP_ALIVE = 1;//空闲线程的超时时间为1秒 private static final BlockingQueue sWorkQueue = new LinkedBlockingQueue(10);//等待队列 private static final ThreadPoolExecutorsExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue,sThreadFactory);//线程池是静态变量,所有的异步任务都会放到这个线程池的工作线程内执行。
  • 40. AsynceTask线程池中的工作线程少于5个时,将会创建新的工作线程执行异步任务(红色表示新任务,下同)
  • 41. AsynceTask2、线程池中已经有5个线程,缓冲队列未满,异步任务将会放到缓冲队列中等待
  • 42. AsynceTask3、线程池中已经有5个线程,缓冲队列已满,那么线程池将新开工作线程执行异步任务
  • 43. AsynceTask4、线程池中已经有128个线程,缓冲队列已满,如果此时向线程提交任务,将会抛出RejectedExecutionException
  • 44. AsynceTask当网络情况较差,异步任务不能尽快完成执行的情况下,新开的线程会造成listview滑动不流畅。当开启的工作线程过多时,还有出现FC的可能。 1、 AsyncTask的本质是一个静态的线程池,AsyncTask派生出的子类可以实现不同的异步任务,这些任务都是提交到静态的线程池中执行。 2、线程池中的工作线程执行doInBackground(mParams)方法执行异步任务 3、当任务状态改变之后,工作线程会向UI线程发送消息,AsyncTask内部的InternalHandler响应这些消息,并调用相关的回调函数
  • 45. ViewView,是Android的一个超类,这个类几乎包含了所有的屏幕类型。每一个View都有一个用于绘图的画布,这个画布可以进行任意扩展。 在游戏开发中叶可以自定义视图(View),这个画布的功能更能满足我们在游戏开发中的需要。在Android中,任何一个View类都只需重写onDraw 方法来实现界面显示,自定义的视图可以是复杂的3D实现,也可以是非常简单的文本形式等。  游戏的核心是不断地绘图和刷新界面,Android中提供了 invalidate 方法来实现界面刷新。注意,invalidate 不能直接在线程中调用, 就是不可以在子线程中调用,因此它违背了 Android的单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI 线程中执行,因此Android中最常用的方法就是利用Handler来实现UI线程的更新。 其实用 AsyncTask 也可以。
  • 46. ViewUI(View)的刷新 1.不使用多线程和双缓冲      这种情况最简单了,一般只是希望在View发生改变时对UI进行重绘。你只需在Activity中显式地调用View对象中的invalidate()方法即可。系统会自动调用 View的onDraw()方法。
  • 47. View2.使用多线程和不使用双缓冲      这种情况需要开启新的线程,新开的线程就不好访问View对象了。强行访问的话会报:android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views.      这时候你需要创建一个继承了android.os.Handler的子类,并重写handleMessage(Message msg)方法。android.os.Handler是能发送和处理消息的,你需要在Activity中发出更新UI的消息,然后再你的Handler(可以使用匿名内部类)中处理消息(因为匿名内部类可以访问父类变量, 你可以直接调用View对象中的invalidate()方法 )。也就是说:在新线程创建并发送一个Message,然后再主线程中捕获、处理该消息。
  • 48. View3.使用多线程和双缓冲     Android中SurfaceView是View的子类,她同时也实现了双缓冲。你可以定义一个她的子类并实现SurfaceHolder.Callback接口。由于实现SurfaceHolder.Callback接口,新线程就不需要android.os.Handler帮忙了。SurfaceHolder中lockCanvas()方法可以锁定画布,绘制完新的图像后调用unlockCanvasAndPost(canvas)解锁(显示),还是比较方便得。
  • 49. View这里我们说下android.view.View 和 android.view.SurfaceView。 SurfaceView是从View基类中派生出来的显示类,直接子类有GLSurfaceView和VideoView,可以看出GL和视频播放以及Camera摄像头一般均使用SurfaceView,到底有哪些优势呢?  SurfaceView可以控制表面的格式,比如大小,显示在屏幕中的位置,最关键是的提供了SurfaceHolder类,使用getHolder方法获取,相关的有Canvas  lockCanvas()   Canvas  lockCanvas(Rect dirty)  、void  removeCallback(SurfaceHolder.Callback callback)、void  unlockCanvasAndPost(Canvas canvas) 控制图形以及绘制, 而在SurfaceHolder.Callback 接口回调中可以通过下面三个抽象类可以自己定义具体的实现,比如第一个更改格式和显示画面。
  • 50. Viewabstract void surfaceChanged(SurfaceHolder holder, int format, int width, int height) abstract void surfaceCreated(SurfaceHolder holder) abstract void surfaceDestroyed(SurfaceHolder holder) 对于Surface相关的,Android底层还提供了GPU加速功能,所以一般实时性很强的应用中主要使用SurfaceView而不是直接从View构建,同时Android123未来后面说到的OpenGL中的GLSurfaceView也是从该类实现。  下面着重介绍View类:
  • 51. View自定义View的常用方法: onFinishInflate() 当View中所有的子控件均被映射成xml后触发 onMeasure(int, int) 确定所有子元素的大小 onLayout(boolean, int, int, int, int) 当View分配所有的子元素的大小和位置时触发 onSizeChanged(int, int, int, int) 当view的大小发生变化时触发 onDraw(Canvas) view渲染内容的细节 onKeyDown(int, KeyEvent) 有按键按下后触发
  • 52. ViewonKeyUp(int, KeyEvent) 有按键按下后弹起时触发 onTrackballEvent(MotionEvent) 轨迹球事件 onTouchEvent(MotionEvent) 触屏事件 onFocusChanged(boolean, int, Rect) 当View获取或失去焦点时触发 onWindowFocusChanged(boolean) 当窗口包含的view获取或失去焦点时触发 onAttachedToWindow() 当view被附着到一个窗口时触发 onDetachedFromWindow() 当view离开附着的窗口时触发,提示该方法和 onAttachedToWindow() 是相反的。 onWindowVisibilityChanged(int) 当窗口中包含的可见的view发生变化时触发
  • 53. View以上是View实现的一些基本接口的回调方法,一般我们需要处理画布的显示时,重写onDraw(Canvas)用的的是最多的:
  • 54. View当然还有就是处理窗口还原状态问题(一般用于横竖屏切换),除了在Activity中可以调用外,开发游戏时我们尽量在View中使用类似。