Android学习笔记-四大组件-基础知识1

        该部分主要记录ActivityServiceBroadcastReceiverContentProvider的基本知识和使用,关于高级部分后续将来不知道哪天的哪天可能或许会再写一篇文章来记录


Activity

        对于Activity的地位不再过多叙述,是一个应用向外界展示信息所必须的一个组件。

生命周期

经典的生命周期图

activity_lifecycle.png

关于各个周期:
onCreate()
Activity被创建时首先调用。
onStart()
Activity界面出现时。
onResume()
Activity被完全显示,可以与用户交互时。
onPause()
Activity失去焦点但仍对用户可见,如显示了一个弹窗。
onStop()
Activity被其他Activity完全遮挡,对用户不可见,如跳转到新的Activity或者退出程序,直接锁屏。
onDestory()
Activity被销毁时调用。
onRestart()
Activity对象再次被启动时调用。

  • 正常启动生命周期
    onCreate()->onStart()->onResume()->activity runing->onPause()->onStop()->onDestory()
  • 被遮挡但可见不可操作又取消遮挡
    onPause()->activity stop->onResume()->activity runing
  • 不可见变为可见
    onPause()->onStop()->activity stop->onRestart()->onStart()->onResume()->activity runing
    Activity示例代码

启动模式

  • standard
    标准模式。
    Activity默认的启动模式,Activity每次启动都会在栈顶创建一个新的Activity实例。
    如果Activity已经位于栈顶,则Activity启动时也将会重新创建新的实例。
  • singleTop
    栈顶复用模式。
    Activity启动时判断其是否在栈顶,如果在栈顶则直接复用,并且回调onNewIntent()方法,不会再重新创建新的Activity实例。
    如果未处于栈顶则重新创建新的Activity实例。
  • singleTask
    栈内复用模式。
    1.Activity被首次创建时首先检测AndroidManifest.xml中相应<activity />节点下的android:taskAffinity="..."属性是否存在,如果不存在则在启动该ActivityActivity所在的任务栈上新建该Activity,如果属性值存在并与某一任务栈相同则在该任务栈中新建该Activity,如果属性名与已存在的任务栈都不相同则新建与属性名相同的任务栈并新建该Activity
    2.Activity非首次创建启动时检测活动栈中是否已存在Activity实例,如果存在则直接复用并将其之上的所有Activity实例全部出栈,并且回调onNewIntent()方法,使该Activity处于栈顶的位置,如果不存在则在栈顶创建新的Activity实例。
  • singleInstance
    单实例模式。
    该模式下Activity会启动一个新的任务栈来管理Activity实例,当从其他任务栈中启动该Activity时,该Activity所在的任务栈,将会转移到前台。
    可以在不同的程序中共享一个Activity

异常状态

当系统资源配置发生改变或者内存不足时Activity会被杀死。

  • 系统配置发生改变
    系统配置发生改变Activity会被杀死重建,经典场景就是横竖屏切换的时候。
    此时的生命周期状态转换:
    onSaveInstanceState()->onStop()->onDestory()->onCreate()->onStart()->onRestoreInstanceState()->onResume()->activity runing
    这里出现了两个方法
    1.onSaveInstanceState()
    当Activity被异常状态下终止时会调用该方法来将Activity终止前的相关状态保存在Bundle中用来重建时恢复状态
    2.onRestoreInstanceState()
    当Activity被在异常状态下重建时回调该方法,该方法中的Bundle里保存了异常终止前Activity相关状态。
    此时可以通过在AndroidManifestl.xml文件中相应的activity节点下配置android:configChanges="orientation|keyboardHidden"属性来禁止相应的配置改变时activity的销毁重建。但是此时会回调Activity中的onConfigurationChanged()方法。
  • 系统内存不足
    当系统内存不足时,系统将会根据activity优先级的高低,优先杀死优先级低的Activity
    1.此时的生命周期:
    activity runing->onPause()->onStop()->onDestory()
    2.优先级:
    前台Activity>可见非前台Activity>后台Activity

上文代码


Service

Service 是一个可以在后台执行长时间运行操作而不提供用户界面的应用组件。服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。 此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信 (IPC)。 例如,服务可以处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序交互,而所有这一切均可在后台进行。

生命周期

service_lifecycle.png

由上图可知Service有两种生命周期,分别对应着Service的两种形式

Service形式

启动形式

        如果应用组件通过startService()方法来启动服务时,该服务即处于启动状态
        服务处于启动状态后将开始在后台无期限运行,组件被销毁也不会影响服务的运行状态。并且启动形式的服务与组件之间没有很大的关联并不会将服务结果返回给组件。如通过启动一个服务来下载网络资源。
        启动的服务可以在组件中通过stopService()或者在服务内部通过stopSelf()方法来停止服务。
onCreate()
服务首次被创建时,系统将会调用该方法来进行相关设置。该方法只有在服务被创建时调用,如果服务已在运行,则该方法不会调用。
onStartCommand()
组件通过调用startService()方法启动服务时,该方法将会被调用。该方法被调用后服务将会启动并将在后台无限期运行,并且需要调用stopService()或者stopSelf()方法来停止服务。每次调用startService()方法都会该方法都将会被调用。在绑定状态下不需要实现这个方法
onDestory()
当服务不再使用并将被销毁时,系统将调用该方法。来清理所有的资源,如线程、监听器、接收器等。
onBind()
无论启动服务还是绑定服务该方法必须实现。如果组件通过bindSercie()方法绑定服务,则系统将调用该方法,该方法的最后需要一个IBinder接口的实现类,用来供组件与服务进行通信。如果组件通过startService()方法来启动服务则该方法返回null

绑定形式

        如果应用组件通过bindService()方法绑定到服务时,该服务即处于绑定状态。组件与服务绑定后,绑定服务提供了一个客户端-服务器接口,允许组件与服务进行交互、发送请求、获取结果,甚至是利用进程间通信(IPC)跨进程执行这些操作。通俗来讲就是绑定服务后组件和服务就可以进行方法调用,增强两者之间的操作性。
        组件与服务绑定后,服务开始运行,一个服务可以绑定多个组件,当绑定形式的服务与任何一个组件都失去绑定后该服务会被销毁。
        绑定的服务可以在组件中通过stopService()或者在服务内部通过stopSelf()方法来停止服务。
onCreate()
服务首次被创建时,系统将会调用该方法来进行相关设置。该方法只有在服务被创建时调用,如果服务已在运行,则该方法不会调用。
onBind()
无论启动服务还是绑定服务该方法必须实现。如果组件通过bindSercie()方法绑定服务,则系统将调用该方法,该方法的最后需要一个IBinder接口的实现类,用来供组件与服务进行通信。如果组件通过startService()方法来启动服务则该方法返回null
onUnbind()
绑定状态的服务被销毁时调用
onDestory()
当服务不再使用并将被销毁时,系统将调用该方法。来清理所有的资源,如线程、监听器、接收器等。

  • 绑定形式生命周期
    onCreate()->onBind()->Service runing->onUnbind()->onDestroy()

1、扩展Binder类实现绑定服务

扩展Binder类绑定服务示例代码

2、使用AIDL来实现绑定服务

使用AIDL来绑定服务示例代码

启动服务与绑定服务之间的转换问题

一个服务可以同时是启动状态和绑定状态。但是系统只会为一个Service创建一个实例对象,所以启动服务和绑定服务操作的都是同一个Service实例,但是由于两者的执行顺序不同将会出现下列两种情况:

  • 先绑定服务后启动服务
    状态变化:绑定服务模式->启动服务模式
    绑定服务将会转换为启动服务运行,此时如果之前绑定服务的组件被销毁也不影响服务的运行。服务将会按照启动服务的模式运行。
  • 先启动服务后绑定服务
    状态变化:启动服务模式
    服务不会转换为绑定服务,仍然以启动服务模式运行。
    但是还是会与组件绑定,当与组件解除绑定之后,对服务无影响。

服务使用注意事项

注意:服务在其托管进程的主线程中运行,它既不创建自己的线程,也不在单独的进程中运行(除非另行指定)。 这意味着,如果服务将执行任何 CPU 密集型工作或阻止性操作(例如 MP3 播放或联网),则应在服务内创建新线程来完成这项工作。通过使用单独的线程,可以降低发生“应用无响应”(ANR) 错误的风险,而应用的主线程仍可继续专注于运行用户与 Activity 之间的交互。

由此可知服务是托管在进程的主线程中运行,所以如果服务要进行耗时或者阻塞性操作,则应该在服务内创建新的线程来完成工作。

  • 建议使用:IntentService
    IntentService是继承并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作

保证服务不被杀死

  • 因内存资源不足被杀死
    可将onStartCommand()方法的返回值设为START_STICKYSTART_REDELIVER_INTENT,该值表示服务在内存资源紧张时被杀死后,在内存资源足够时再恢复。
    也可将Service设置为前台服务,这样就有比较高的优先级,在内存资源紧张时也不会被杀掉。
  • 用户通过 settings -> Apps -> Running -> Stop 方式杀死Service
    该方法会执行Service的生命周期将会调用onDestory,所以可以在onDestory()中发送广播重新启动Service
    也可以开启两个服务,相互监听,相互启动。

onStartCommand返回值

  • START_STICKY
    返回此值时Service被系统kill后,系统将会尝试重新创建Service,并调用onStartCommand()方法,如果在此期间没有新的命令被传递到Service则参数Intentnull
  • START_NOTE_STICKY
    返回值为该值时,如果Service被系统kill则系统不会自动重启该服务
  • START_REDELIVEER_INTENT
    返回此值时,如果Service被系统kill杀死,系统将自动重启该服务,并重新传递Intent
  • START_STICKY_COMPATIBILITY
    START_STICKY的兼容版本并不保证kill后一定能重启
    系统默认返回START_STICKY

上文代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容