原文:Android菜鸟的成长笔记(4)——你真的理解了吗?

在上一篇中我们查看了QQ的apk源文件中的布局结构,并仿照QQ完成了我们第一个应用的界面,详细请看《Android菜鸟的成长笔记》专栏。这一篇中我们来具体看看这个界面到底是怎么呈现出来的,具体的原理是什么等问题,下面我们将一步一步的解开留在我们心中的谜团。

有的朋友可能会产生这样的疑问为什么几句代码就能显示这样好看的界面?

其实能让这个界面显示的如此丰富多彩,一半功劳在我们编写的那几句代码,还有一半功劳在我们尊敬的google工程师和伟大的linux之父Linus Torvalds。下面我们进到google为我们提供的Android开发人员的官网。http://developer.android.com/index.html

主要菜单如上图所示:

Design(设计):关于Android界面设计的标准和文档。

Develop(开发):Android开发人员相关的API、工具、例子等。

Distribute(分类):分类的目录

下面来重点看一下Develop菜单下的子菜单:

Training(培训):入门指导

API Guide(API指南):API文档

Reference(参考):所有版本API对比

Tools(工具):工具及下载

Google Services(Google服务):Google的公共服务,比如Google地图

Samples(例子):一些Android开发例子及源代码

在该网站上有关于Android体系架构图,如下图所示:

从上图可以看出Android整个系统的架构分为四层:

(1)Linux Kernel (Linux 内核)

Android是基于Linux2.6内核,其核心系统服务如安全性、内存管理、进程管理、网路协议以及驱动模型都依赖于Linux内核。感谢Linus Torvalds创造出如此伟大的系统

(2)Libraries(系统运行库层)

从图中可以看出来,系统运行库层可分为两部分,分别是系统库和Android运行时。

【1】系统库:

系统库是应用程序框架的骨骼,支撑这整个应用程序的运行,是连接应用程序框架与Linux内核层的重要纽带。主要包括以下几个

Surface Manager: 执行多个应用程序的时候,负责管理显示与存取操作间的互动,另外也负责2D绘图与3D绘图进行显示合成。

Media Framework:多媒体库。

SQLite:小型关系型数据库引擎。

OpenGL|ES:3D绘图函数库。

FreeType:提供点阵字与向量字的描绘与显示。

WebKit:网页浏览器的引擎。

SGL:底层2D图形渲染引擎。

SSL:通信相关引擎。

Libc:标准c系统函数库。

【2】Android运行时

Android运行时和JRE有点类似。JRE包括JVM和其他功能函数库;而这里的Android运行时则包括Dalvik虚拟机和核心库集。

每个Android应用程序都运行在单独的Dalvik虚拟机内,也就是说Android应用程序对应一条Dalvik进程,不就是虚拟机吗?这个我在Java中学过。要注意的是:这个和Java中的虚拟机不同,不同点如下:

JVM运行的是java字节码文件,而Dalvik运行的是专有的dex文件。

JVM基于寄存器实现,Dalvik基于栈实现,所以Dalvik的速度是很快的。

(3)应用程序框架层

应用程序框架层是我们从事Android开发的基础,很多核心应用程序也是通过这一层来实现其核心功能的,该层简化了组件的重用,开发人员可以直接使用其提    供的组件来进行快速的应用程序开发,也可以通过继承而实现个性化的拓展。下面介绍一下常用的应用程序框架。

Activity Manager(活动管理器):管理各个应用程序生命周期以及通常的导航回退功能。

Window Manager(窗口管理器):管理所有窗口程序。

Content Provider(内容提供者):使不同应用程序之间可以存取或者分享数据。

View System(视图系统):构建应用程序的基本组件。

Notification Manager(通告管理器):使得应用程序可以在状态栏中显示自定义的提示信息。

Package Manager(包管理器):Android系统内的程序管理。

Telephony Manager(电话管理器):管理所有的移动设备功能。

Resource Manager(资源管理器):提供应用程序使用的各种非代码资源,如本地化字符串、图片、布局文件、颜色文件等。

Location Manager(位置管理器):提供位置服务。

XMPP Service(XMPP服务):提供Google Talk服务。

(4)应用程序层:

Android平台不仅仅是个操作系统,也包含了许多应用程序,诸如SMS短信客户端程序、电话拨号程序、图片浏览器、Web浏览器等应用程序。这些应用程序都是用Java语言编写的,并且并且这些应用程序都是可以被开发人员开发的其他应用程序所替换,这点不同于其他手机操作系统固化在系统内部的系统软件,更加灵活和个 性化。

通过上面的介绍这个问题的答案就很明显了,其实android系统为我们在底层做了很多工作。下面我们再来看看我们前面写的代码:

public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

MainActivity是我们程序的入口,继承与Activity并重写了Activity的onCreate(Bundle saveInstanceState)方法,下面我们来看看Activity中的setContentView方法和onCreate方法。

打开Android系统的源代码(后期将会专门写关于Android源代码下载方法的博客)

    public void setContentView(int layoutResID) {
getWindow().setContentView(layoutResID);
}

可以看到Activity的setContentView方法中调用了getWindow()方法返回对象的setContentView方法,下面再看看getWindow()方法返回的对象是什么

    public Window getWindow() {
return mWindow;
}
    private Window mWindow;

实际上我们底层调用的是Window对象的setContentView()方法,下面我们先来看看Activity的另一个方法onCreate()

    protected void onCreate(Bundle savedInstanceState) {
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
mCalled = true;
}

我们看到这个调用了Window对象的getWindowStyle()方法

那么这个Window到底是个什么东西呢?

其实Window对象就是描述我们Android手机具体窗体的对象,由此可见,Activity不只是一个高度抽象的UI组件,他的具体UI实现是由一系列对象来实现的。

我们可以到官方的API文档中进行查看:http://developer.android.com/reference/android/view/Window.html#setContentView(android.view.View)

Abstract base class for a top-level window look and behavior policy. An instance of this class should be used as the top-level view added to the window manager. It provides standard UI policies such as a background, title area, default key processing, etc.

The only existing implementation of this abstract class is android.policy.PhoneWindow, which you should instantiate when needing a Window. Eventually that class will be refactored and a factory method added for creating Window instances without knowing about
a particular implementation.

这个是官网上对这个类的介绍,大意如下:

该类是最顶层外观和行为策略的抽象类。这个类的实现类的实例应该添加到窗口管理器的最顶层,该类提供了标准的UI组件接口,这个接口的唯一实现类是PhoneWindow类,好的我们先来看看PhoneWindow类的源代码。

    @Override
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor();
} else {
mContentParent.removeAllViews();
}
mLayoutInflater.inflate(layoutResID, mContentParent);
final Callback cb = getCallback();
if (cb != null) {
cb.onContentChanged();
}
}
    private ViewGroup mContentParent;
    private LayoutInflater mLayoutInflater;

可以看到实际底层是一个ViewGroup对象,传给setContentView()方法的资源ID通过资源加载器LayoutInflater装载成View对象添加到ViewGroup组件中。

再看看getWindowStyle方法

从官方API上我们可以看到getWindowStyle()方法实际上是返回一个主题。

好了,我们先暂且记下PhoneWindow这个类和上面的分析,后面将会详细介绍。

Android菜鸟的成长笔记(4)——你真的理解了吗?的更多相关文章

  1. Android菜鸟的成长笔记(3)——给QQ登录界面说So Easy

    原文:Android菜鸟的成长笔记(3)--给QQ登录界面说So Easy 上一篇:Android菜鸟的成长笔记(2)--第一个Android应用 我们前面已经做了第一个Android应用程序,虽然有 ...

  2. Android菜鸟的成长笔记(6)——剖析源码学自定义主题Theme

    原文:Android菜鸟的成长笔记(6)--剖析源码学自定义主题Theme 还记得在Android菜鸟的成长笔记(3)中我们曾经遇到了一个问题吗?"这个界面和真真的QQ界面还有点不同的就是上 ...

  3. Android菜鸟的成长笔记(2)——第一个Android应用

    原文:Android菜鸟的成长笔记(2)--第一个Android应用 上一篇:Android菜鸟的成长笔记(1)--Anddroid环境搭建从入门到精通 在上一篇Android菜鸟的成长笔记(1)中我 ...

  4. Android菜鸟的成长笔记(1)——Android开发环境搭建从入门到精通

    原文:Android菜鸟的成长笔记(1)--Android开发环境搭建从入门到精通 今天在博客中看到好多Android的初学者对Android的开发环境的搭建不熟悉而导致不能进行学习,所以我决定自己写 ...

  5. Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上)

    原文:[置顶] Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上) 我们在用手机的时候可能会发现,即使应用被放到后台再返回到前台数据依然保留(比如说我们正在玩游戏,突然电话 ...

  6. Android菜鸟的成长笔记(13)——异步任务(Async Task)

    原文:[置顶] Android菜鸟的成长笔记(13)——异步任务(Async Task) Android的UI线程主要负责处理用户的事件及图形显示,因此主线程UI不能阻塞,否则会弹出一个ANR(App ...

  7. Android菜鸟的成长笔记(12)——Handler、Loop、MessageQueue

    原文:[置顶] Android菜鸟的成长笔记(12)——Handler.Loop.MessageQueue 当一个程序第一次启动时,Android会启动一条主线程(Main Thread),主线程主要 ...

  8. Android菜鸟的成长笔记(11)——Android中的事件处理

    原文:[置顶] Android菜鸟的成长笔记(11)——Android中的事件处理 Android提供了两种方式来处理事件,一个是基于回调的事件处理,另一个是基于监听的事件处理,举个例子: 基于回调的 ...

  9. Android菜鸟的成长笔记(10)——使用Bundle在Activity之间传值

    原文:[置顶] Android菜鸟的成长笔记(10)——使用Bundle在Activity之间传值 前面我们了解了如何启动一个Activity,一个Activity在启动另外一个Activity的时候 ...

随机推荐

  1. hdu4704之费马小定理+整数快速幂

    Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Subm ...

  2. kvm libvirt: hostdev passthrough support 解决加密狗冲突问题

    From: "Daniel P. Berrange" <berrange redhat com> To: Guido Günther <agx sigxcpu o ...

  3. Android中如何查找内存泄露

    1.首先确定是否有内存泄露及哪个程序造成. 1.1.内存泄露已弹出out of memory对话框的情况. 这种情况很简单,直接看对话框就知道是哪个应用的问题了.然后再分析该应用是否是因为内存泄露造成 ...

  4. 安装Devstack的DNS问题

    所谓的OpenStack一键安装,省去了敲键盘的麻烦,但是卡在中间出了问题也是比较尴尬的 在公司内安装经常会出现卡在下载软件的地方,有时候还会出错 trick就是换一个US的dns,比如8.8.8.8

  5. 【CSDN博客之星评选】我为什么坚持写博客

    今天无意中在CSDN的博客之星评选活动看到自己竟然是候选人之一,真的是十分的惊讶也十分的高兴.对于喜欢写东西.喜欢分享的我来说,已经忍不住用文字来记录一下今天的美好心情,同时也让我回想起我是如何开始在 ...

  6. javascript每日一练(九)——运动一:匀速运动

    一.js的运动 匀速运动 清除定时器 开启定时器 运动是否完成:a.运动完成,清除定时器:b.运动未完成继续 匀速运动停止条件:距离足够近  Math.abs(当然距离-目标距离) < 最小运动 ...

  7. U盘安装centos 7 提示 “Warning: /dev/root does not exist, could not boot” 解决办法

    1.查询磁盘 cd /dev ls 2.查询结果 sda 是我的硬盘对应的文件名(我机子只有一块硬盘),所以sda4就是U盘对应的文件名了,可以看到是sda4.至此我们重启一下,回到第一个图片所示的界 ...

  8. IE浏览器下web调试工具之--IE WebDeveloper介绍

    做Web项目的架构设计.开发.测试,免不了要熟悉Web页面调试工具,以此来获知哪些浏览器支持Web页面的显示,哪些浏览器下显示有问题. 目前市面上比较火爆的浏览器内核提供商,有微软的IE.mozill ...

  9. keepavlied一些参数

    priority 表示优先级 virtual_ipaddress 虚拟的IP地址(VIP) delay_loop 每个2秒检查一次real_server状态 notify_down 检测到服务down ...

  10. 欢迎大家关注我的微信公众帐号小q机器人(xiaoqrobot)(转)

    一个偶然的机会让我接触到了微信公众平台,赶紧加了几个交流群了解下相关情况,突然间发现好像全部的APP开发人员都在研究微信公众帐号的开发,而我显得有些落舞了.至于为什么热度会这么高,我想一个数字足以说明 ...