`
lxh2002
  • 浏览: 126492 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

〔原创〕Android的组件编程模型

 
阅读更多

一、Android应用的理解

对一般的操作系统而言,程序通常就是操作系统中进程的概念。以Windows里面的办公软件Word为例,如图1所示,当启动Word程序后,Windows的任务管理器中会出现一个名为“winword.exe”的进程,而这个winword.exe其实就是MS Office软件包中的一个可执行文件。只是除了这个winword.exe文件之外,还需要若干个依赖的.dll动态链接库文件一起配合才能执行,如图2所示。



 

1 Windows中的进程



 

2 winword.exe程序依赖的动态链接库

 

从这里可以看出,一个Windows系统上的应用程序,可以简单理解为由.exe可执行程序和.dll动态链接库文件共同构成。当应用程序启动加载到内存中,就变成了“进程”的概念了。同样,

 

Linux平台上,一个应用程序也是由一个可执行文件(比如gzip)和若干.so的文件构成,其中.so文件是一些共享对象(shared object)文件,它们的作用与.dll动态链接库是类似的。

 

现在回过头来看看Android平台上的应用程序。当我们开发Android应用程序时,一般需要在ADT集成开发环境中新建一个Android Application Project项目,图3是一个典型的Android项目结构:



 

3 Android项目结构

 

当然,Android项目最终还是要被打包成.apk文件(比如这里的BMI.apk)才能使用,这个.apk表面上看起来与Windows平台上的.exe是类似的,都是用来执行的程序,对Android的初学者而言,这种类比更容易理解。

 

实际上,Android平台的.apk文件的角色,只是承载Android组件的一个载体,.apk并不等同于.exe文件。

二、Android组件模型

我们知道,在开发Android应用程序时,一般都会涉及到AcivityServiceBroadcastReceiverContentProvider这四大组件。那么,到底什么是组件呢?所谓组件,我们可以将它理解成是Android应用程序的组成部分,一个Android应用程序通常都要包括若干个组件,这些组件可以来自于一个apk文件,也可以来自多个apk文件。值得注意的是,这里说的组件概念更为宽泛,并不是一般意义上所说的按钮、下拉框之类的控件,而是一种抽象意义上的“软件单元”。

 

下面使用一张图来对Android平台的组件进行说明,如图4所示。



 

4 Android组件模型

 

Android来说,外部的应用程序通常都是以.apk软件包的形式安装的。在图3BMI项目结构中,共定义了两个Activity组件(BMIActivityInfoActivity),当我们把项目打包成.apk文件并安装到Android系统时,BMIActivityInfoActivity就成了Android系统管理的两个组件了。

 

此时,AcivityServiceBroadcastReceiverContentProvider这四大组件实际上就变成了Android平台上的“积木块”,安装某一个.apk软件包到Android平台,实际上只是往Android平台上安放了几个积木块,如图4所示,这就是Android所谓的“组件”概念。在图4中,X.apk中承载了Activity1Activity2两个组件,Y.apk中承载了Activity3Service1BroadcastReceiver0这三个组件,Z.apk中承载了ContentProvider0这个组件。

 

还记得每个Android应用程序项目都有一个AndroidMenifest.xml文件吗,这个文件其实就是组件的注册文件(类似Windows平台的.reg文件),每个定义的AcivityServiceBroadcastReceiverContentProvider组件都必须在AndroidMenifest.xml中予以声明,否则在Android上是不可用的,至多只是一个普通的Java类而已。当.apk软件包安装到Android中时,Android会读取AndroidMenifest.xml中声明的组件,然后集中管理这些组件,就像Windows注册表所做的那样。

 

一个真正意义上的Android应用程序,其中用到的组件并不一定恰好在一个.apk中,它可以是Android上组件“积木块”的任意组合。比如我们开发了一个应用,这个应用的项目中定义了Activity1Activity2两个组件,然后打包成X.apk安装到Android,但在Activity1的代码中还用到了Activity3组件,这个Activity3组件是Android系统上已经安装好的一个组件(比如Activity1调用Activity3这个照相机组件,而Activity3组件是通过Y.apk安装进来的)。

三、Task栈与Intent组件调用

与传统操作系统不同的是,Android应用程序的概念并不是一个apk,而是一个Task,即任务。所谓Task,就是根据需要将Android平台上的若干组件组合起来,通过这些组件的配合达到预期的目的。Windows中的应用程序体现出来的是“进程”,而Android应用程序体现出来则是“Task”,即任务。当然,Android底层的Linux操作系统上最终的跑的还是进程,但这些进程不是由我们的应用程序直接控制的,所以,Android组件是被托管到进程中运行的。所以,Android应用程序并不与.apk文件一一对应,我们可以根据需要对Android上的组件任意组合,就像搭乐高积木一样,而Android应用包含的各组件在哪个进程中,已经变得不重要了,系统会帮忙处理好一切。

 

一般情况下,当我们运行某个应用程序时,实际上是找到这个应用程序的“起始组件”,通常都是Activity组件,因为只有Activity组件才有可视界面,可以响应用户的操作,然后以起始组件为出发点调用其它组件,从而完成我们希望的功能。在开发Android应用程序时,通常都会声明处理如下动作的Activity组件:

<activity

    android:name="mytest.Activity1"

    android:label="@string/app_name">

     <intent-filter>

          <action android:name="android.intent.action.MAIN" />

          <category android:name="android.intent.category.LAUNCHER" />

     </intent-filter>

</activity>

 

其中,“android.intent.category.LAUNCHER”的含义是允许Android桌面启动器(Launcher)检测应用软件的包名,然后把当前应用的图标和名称解析出来显示在应用列表里。这样,当我们点击桌面启动器的应用程序图标时,声明了“android.intent.action.MAIN”动作的Activity将被启动,类似于Java语言程序的main()方法。

 

顺带提一下,如果你希望自己的应用程序不会在桌面启动器中出现图标,只需将“android.intent.category.LAUNCHER”的声明去掉即可。

 

现在假定应用程序要从Activity1开始启动,然后在Activity1中有一个按钮,点击按钮能启动到Activity2Activity2中也有一个按钮能启动到Activity3,此时,这三个组件就共同完成了当前应用程序的功能。对Android来说,这三个组件是一任务栈的方式进行管理的,如图5所示。



 

5 Android任务栈(应用程序当前组件为Activity3

 

严格来说,由Activity1Activity2Activity3共同形成的任务栈才是Android应用程序的概念。如果当前显示的是Activity3组件,然后点击两次返回键,此时任务栈中就剩下Activity1了,如图6所示。



 

6 Android任务栈(应用程序当前组件为Activity1

 

当然,在任务栈中管理的只是Activity组件,其它组件也可以在应用程序中使用,只不过它们不会出现在任务栈中而已。到现在,我们应该明白Android应用程序是怎么回事,说白了,Android应用程序是由若干组件共同配合所构成的一个动态过程(任务栈),它用到的组件可能来自一个或多个.apk文件中定义的组件。

 

在应用程序中,当你需要启动某个组件时,因为组件是被托管在底层的进程中,因此我们不能直接创建组件的对象,而是通过AndroidIntent意图机制来达到目的。引入Intent的原因,就是因为组件是被托管的,既然是被托管,我们不能直接决定其生死(比如new Activity1()),而是需要构造一个Intenet对象,丢给Android系统,Android系统会根据Intent中提供的意图信息去查找所有注册过的组件,找到后启动该组件。也正是因为Android组件的生死不是有我们来控制的,我们只能向Android请求需要用到某个组件,所以才会出现ActivityService等组件声明周期的说法。

 

下面以Activity1启动Activity2为例来说明Intent的工作原理,如图7所示:



 

通过Intent启动其它组件

    Intent intent = new Intent();

    intent.putExtra("bmi", 1.5);

    intent.setClass(Activity1.this, Activity2.class);

    startActivity(intent);

 

从这里可以看出,我们要启动Activity2,要做的只能是新建一个Intenet对象,然后通过startActivity()方法将这个Intent对象发给Android。当Android收到这个要求时,它会查找符合条件的组件,然后启动这个组件。

 

Android中,通过Intent机制启动组件分为显式启动和隐式启动。这里给的例子就是显式启动,组件Activity1的代码中完全知道Activity2,因此通过intenet.setClass()就提供了所要的组件信息,而且还使用intenet.putExtra()方法将某些数据传递给Activity2组件。而对于隐式启动组件的方法,首先要在配置文件中声明被启动组件Activity2,设置其能够处理的<intent-filter>,然后在调用者Activity1的代码中,就要通过Intent设置希望匹配的动作信息,比如:

        // 调用Web浏览器

        uri = Uri.parse("http://www.google.com");

        intent = new Intent(Intent.ACTION_VIEW, uri);

        startActivity(intent);

 

总之,Android的组件机制要求组件之间不能相互直接调用或使用,因此你不能在Activity1的代码中直接创建一个Activity2的对象(new Activity2()),永远不要这样做!组件之间的调用必须通过Android统一进行调度,有点类似于“中央集权”。组件之间的调用,必须通过Intent,无论是显式Intent还是隐式Intent都是如此。

四、Context的理解

Android应用程序开发时,还有一个经常用到的Context概念,即“上下文”。这个Context就像一只无形的手,很多类和方法的调用都需要借助Context,通过它可以访问当前包的资源(getResources()getAssets()),也能启动其它组件(ActivityServiceBroadcastReceiver),还可以得到各种服务(getSystemService()),因此,实际上Context是提供了应用程序的运行环境,在Context这个大环境里,各个组件才可以访问资源,才能完成和其他组件、服务的交互。

 

我们首先来看一下ContextApplicationServiceActivity等几个常用类之间的关系:



 

8 Context/Activity/Service/Application之间的关系

 

最上面的Context是一个抽象类,下面的ApplicationServiceActivity类都间接继承了这个Context抽象类。ContextWrapper类是Context抽象类的实现者,但它实际上只是一个Context抽象类所要求功能的一个“封装”(抽象类中有抽象方法,子类必须提供抽象方法的实现代码),真正提供具体功能代码的实际上是ContextImpl类,因此ContextImpl类才是那只真正伸向Android核心框架服务的手,ApplicationServiceActivity类可以通过ContextWrapper类间接将手伸向Android核心框架服务。比如向Android要求获取应用程序的资源文件,用到的getResource()方法就是通过ContextWrapper调用ContexImpl的具体方法来得到的。

 

因为ActivityService类都继承了ContextWrapper,换句话说ActivityService组件都是上下文,都有获取系统资源的能力。对于Application,这是一个应用对象,AcivityServiceBroadcastReceiverContentProvider这四大组件都必须在<application>应用对象内部声明才能被Android系统所接受。在ActivityService中要获得这个Application对象,可以通过调用getApplication()得到,此外还可以通过调用getApplicationContext()得到这个Application对象,它同时也代表一个Context

 

值得注意的是,尽管AcivityServiceApplication都是继承自Context,虽然它们都代表Context,但它们并不是同一个,因为各个组件都是独立的。

 

 

参考资料:

http://www.cnblogs.com/android100/p/Android-Context.html

 

 

  • 大小: 27.2 KB
  • 大小: 30.6 KB
  • 大小: 15.5 KB
  • 大小: 15 KB
  • 大小: 4.5 KB
  • 大小: 3.4 KB
  • 大小: 7.3 KB
  • 大小: 17.4 KB
分享到:
评论

相关推荐

    Android 7.0 全套教程PPT 全部手写 原创

    此外,理解Android的组件模型是关键,如Activity(活动)、Service(服务)、BroadcastReceiver(广播接收器)和ContentProvider(内容提供者),这些构成了Android应用的核心架构。 PPT中可能详细讲解了如何创建...

    传智播客 Android 面试题精编第四版

    2. Android组件:深入探讨Activity、Service、BroadcastReceiver、ContentProvider和Intent的工作原理及其交互方式。 3. UI设计:介绍布局管理器如LinearLayout、RelativeLayout和ConstraintLayout,以及自定义视图...

    Android Studio开发的单词本APP源码(期末大作业)

    在这里,Model表示数据模型,View是用户界面,ViewModel作为两者之间的桥梁。 4. **XML布局文件**: XML文件定义了应用的用户界面元素,如TextView、EditText和Button等,以及它们的布局属性。 5. **Adapters**: ...

    android52期 Android46期(已破解)android35 期

    - **Android 5.x新特性**:如Material Design的设计风格更新、新的权限模型等。 - **运行时权限管理**:Android 6.0引入的新特性,用户可以在应用运行时选择授予或拒绝特定权限。 - **多窗口支持**:针对大屏设备的...

    Android下的原创小游戏-九宫格

    在Android平台上,开发一款原创的小游戏是学习移动应用编程的好方式。这个名为“九宫格”的小游戏就是一个典型的示例,它结合了基本的Android开发技术和逻辑思维元素。下面我们将深入探讨这款游戏中涉及到的关键知识...

    基于Android的移动应用app安全卫士源码(原创).rar

    1. UI层:主要包括Activity、Fragment和Adapter等组件,负责用户界面的展示和交互。 2. 业务逻辑层:包括Presenter类,处理UI层与Model层的通信,执行具体的业务逻辑。 3. 数据模型层:包括Model类,封装数据处理和...

    Android常用代码

    - `原创android界面效果全汇总.pdf`:这份文档可能包含了各种Android界面设计和实现的实例,包括但不限于滑动菜单、动画效果、自定义控件等。开发者可以通过学习这些案例,提升应用的视觉吸引力和交互性。 2. **...

    基于android平台的GTD事务管理系统本科毕业设计.doc

    理解Android的组件模型,如Activity、Service、BroadcastReceiver和ContentProvider。 2. **用户界面设计**:遵循Material Design指南创建直观、响应式的用户界面,使用XML布局文件定义界面元素,可能涉及...

    基于Android计算器功能的实现毕业设计.pdf

    Android开发平台为开发者提供了完善的开发环境,包括集成开发环境(IDE)如Eclipse,它支持面向对象的编程语言Java,使得开发者能够构建高效、稳定的移动应用。对于Android计算器的实现,首先需要理解Android的基本...

    Android扑克网络游戏源码

    Socket是网络编程中的基础组件,它允许两个程序通过网络进行数据交换。在Android应用中,我们通常使用`java.net.Socket`类来创建和管理连接。源码中的Socket通信可能涉及到以下几个步骤:建立连接、发送数据(如玩家...

    react-native progress bar 原创

    通过React的声明式编程模型和组件化思想,开发者可以轻松地创建丰富的用户界面。 针对"react-native progress bar",我们主要会用到React Native的Progress组件。这个组件提供了两种类型的进度条:Progress.Circle...

    Android模仿乐淘的应用程序分析源码

    7. **权限管理**:考虑到Android的权限模型,源码可能包含了对运行时权限的管理,例如使用AndroidX的PermissionRequester或者EasyPermissions库。 8. **支付集成**:为了实现在线支付,源码可能集成了支付宝、微信...

    毕设&课程作业_一款基于DCT算法的水印嵌入和提取的移动智能终端数字图像证据系统Android APP.zip

    6. **Android应用开发**:涉及到Android SDK、Android Studio等开发工具的使用,以及对Android编程模型的理解,包括Activity、Intent、BroadcastReceiver等组件的使用,以及XML布局设计和Java/Kotlin编程语言的应用...

    应用源码tewilove-faplayer.zip

    这有助于理解Android的异步编程模型和生命周期管理。 5. **服务与广播接收者**: 音乐播放器可能包含后台服务,以便在应用被关闭后仍能继续播放音乐。同时,应用可能注册了广播接收者来监听系统事件,如耳机插拔或...

    基于Android的新闻客户端设计与实现.doc

    设计Android新闻客户端,需要掌握Android SDK、Java编程语言,以及XML布局设计。应用通常包括以下几个关键组件: - 数据获取:通过API接口与新闻服务器进行数据交换,获取最新、热门的新闻资讯。 - 数据解析:使用...

    应用源码之TestSwitchButton.zip

    【标题】"应用源码之TestSwitchButton.zip" 提供了一个深入学习Android源码的机会,特别是聚焦于`SwitchButton`这一组件。`SwitchButton`在Android应用开发中扮演着重要角色,它是一种开关控件,用户可以切换其状态...

    大话企业级androoid开发精简版

    6. MVC设计模式:模型-视图-控制器(MVC)是一种广泛使用的软件设计模式,将应用分为三个核心组件:模型(Model)负责数据和业务逻辑,视图(View)负责展示数据,控制器(Controller)负责接收用户输入并调用模型和...

    应用源码高仿天天动听音乐.zip

    8. **事件监听与响应**:Android的事件驱动模型在源码中会有体现,如点击事件、滑动事件等,通过OnClickListener、OnSeekBarChangeListener等接口实现。 9. **异步编程与线程管理**:为了保证UI线程不被阻塞,源码...

    应用源码在线词典源码.zip

    该压缩包“应用源码在线词典源码.zip”包含了一个Android应用项目,其设计目标是实现一个在线词典功能,这对于学习Android编程以及Java编程的开发者来说是一个宝贵的资源。源码学习是提升技能的重要途径,通过阅读和...

Global site tag (gtag.js) - Google Analytics