Android 四大组件

来源:互联网 发布:basetypehandler 源码 编辑:程序博客网 时间:2024/06/18 04:33

1.Activity

一个活动,如打电话、发短信、浏览网站等等,这些活动会被分配到一个Window对象,因此可以与用户进行有窗口的交互。用户界面使用了富有层次的View和ViewGroup对象。


整个ViewGroup是个树型结构。可以验证其实一般用到的数据结构就是Array、Tree、HashMap。说到View就会引入另外一个问题:View的刷新机制是?

一般的Activity都会是全屏窗口,也可以是浮动窗口(通过设置windowIsFloating主题)或者嵌入到另外一个Activity(使用ActivityGroup)。Activity的子类一般会实现两个方法onCreate,onPause.

在onCreate方法中进行初始化的工作,在onPause中比较重要的是注意把用户作的一些修改提交到数据库保存下来。

与Activity相关的几个话题是Fragments,Activity Lifecycle,Configuration Changes,Starting Activities and Getting Results,Save Persistent State,Permissions,Process Lifecycle.


从Android 3.0开始引入了Fragment,增强了代码的模块性,解决了应用需要根据大小不同的屏幕显示不同的界面组合的问题。比较明显的一个例子就是手机QQ与Pad QQ,在手机QQ上用一个Activity来显示消息列表,另一个Activity来显示消息的具体内容;而在Pad上在左边显示消息列表,右边显示消息的具体内容。


Activity的生命周期、onPause与onResume相对,onStop与onStart相对,onDestroy与onCreate相对,另外onStop通过onRestart到达onStart。简单记法就是上三、下三、右一.

Configuration Changes

onSaveInstanceState,android:configChanges,onConfigurationChanged

实际上如果用户旋转了屏幕,那么Activity会重建,加载相应的资源,如portrait或者landscape后缀的资源。


现在的手机存储空间大了,再也不像以前那样只有一个drawable-hdpi来适应各种屏幕。我记得解压过微信里面好像就是采用了各个文件夹下面放适应各种配置的资源,以使用户获得最佳的体验。

在保存用户Activity状态时,如图


在activity被destroy之前会调用onSaveInstanceState方法,在其中可以保存一些变量;下一次activity创建时系统会用已经保存的变量来恢复activity的状态,在onRestoreInstanceState中恢复。

2.Service

作为应用的组件之一代表着应用需要执行长时间的不需要与用户进行交互的操作。或者向其他的应用提供服务的服务器。在manifest中每个Service都会有一个service标签。

有两种启动服务的方法,startService和bindService

service和其他应用组件一样也是运行在宿主进程的主线程中,这个意味着如果你的应用是播放mp3或者其他阻塞的操作,应该开新的线程来运行它们。这方面可以参考下Processes and Threads主题。

IntentService是一个用来运行具有单独工作线程的标准的服务,提交上来的工作会放在等待队列中被依次执行。

关于Service的话题包括:

What is Service?

  • 一个服务不是一个单独的进程。服务本身并不会私自运行在自己的进程中,除非开发者指定它运行在进程。服务一般运行在应用进程内。
  • 一个服务不是一个线程。它并不意味着它会在主线程之外开另一个线程来处理所要做的工作来避免出现ANR错误。

服务本身实际上非常简单,它提供了两个主要特点:

  • 给应用提供了一种便利来告诉系统应用想要把一些工作放在后台运行。这种服务开启之后用户不会直接与之进行数据交互,只是在后台运行。相关的方法是Context.startService(),这个方法请求系统把任务调度给服务,让服务在后台运行,直到服务自己结束或者别人来结束服务。
  • 给应用提供了一种能力来向其他的应用暴露接口,作为一个服务器来使用。这个相关的方法是Context.bindService(),其允许与服务建立一个长连接来与服务进行数据交互。比如下载服务,新浪微薄的登录服务,支付服务等等。现在一个客户端都是几百号人来写,必然也会加速技术的成熟速度。

服务可以非常简单也可以变得复杂,这取决于你的需要。你可以把它当成是本地的一个java对象来直接调用其的一些方法,这就是本地服务。或者使用AIDL(Android Interface Define Language)来提供一个远程服务接口。

Servcie Lifecycle

服务开始使用Context.startServcie或者Context.bindService方法,结束用Context.stopServcie或者stopSelf方法。使用stopSelf方法可以确保已经提交上来的intents处理完才结束服务。

Permissions

在自身应用的manifest中声明的service可以被其他的应用所使用。其他应用需要声明相关的使用权限来开启、停止、绑定另一个应用的服务。另外一个服务可以通过checkCallingPermission方法来保护私有进程间的通信。

Process Lifecycle

Local Service Sample

把服务放在与应用同一个进程中来使用是最普遍的用法。一个.apk文件中的所有组件(Applicaion/Activity/Service/Receiver/Provider)都运行在同一个进程中是一个最为经典的情况。


Remote Messenger Service Sample

如果你想写一个运行在另一个进程中的服务来与多个客户端来进行数据交互,而不是仅仅startService之后向服务发送命令。这个时候你可以使用Messenger类来代替写一个完整的AIDL文件。也就是说进程之间的通讯方式有两种?一种是AIDL,另一种是Messenger+Handler?来看一段源码:

    /**     * Create a Messenger from a raw IBinder, which had previously been     * retrieved with {@link #getBinder}.     *      * @param target The IBinder this Messenger should communicate with.     */    public Messenger(IBinder target) {        mTarget = IMessenger.Stub.asInterface(target);    }
其实Messenger内部也是通过AIDL来实现,也就是进程间通讯还是AIDL。

3.BroadcastReceiver

LocalBroadcastManager进程内的广播通知,更加高效。

可以动态注册或者静态注册receiver。如果是在onResume中注册,则需要在onPause中取消注册,减少系统开销。

可以接收两种类型的广播,普通类型(sendBroadcast)、有序类型(sendOrderedBroadcast),在监听短信时可以设置优先级,优先接收到短信之后可以选择停止广播的传播。

与receiver相关的话题有:

Security

  • intent的action命名空间最好带应用自己的信息,不然可能会跟其他的应用起冲突。intent的命名空间是全局的。
  • 当使用registerReceiver时,任何应用都可以发广播到这个receiver,除非通过设置一些permission
  • 当在manifest中声明的receiver时,任何应用都可以发广播到这个receiver.可以通过设置android:exported='false'来阻止
  • 使用sendBroadcast方法发送的广播,一般所有的应用都可以接收到。通过设置permission或者从ice_cream_sandwich开始可以指定包名Intent.setPackage

当使用LocalBroadcastManage时,广播只在本进程内传播。

在sender和receiver中都可以设置permission.

Receiver Lifecycle

一个receiver的生命周期相当短,只在onReceive方法中。只要返回,那么系统认为这个object不再是激活状态,已经结束。所以不能在onReceive方法中进行异步操作,因为异步操作是要等到一段时间之后再回调之前的接口,所以可能在回调的时候Receiver已经被系统结束了。

特别地,不能在onReceive中显示一个dialog或者bind Service.对于提示信息,可以通过NotificationManager来做。对于service,可以通过startService来发送一条命令到service.

Process Lifecycle

由于receiver出了onReceive方法之后,进程就可能被系统回收。所以对于一些需要长时间运行的操作来讲,最好是使用Service和BroadcastReceiver来保持在操作过程中进程处于激活状态。

4.ContentProvider


0 0