Android 四大组件与 Intent

一、Activity

四种启动模式

standard 标准启动模式,也是默认启动模式,任务栈中允许存在多个实例。

singleTop 同一个任务栈中,若 Activity 已在栈顶,那么会重用该实例,而不会新建一个实例,同时会调用 onNewIntent() 方法。

singleTask 同一个任务栈中,若 Activity 已存在该栈中,那么会重用该实例,而不会新建一个实例,同时会调用 onNewIntent() 方法。

singleInstance 同一个系统中,若 Activity 已在一个单独的任务栈中,那么会重用该实例,而不会新建一个实例,同时会调用 onNewIntent() 方法。

Activity Flags

FLAG_ACTIVITY_NEW_TASK 为 Activity 指定 singleTask 模式,效果与在 XML 中指定效果一样。

FLAG_ACTIVITY_SINGLE_TOP 为 Activity 指定 singleTop 模式,效果与在 XML 中设置的相同。

FLAG_ACTIVITY_CLEAR_TOP 具有此标记的 Activity 启动时,同一个任务栈中,它上面的所有 Activity 都要出栈。一般与上面两个标记配合使用,若复用已存在的 Activity,则同时会调用 onNewIntent() 方法。singleTask 启动模式默认具有 clear top 功能(已存在该实例时生效)。

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 具有这个标记的 Activity 不会出现在最近使用的应用程序列表中。等同于在 XML 中指定 excludeFromRecents 为 true。

二、Service

一些不需要用户交互的长期后台任务可以用 Service 来实现,但其仍然运行在 UI 线程,会受到耗时任务的影响,必要时需要使用子线程来完成相关操作。

生命周期遵循 onCreate -> onStartCommand/onStart -> onDestory 的调用结构,一个 Service 启动后只存在一个该 Service 的实例,每次调用
startService() 时,onStartCommand/onStart 会执行一次,但是 onCreate 只会在第一次启动时执行。

IntentService

IntentService 适合处理一些短时间内的耗时操作,其将用户的请求执行在一个子线程(HandlerThread)中,用户只需重写 onHandleIntent() 方法,并在该方法内完成耗时操作的业务逻辑即可。任务执行完毕后,IntentService 会自行执行 stopSelf() 方法完成自我销毁。

前台 Service

相对于后台 Service 而言,前台 Service 具有更高的优先级,当内存不足时,前台 Service 能够拥有更高的活下去的机会。通过调用 Service 的方法 startForeground(),结合通知栏 Notification 完成前台 Service 的设置。

Service 保活机制

1 将 Service 设置为 START_STICKY,利用系统机制在 Service 挂掉后自动拉活;
2 通过 startForeground() 方法将 Service 切换为前台进程;
3 高频广播拉活:在发生特定系统事件时,系统会发出响应的广播,通过在 AndroidManifest 中“静态”注册对应的广播监听器,即可在发生响应事件时拉活;
4 通过 Native 层 fork 新的进程,监控主进程是否销毁并及时保活;
5 接入合作厂商特定推送 API、APP 互相拉活;

6 双进程 Service 互相拉活;
7 监控手机锁屏、解锁事件,在屏幕锁屏时启动1个像素的透明 Activity,在用户解锁时将 Activity 销毁掉,利用 Activity 的高优先级原理进行保活;
8 提升 Service 优先级(android:priority);
+∞ ... ...

三、BroadcastReceiver

Android Broadcast 是基于观察者模式设计的一种信息传输机制。

普通广播

sendBroadcast() 普通广播是异步的,并且所有的接收者都可能在不同的时间接收到广播,没有一定的顺序,广播不可控。广播可动态注册和静态注册,动态注册的广播,在任务完成后,需要在合适的时机及时注销广播的注册。

有序广播

sendOrderedBroadcast() 和普通广播不同,有序广播能够对广播进行控制。有序广播按照广播接收器的优先级(android:priority)顺序进行传递,广播接收器可通过 setResult() 方法将结果传递给下一个接收器,通过 getResult() 方法获取上一个广播接收器返回的结果。同时,可通过 abortBroadcast() 终止广播的传递,使得其他接收器不再接收该广播。

滞留广播

sendStickyBroadcast() 顾名思义,滞留广播会一直滞留,直到有匹配的广播接收器被注册,然后该接收器就会收到此条广播,值得注意的是,需要声明以下权限才会生效:

    

本地广播

LocalBroadcastManager 本地广播与普通广播无异,主要区别在于 Support v4 包中新增了 LocalBroadcastManager 类,用于发送只对该应用程序自身有效的本地广播,通过该类发送的广播不会被其他应用程序获取,有效提升了 App 安全。

四、ContentProvider

一个 ContentProvider 包含 schema、authority、path、id 等基本 Uri 信息。

ContentProvider 其实是对 SqliteOpenHelper 的再次封装,主要用于将当前 App 的数据共享给其他 App,实现跨进程数据共享。

ContentProvider 通过 UriMatcher 对 Uri 进行解析,确定对方需要进行数据操作的类型,构造关系映射,进而返回匹配的数据操作给对方,实现跨进程增删改查。

对方可通过 ContentResolver 进行数据的增删改查。

五、Intent 的匹配规则


    
        
        

        
        

        
    

显示调用和隐式调用

一般来说指定了显示调用就不必再定义隐式调用了,否则以显示调用优先。对于隐式调用而言,Intent 必须完全匹配其中一组 InterFilter 中的 action、category、data,才能匹配成功。

action 的匹配规则

系统中定义了一些 action,我们还可以自定义一些 action。action 严格区分大小写,Intent 中必须存在 action ,并且这个 action 在一组 IntentFilter 中出现才算匹配成功,否则匹配失败。只要 Intent 匹配 IntentFilter 中多个 action 中的其中一个即可,但是必须严格匹配所有 category 才算匹配成功。

category 的匹配规则

Intent 中的 action 只要其中一个在 IntentFilter 中出现即可匹配成功。但是,category 要求 Intent 中的 category 必须是 IntentFilter 中的子集,也就是说 Intent 中的所有 category 必须都在 IntentFilter 中出现才算匹配成功。

如果没有指定 category,系统会自动为 Intent 加上默认的 category:android.intent.category.DEFAULT,所以如果没有在 Intent 中指定 category,为了接收隐性 Intent 必须要加一个 android.intent.category.DEFAULT 在 IntentFilter 中。

data 的匹配规则

data 的匹配规则和 action 类似。如果未指定 scheme 或 host,那么整个 URI 无效,必须两者都指定,后面的 port、path 才有效。

本文由 Fynn_ 原创,未经许可,不得转载!

你可能感兴趣的:(Android 四大组件与 Intent)