Android四大组件基本介绍及其生命周期

Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器。

Activity

应用程序中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。

生命周期

Activity栈:先进后出规则
Android四大组件基本介绍及其生命周期_第1张图片
例1:有3个Acitivity,分别用One,Two(透明的),Three表示,One是应用启动时的主Activity

  启动第一个界面Activity One时,它的次序是

         onCreate (ONE) - onStart (ONE) - onResume(ONE)

  点"打开透明Activity"按钮时,这时走的次序是

         onPause(ONE) - onCreate(TWO) - onStart(TWO) - onResume(TWO)

  再点back回到第一个界面,Two会被杀这时走的次序是

         onPause(TWO) - onActivityResult(ONE) - onResume(ONE) - onStop(TWO) - onDestroy(TWO)

  点"打开全屏Activity"按钮时,这时走的次序是

         onPause(ONE) - onCreate(Three) - onStart(Three) - onResume(Three) - onStop(ONE)

  再点back回到第一个界面,Three会被杀这时走的次序是

         onPause(Three) - onActivityResult(ONE) - onRestart(ONE) - onStart(ONE)- onResume(ONE) - onStop(Three) - onDestroy(Three)

  再点back退出应用时,它的次序是

         onPause(ONE) - onStop(ONE) - onDestroy(ONE)  

例2:横竖屏切换时候Activity的生命周期

onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->  

1. 不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
2. 设置Activity的android:configChanges=”orientation”时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
3. 设置Activity的android:configChanges=”orientation|keyboardHidden”时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法(最后)

onCreate(Bundle savedInstanceState)与onSaveInstanceState(Bundle savedInstanceState)配合使用,达到显示activity被系统杀死前的状态,见如下代码

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (null != savedInstanceState) {
            String _userid = savedInstanceState.getString("StrUserId");
            String _uid = savedInstanceState.getString("StrUid");
            String _serverid = savedInstanceState.getString("StrServerId");
            String _servername = savedInstanceState.getString("StrServerName");
            int _rate = savedInstanceState.getInt("StrRate");
            // updateUserId(_userid);
            // updateUId(_uid);
            // updateServerId(_serverid);
            // updateUserServer(_servername);
            // updateRate(_rate);
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putString("StrUserId", getUserId());
        savedInstanceState.putString("StrUid", getUId());
        savedInstanceState.putString("StrServerId", getServerId());
        savedInstanceState.putString("StrServerName", getServerName());
        savedInstanceState.putInt("StrRate", getRate());
    }

除了系统处于内存不足的原因会摧毁activity之外, 某些系统设置的改变也会导致activity的摧毁和重建. 例如改变屏幕方向(见上例), 改变设备语言设定, 键盘弹出等.

BroadcastReceive广播接收器

广播类型:

普通广播,通过Context.sendBroadcast(Intent myIntent)发送的

有序广播,通过Context.sendOrderedBroadcast(intent, receiverPermission)发送的,该方法第2个参数决定该广播的级别,级别数值是在 -1000 到 1000 之间 , 值越大 , 发送的优先级越高;广播接收者接收广播时的级别级别(可通过intentfilter中的priority进行设置设为2147483647时优先级最高),同级别接收的先后是随机的, 再到级别低的收到广播,高级别的或同级别先接收到广播的可以通过abortBroadcast()方法截断广播使其他的接收者无法收到该广播,还有其他构造函数:

异步广播,通过Context.sendStickyBroadcast(Intent myIntent)发送的,还有sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode, initialData, initialExtras)方法,该方法具有有序广播的特性也有异步广播的特性;发送异步广播要: 权限,接收并处理完Intent后,广播依然存在,直到你调用removeStickyBroadcast(intent)主动把它去掉。

监听广播Intent步骤:

  1. 写一个继承BroadCastReceiver的类,重写onReceive()方法,广播接收器仅在它执行这个方法时处于活跃状态。当onReceive()返回后,它即为失活状态,注意:为了保证用户交互过程的流畅,一些费时的操作要放到线程里
  2. 注册。

    1. 静态注册,AndroidManifest文件中进行注册的广播,下面的priority表示接收广播的级别”2147483647”为最高优先级

      <receiver android:name=".SMSBroadcastReceiver" >
          <intent-filter android:priority = "2147483647" >
          <action android:name="android.provider.Telephony.SMS_RECEIVED" />
          intent-filter>
      receiver >
    2. 动态注册,一般在Activity可交互时onResume()内注册BroadcastReceiver

      IntentFilter intentFilter=new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
      registerReceiver(mBatteryInfoReceiver ,intentFilter);
      
      //反注册
      unregisterReceiver(receiver);

注意:

  1. 生命周期只有十秒左右,如果在 onReceive() 内做超过十秒内的事情,就会报ANR(Application No Response) 程序无响应的错误信息,如果需要完成一项比较耗时的工作 , 应该通过发送 Intent 给 Service, 由Service 来完成 . 这里不能使用子线程来解决 , 因为 BroadcastReceiver 的生命周期很短 , 子线程可能还没有结束BroadcastReceiver 就先结束了 .BroadcastReceiver 一旦结束 , 此时 BroadcastReceiver 的所在进程很容易在系统需要内存时被优先杀死 , 因为它属于空进程 ( 没有任何活动组件的进程 ). 如果它的宿主进程被杀死 , 那么正在工作的子线程也会被杀死 . 所以采用子线程来解决是不可靠的

  2. 动态注册广播接收器还有一个特点,就是当用来注册的Activity关掉后,广播也就失效了。静态注册无需担忧广播接收器是否被关闭,只要设备是开启状态,广播接收器也是打开着的。也就是说哪怕app本身未启动,该app订阅的广播在触发时也会对它起作用

系统常见广播Intent,如开机启动、电池电量变化、时间改变等广播

BroadcastReceive广播接收器生命周期

生命周期只有十秒左右,如果在 onReceive() 内做超过十秒内的事情,就会报ANR(Application No Response) 程序无响应的错误信息,它的生命周期为从回调onReceive()方法开始到该方法返回结果后结束

Service服务

一个Service 是一段长生命周期的,没有用户界面的程序,可以用来开发如监控类程序。

启动方式:
1. 通过startService()方法启动的服务于调用者没有关系,即使调用者关闭了,服务仍然运行想停止服务要调用Context.stopService(),此时系统会调用onDestory(),使用此方法启动时,服务首次启动系统先调用服务的onCreate()–>onStart(),如果服务已经启动再次调用只会触发onStart()方法,onStart()方法会被多次调用

  1. 使用bindService()启动的服务与调用者绑定,只要调用者关闭,服务就终止,使用此方法启动时,服务首次启动系统先调用服务的onCreate()–>onBind(),如果服务已经启动再次调用不会再触发这2个方法,调用者退出时系统会调用服务的onUnbind()–>onDestory(),想主动解除绑定可使用Contex.unbindService(),系统依次调用onUnbind()–>onDestory()

Service服务生命周期

Android四大组件基本介绍及其生命周期_第2张图片
Service完整的生命周期:从调用onCreate()开始直到调用onDestroy()结束

Content Provider内容提供者

Android平台提供了Content Provider使一个应用程序的指定数据集提供给其他应用程序。

contentprovider中的Uri格式:结构头://authorities(域名)/路径(要操作的数据,根据业务而定)
例:content://com.test.provider.personprovider/person/10

要操作person表行号为10的记录(单条数据),可以这样构建/person/10,对应的MIME类型字符串应该为vnd.android.cursor.item/person"
要操作person表的所有记录(多条数据),可以这样构建/person,对应的MIME类型字符串应该为"vnd.android.cursor.dir/person"

在AndroidManifest.xml文件中注册

<provider android:name=".PersonProvider"
 android:authorities="com.test.provider.personprovider"/>

你可能感兴趣的:(Android)