• android核心系列--1,组件生命周期


    一,进程模型及进程托管

    1,一个APP应用是由一个或多个组件构成的,这些组件可以运行在一个进程中,也可以分别运行在多个进程中;
    进程的构造和销毁是由系统全权负责的。
    2,一个应用进程只有一个应用环境对象,它在第一个应用进程的组件加载之前被构造,在应用进程中最后一个组件结束后销毁。
    3,组件可以通过 android:process = ":com.zy.tool.another"  将组件配置到指定的进程中,冒号开头表示这是一个私有进程,只有本应用的组件才能使用该进程。
    如果是小写字母开头表示是一个共享进程,那么其它应用的组件也可以使用该进程。
    所以说一个应用可以有一个或多个进程,即:可以有一个默认进程和多个附加进程。
    4,进程按优先级从高到低分为: 
    1)前台进程:有正在与用户交互的界面组件 或者 有服务组件和用户交互的界面组件绑定 或者 有服务组件的onCreate, onStart, onDestroy方法正在执行  或者  有前台服务组件
    或者 触发器组件的onReceive方法正在执行。
    2)可视进程:没有与用户交互的界面组件,但是界面组件可见,或者 有服务与用户可视的界面组件绑定。
    3)服务进程: 有服务在后台运行。
    4)后台进程:没有与用户交互的界面组件,并且也没有可见的界面组件,即整个app处于后台,并且没有正在运行的服务。
    5)空进程:该进程中没有任何组件在运行。
    进程优先级是在不断变化的,它随着进程中组件与用户交互状态的改变而改变。
     
    进程回收策略:
    1)按优先级从低到高回收。
    2)越近使用过的进程越晚回收。
     
    可能导致进程被回收的行为:
    1)界面组件被销毁。
    2)触发器执行完毕或者被注销。
    3)系统进入了待机状态。
     
    5 异常进程和无响应进程:
    1) 异常进程:系统会先保存进程中各个任务的界面组件栈中的内容,然后强行终止进程。然后重新构造新的应用进程,并将各个任务的组件栈恢复到异常前的状态。
    2)无响应进程:应用对用户的操作超过5秒仍未处理 或者 触发器的onReceive执行时间超过10秒。 此时会弹出对话框提示用户是终止进程还是继续等待。
     
    二,组件的生命周期:
    1,界面组件的生命周期:
    1)构造组件时先调用 onCreate方法,onStart()执行后进入可视状态。
    2)如果是恢复性构造(即界面组件是由系统回收的而非用户关闭的),那么onRestoreInstanceState()会被调用。
    3)onResume()执行后进入前台状态,可以与用户进行交互了。
    4)如果界面组件被系统回收,则会执行 onSaveInstanceState()方法。
    5)onPause()执行后界面组件进入可视状态。注意:如果是系统强制回收,则后面的两个方法可能来不及执行。
    6)onStop()执行后界面组件进入后台状态。
    7)  onDestroy() 执行后界面组件生命周期结束。

    2,服务组件生命周期:
    参考:
    a 深入浅出 Android核心组件(1):
    b Android组件系列,Android Service 深入解析:

    http://www.cnblogs.com/smyhvae/p/4070518.html

    1 )  Service默认是运行在主线程中的;Android中的后台指的是运行不依赖UI,即使APP关闭,只要进程还在,Service就可以继续运行。

    2)服务一旦启动后,就一直处于运行状态,只有调用stopService 或者 stopSelf 方法才会让服务停止下来。

    3)通过调用方式首次启动服务会执行 onCreate方法,然后执行 onStartCommand方法,如果服务没有停止,再次调用服务会直接执行 onStartCommand方法。

    4)服务的onStartCommand方法的返回值:

    a START_STICKY:  服务进程被kill后,后续如果资源运行系统会重新启动服务,并执行onStartCommand方法,但不会保留之前传送的Intent对象,除非有组件重新发送。

    例如音乐应用,返回这种值的服务要在适当的时候手动调用代码关闭服务。

    b START_REDELIVER_INTENT  系统会自动重启该服务,并会将Intent传入。重新发送后,flags参数的值会变成 Service.FLAG_START_REDELIVERY

    c START_NOT_STICKY: 服务被终止后就不会再启动。

    5)IntentServer 是一个异步的,会自动关闭的服务,它的 onHandleIntent方法是在单独的子线程中执行的,该服务每次只会启动一个线程来执行任务,多个任务会排成工作队列,顺序执行。 onHandleIntent执行完毕后服务会自动停止,即会调用 onDestroy方法。

    6)Service必须在没有和其它组件关联(调用unbindService方法),并且已经停止(调用stopService)的情况下才会被销毁(执行onDestroy方法),单独解除关联或者停止服务并不会销毁服务。

    7)绑定方式启动服务:bindService方法是异步的,被调用后会立即返回,并不会返回IBinder对象,要接收IBinder对象,必须要实现一个ServiceConnection实例,并将该实例传递给bindService方法,绑定成功后系统会先调用onBind方法,该方法的返回值就是一个IBinder对象,然后回调ServiceConnection的onServiceConnected方法,并将IBinder对象通过参数传递进来,然后我们就可以在该方法中调用IBinder的方法了。

    通过这种方式启动的服务,我们一般会在服务内部建立一个继承Binder的内部类,该内部类里面提供一些公共方法,用来向外公开服务的功能,当其它组件和服务建立关联后,就会通过得到的IBinder实例来调用服务的功能了。

    重复调用unbindService会引发异常,所以需要在程序里面做一些判断。

    8)started服务和bind服务的区别:(摘自:http://www.cnblogs.com/smyhvae/p/4070518.html 

    区别一:生命周期

    • 通过started方式的服务会一直运行在后台,需要由组件本身或外部组件来停止服务才会以结束运行

    • bind方式的服务,生命周期就要依赖绑定的组件

    区别二:参数传递

    • started服务可以给启动的服务对象传递参数,但无法获取服务中方法的返回值

    • bind服务可以给启动的服务对象传递参数,也可以通过绑定的业务对象获取返回结果

    实际开发中的技巧;

    • 第一次先使用started方式来启动一个服务

    • 之后可以使用bind的方式绑定服务,从而可以直接调用业务方法获取返回值

    9)Service生命周期图 :(摘自:http://www.cnblogs.com/smyhvae/p/4070518.html  

    10)使用bindService进行IPC通信的步骤:

    注意:触发器无法绑定服务。

    10.1)  在Android进行进程间通信,需要通过 IBinder/Binder 框架来实现,IBinder/Binder 接口就是Android远程对象的基本接口,描述与远程对象进行通信的协议(即如何调用远程对象,远程对象都有哪些功能)。

    AIDL 可以用于让某个Service与多个应用的组件进行跨进程通信,即实现了一个Service被多个应用共享的功能。一般用AIDL来描述需要被客户端调用的接口,它以.aidl 文件的形式存在,内部书写方式和普通java类的书写方式一样。注意:aidl文件只是起一个模板作用,真正起作用的是ADT根据aidl文件生成的那个.java文件。

    这个java文件会按照 aidl的描述生成一个继承自android.os.IInterface的接口A,接口A内部有一个静态抽象类 Stub,Stub类会继承 android.os.Binder类并实现接口A,

    Stub类内部还有一个内部静态类Proxy,Proxy也实现了接口A,Proxy内部有一个IBinder对象,这个Proxy就是实现真正的跨进程调用使用的。

    10.2)  新建一个类 AImpl ,这个类实现 A.Stub接口,这个AImpl就是业务对象。

    10.3)新建一个Service ,内部声明一个 AImpl类型的变量 mBinder,并且在 onBind方法中返回该变量。

    11)如果将Service的配置改为: android:process=":remote",那么界面组件和服务组件就会运行在不同的进程中,此时就不能直接绑定服务了,而只能通过IPC调用服务了。

    另外如果跨进程调用远程的Service,就需要使用隐式Intent了,无法使用显式Intent。并且如果A应用要调用B应用中的接口,需要将B应用中aidl文件原样拷贝到A应用中,包括包名。

    12)通过Messenger来实现IPC通信,底层依然使用的是AIDL,具体来说就是在调用端建立一个Messenger,并在绑定Service的时候将Messenger和Binder绑定(messenger = new Messenger(binder); ); 在被调用端的Service中,也新建一个Messenger,同时新建一个Handler,并让它和Messenger绑定(当消息来时让Handler来处理),然后在onBind方法中直接 return messenger.getBinder();  返回Binder,这样Messenger和Binder就绑定好了; 这样两个Messenger绑定到同一个Binder上了,就可以通信了,这种方式是线程安全的和同步方式执行的。

     

    3,触发器组件生命周期

    触发器组件的生命周期就是onReceive方法,该方法一执行完毕会立即被系统回收。

    onReceive方法执行时,触发器所在进程为前台进程。

    onReceive方法在主线程中执行,执行时长超过10秒会变为无响应进程,有被强制回收的风险。

    4,数据源组件生命周期

    数据源组件在被构造时,onCreate方法会被调用,而且一旦被构造就会一直存在,直到所在进程被回收。

    5,应用环境对象的生命周期

    与进程生命周期一样长,被构造时onCreate方法会被调用,被销毁时onTerminate方法会被调用(也可能不会调用)。 

     
     
     
  • 相关阅读:
    hdu 2665 划分树
    概率模型与条件随机场
    shell中各种括号的作用()、(())、[]、[[]]、{}
    今日BBC
    小贝_mysql主从复制作用以及案例
    c++ builder 版CreateAnonymousThread用法
    安卓UI适配限定符
    编译3.10内核 出现错误 “undefined reference to...." 解决方法
    iptables的4表5链(未完)
    已有iptables表的查看
  • 原文地址:https://www.cnblogs.com/imap/p/4166672.html
Copyright © 2020-2023  润新知