Android 的一个外围个性就是一个应用程序可作为其余应用程序中的元素,可为其余应用程序提供数据。例如,如果程序须要用某些控件来加载一些图片,另一个程序曾经开发出了此项性能,且可供其余程序应用,就能够间接应用跨过程通信形式调用那个程序的性能,而不是本人再开发一个。为了实现这样的性能,Android 零碎必须可能在须要应用程序中的任何一部分时启动它的过程,并且实例化那局部的 Java 对象。所以,不像大多数其余零碎中的程序,Android 程序不是只有繁多的进入点,而是它们领有零碎实例化和运行必须的组件,Android 中提供了 4 大组件;Android 中的四大组件除了 BroadcastReceiver 之外,Activity、Service、ContentProvider 都要必须在 AndroidManifest.xml 中注册,而 BroadcastReceiver 能够在 AndroidManifest.xml 文件中注册,也能够在 Java 代码或者 kotlin 代码中注册;在 Android 8.0 后,在 AndroidManifest.xml 文件中动态注册播送接管生效,是因为官网对耗电量的优化,防止 APP 滥用播送的一种解决形式。
1、Activity
Activty 是一种展现型组件,Activity 为用户提供了一个可视的用户界面。例如,一个拨打电话程序可能有一个 Activity 用来显示能够拨打电话的联系人,第二个 Activity 用来新建联系人写信息,其余的 Activity 用来查看具体的联系人,或者更改联系人信息,尽管应用程序中的各个 Activity 所提供的用户界面聚合性很强,然而每个 Activity 都独立于其余的 Activity,每一个实例化的 Activity 都是 Activity 的子类,Intent 可触发了 Activity 的启动,Intent 可分为显式 Intent 触发和隐式 Intent 触发;显式 Intent 触发可明确的指向 Activity 组件,用如下代码示意:
Intent in = new Intent(this,SecondActivity.class)
MainActivity.this.startActivity(in)
隐式 Intent 触发是指向一个或者 2 个以上的 Activity 的指标组件,它也能够没有指标 Activity,它的隐式触发用如下代码示意:
Intent intent = new Intent();
intent.setPackage("com.xe.launchmode");
intent.setAction("com.xe.actoin.MAP");
intent.addCategory("android.intent.category.APP_MAPS");
MainActivity.this.startActivity(intent);
2、Service
Service 是一种后盾解决工作型组件,它始终在后盾运行,用于后盾解决一系列的计算工作或者解决其余事件的时候播放背景音乐等,每个 service 都扩大自 Service 类;Service 组件和 Activity 组件的开启是不同的,Activity 只有一种启动状态,用如下代码示意:
Intent in = new Intent(this,SecondActivity.class)
startActivity(in)
而 Service 的开启却有 2 种,当处于启动状态时,它能够做一些后台任务,不须要和用户界面交互,它的生命周期和应用程序一样长,多媒体播放器播放音乐是利用 Service 的一个十分好的例子。多媒体播放器程序可能蕴含一个或者多个 Activity,用户通过这些 Activity 抉择并播放音乐。然而音乐回放并不需要一个 Activity 来解决,因为用户可能会心愿音乐始终播放上来,即便退出了播放器去执行其余应用程序也不进行。为了让音乐始终播放,多媒体播放器 Activity 可能会启动一个 Service 在后盾播放音乐。Android 零碎会使音乐回放 Service 始终运行,即便在启动这个 Service 的 Activity 退出之后。它的启动可用如下代码示意:
Intent in = new Intent(this,SecondActivity.class)
MainActivity.this.startService(in)
当它处于绑定状态时,它即能够做一些后台任务,也能够和用户界面做交互,它的生命周期和用户界面一样长,它的绑定可用如下代码示意:
ServiceConnection mBinderPoolConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) { }
@Override
public void onServiceDisconnected(ComponentName name) {}};
Intent intent = new Intent(mContext, MyService.class);
MainActivity.this.bindService(intent,new ServiceConnection(),Context.BIND_AUTO_CREATE);
以上 2 中开启,不论是哪一种都不能够间接在 Service 中做耗时操作,因为它是运行在主线程中的,如果非要做耗时操作,应该开一个工作线程给它去执行。
3、BroadcastReceiver
个别不执行任何工作,仅仅是接管并相应播送告诉一类的组件。大部分播送告诉是由零碎产生的,例如扭转时区、闹钟揭示、用户抉择了一幅图片或者用户扭转了语言首选项。应用程序同样也能够发送播送告诉,例如告诉其余应用程序某些数据曾经下载到设施上能够应用;一个应用程序的 BroadcastReceiver 来响应它的告诉,所有的 BroadcastReceiver 的实现类都扩大自 BroadcastReceiver 类。BroadcastReceiver 适宜用于不同的组件以及不同的过程之间进行通信,它是没有用户界面的,是因为它在零碎外部工作。上面介绍它的 2 种注册形式,首先是动态注册,它是在 AndroidManifest.xml 文件中实现的,装置利用时会被利用解析,不启动利用也能接管播送,用如下监听 wifi 状态扭转的代码示意:
<receiver android:name=".myapplication.receiver.WifiReceiver">
<intent-filter>
<action android:name="android.net.wifi.RSSI_CHANGED" />
<action android:name="android.net.wifi.STATE_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
从以上代码能够发现,接管过程的匹配是通过 <intent-filter> 来形容的,能够总结出播送是一个低耦合的观察者模式这样的论断。
另外一种形式就是动静注册,须要启动应用程序才能够接管到播送,是通过在 Java 代码中实现注册的,用如下代码示意它的动静注册:
public class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent){}}
MyBroadcastReceiver receiver = new MyBroadcastReceiver();
IntentFilter filter=new IntentFilter();
filter.addAction("com.xe.intent.action.ACTION_1");
filter.addAction("com.xe.intent.action.ACTION_2");
SecondActivity.this.registerReceiver(receiver,filter);
发送播送可用如下代码来实现:
Intent intent = new Intent();
intent.setAction("com.xe.intent.action.ACTION_2");
MainActivity.this.sendBroadcast(intent);
以上 2 种播送的注册形式中播送的接管是不能够做耗时操作的,因为接管播送的办法是在主线程中被调用的。
4、ContentProvider
ContentProvider 是一种共享数据型组件,应用程序能够通过 ContentProvider 来拜访其余应用程序的数据,包含其余应用程序的公有数据;和 Service 一样,它是没有用户界面的,它的外部须要实现 insert、update、delete 和 query 办法,它在外部应用一份数据汇合并且对数据汇合没有要求。ContentProvider 是跨过程通信的,当 Android 零碎收到一个需要某个组件进行解决的申请的时候,Android 会确保解决此申请的组件的宿主过程是否曾经在运行,如果没有,则立刻启动这个过程。ContentProvider 是提供一个内部接口 ContentResolver 给其余过程拜访数据的,上面一部分代码简略的示意 query 办法的应用过程:
Uri bookUri = Uri.parse("content://com.zyb.provider/data");
ContentResolver cr = ContentProviderActivity.this.getContentResolver();
Cursor bookCursor = cr.query(bookUri,new String[]{"_id","name"},null,null,null);
while (bookCursor.moveToNext()) {int id = bookCursor.getInt(0);
String name = bookCursor.getString(1);
}
以上代码,首先要创立要拜访数据的 Uri,而后通过应用程序获取 ContentResolver 接口,通过该接口获取数据汇合 Cursor 对象,最初通过 Cursor 对象查找索引获取到最终所需的数据。好了,本章内容就写到这里,因为自己技术无限,文章难免会呈现谬误,还望批评指正;前面我会找个工夫写一下 Android 四大组件工作过程的源码剖析,谢谢大家的浏览。