Android四大组件和启动模式

Android四大组件的生命周期、使用方法、ANR时间及四大启动模式的生命周期与使用场景


一、Android四大组件的生命周期、使用方法及ANR

1. Activity

Activity 是应用中最重要的组件之一,通常负责显示用户界面。每个Activity都对应着一个生命周期,开发者可以在生命周期的不同阶段执行相关操作,如初始化、释放资源等。

Activity的生命周期:

  • onCreate():Activity第一次创建时调用。在此方法中通常进行UI布局的初始化、数据的设置等。
  • onStart():当Activity对用户可见时调用,但此时它并没有获得焦点。
  • onResume():Activity获得焦点并开始与用户交互时调用,此时Activity处于前台。
  • onPause():当系统正在启动或恢复另一个Activity时,当前Activity失去焦点时调用。此时可以保存临时数据、释放资源等。
  • onStop():当Activity不再对用户可见时调用。此时Activity完全处于后台,可以进行资源的释放工作。
  • onRestart():当Activity从停止状态恢复时调用。通常用于恢复UI等。
  • onDestroy():当Activity销毁时调用。此时应释放资源,清理工作。

使用方法:

  • 启动Activity:可以通过startActivity()启动另一个Activity,通常还会携带数据:
    Intent intent = new Intent(this, TargetActivity.class);
    intent.putExtra("key", "value");
    startActivity(intent);
    
  • 返回数据:可以通过setResult()向调用的Activity返回结果,并通过onActivityResult()接收返回的数据。

ANR时间限制:

  • ANR(Application Not Responding) 是当应用在主线程上执行耗时操作(如网络请求、数据库操作、界面更新等)超过一定时间,Android系统会判定应用无响应,并弹出ANR对话框。通常,ANR的时间限制为 5秒(针对输入事件)和 10秒(针对广播接收器)。
  • 避免ANR:长时间的操作应该放到子线程中,避免阻塞主线程。可以使用AsyncTaskHandlerThreadIntentService等来进行后台操作。

2. Service

Service 是用于执行长时间运行的后台任务的组件,它没有用户界面,通常用于后台处理任务,如播放音乐、下载文件等。

Service的生命周期:

  • onCreate():Service第一次创建时调用,通常在此方法中初始化资源。
  • onStartCommand():每次调用startService()时,都会调用此方法。在此方法中执行后台任务。返回值决定Service如何重新启动:
    • START_STICKY:Service会在被杀死后重新启动。
    • START_NOT_STICKY:Service被杀死后不会重新启动。
    • START_REDELIVER_INTENT:Service被杀死后会重新启动,并传递最新的Intent。
  • onBind():当bindService()被调用时,执行此方法。返回一个IBinder对象,允许组件与Service进行通信。
  • onUnbind():当所有客户端都解绑时调用。
  • onDestroy():Service销毁时调用,用于清理资源和停止后台任务。

使用方法:

  • 启动Service
    Intent intent = new Intent(this, MyService.class);
    startService(intent);
    
  • 绑定Service
    Intent intent = new Intent(this, MyService.class);
    bindService(intent, connection, Context.BIND_AUTO_CREATE);
    

ANR时间限制:

  • ANR:在Service中进行网络请求、数据库操作等耗时操作时,如果没有在子线程中执行超过20S,就可能导致ANR。
  • 避免ANR:确保长时间运行的任务不会阻塞主线程,可以通过使用AsyncTaskExecutorService等将任务放到子线程中。

3. BroadcastReceiver

BroadcastReceiver 用于接收广播并响应它。广播可以是系统广播(例如电池电量变化、网络状态变化)或应用自定义广播。

BroadcastReceiver的生命周期:

  • onReceive():每当广播被接收时,onReceive()方法被调用。该方法在调用完成后立即结束,BroadcastReceiver会被销毁。因此,onReceive()中不应执行耗时操作。

使用方法:

  • 静态注册:通过在AndroidManifest.xml中声明广播接收器。
    <receiver android:name=".MyReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
    
  • 动态注册:通过registerReceiver()方法注册,在不需要时应调用unregisterReceiver()注销。
    IntentFilter filter = new IntentFilter("android.intent.action.BOOT_COMPLETED");
    registerReceiver(new MyReceiver(), filter);
    

ANR时间限制:

  • ANR:广播接收器的onReceive()方法如果执行时间超过 10秒,会导致ANR。因此,广播接收器中的代码应尽量避免耗时操作。
  • 避免ANR:对于耗时操作,应该通过HandlerAsyncTask等异步方式在后台执行,避免阻塞onReceive()

4. ContentProvider

ContentProvider 是用于不同应用之间共享数据的组件。通过ContentResolver,其他应用可以访问提供的数据。

ContentProvider的生命周期:

  • ContentProvider的生命周期由系统管理,通常在第一次访问时创建,并在不再使用时销毁。

使用方法:

  • 查询数据
    Uri uri = Uri.parse("content://com.example.provider/data");
    Cursor cursor = getContentResolver().query(uri, null, null, null, null);
    
  • 插入数据
    ContentValues values = new ContentValues();
    values.put("name", "John");
    Uri uri = getContentResolver().insert(uri, values);
    

ANR时间限制:

  • ANR:ContentProvider的查询、插入、更新等操作如果执行过慢,可能会导致ANR。特别是在进行数据库操作时,如果查询操作没有加速,就可能导致ANR。
  • 避免ANR:对于复杂的数据库查询或大规模数据的操作,建议使用异步查询或分批操作。

二、四大启动模式的生命周期与使用场景

Android提供了四种启动模式(StandardSingleTopSingleTaskSingleInstance),每种模式都会影响Activity的生命周期、任务栈以及启动时的行为。合理选择启动模式,可以帮助开发者避免冗余实例,提高内存利用效率和用户体验。

1. Standard(标准模式)

在标准模式下,每次调用startActivity()都会创建新的Activity实例,新的实例会被添加到任务栈的顶部。

生命周期:

  • 每次调用startActivity()都会触发onCreate()onStart()onResume()等方法。
  • 每个Activity都会创建一个新的实例,并且在任务栈中有独立的生命周期。

使用场景:

适用于每次需要创建一个新的Activity实例的场景,如新闻页面、列表页等。

注意点:

  • 可能导致内存占用过高,特别是在频繁切换界面时。
  • 如果没有合理管理Activity的堆栈,可能会导致栈中堆积大量实例。

2. SingleTop(单例模式)

当目标Activity已经位于栈顶时,系统不会创建新的实例,而是复用栈顶的Activity。如果目标Activity不在栈顶,则会创建新的实例。

生命周期:

  • 如果目标Activity在栈顶,onNewIntent()方法会被调用,而不是onCreate()
  • 如果目标Activity不在栈顶,创建新的实例。

使用场景:

适用于避免栈顶重复创建实例的场景,例如聊天界面、通知界面等。

注意点:

  • 如果目标Activity已经在栈顶,onCreate()不会被调用,只有onNewIntent()会被调用。
  • onNewIntent()方法中应该处理新的Intent数据。

3. SingleTask(单任务模式)

当启动一个SingleTask模式的Activity时,系统会查找该Activity是否已存在于任务栈中。如果存在,则会将

该Activity及其上面的Activity从栈中移除,并将目标Activity置于栈顶。

生命周期:

  • 如果目标Activity已存在,会调用onNewIntent(),并将目标Activity带到前台。
  • 如果目标Activity不存在,系统会创建新的实例。

使用场景:

适用于那些只需要一个实例的Activity,如登录页面、主页面等。

注意点:

  • 由于每次启动都会清除栈中上面的Activity,使用时需要谨慎处理栈内的状态。

4. SingleInstance(单实例模式)

SingleInstance模式下,Activity被放置在一个独立的任务栈中,且该栈中只会有一个实例。其他任何启动该Activity的请求都会复用该实例。

生命周期:

  • 只有一个实例,所有启动请求都会复用该实例。

使用场景:

适用于只有一个实例的全局Activity,例如某些全局控制界面。

注意点:

  • SingleInstance模式的Activity被放置在独立的任务栈中,和其他任务栈的Activity不会在同一栈中。使用时要注意栈之间的跳转与状态管理。

总结

理解Android四大组件的生命周期、使用方法以及ANR的时间限制,可以帮助开发者避免常见的性能问题和内存泄漏。合理选择四大启动模式,不仅能够优化内存管理,还能提升用户体验。在应用设计中,开发者需要根据实际需求来选择合适的启动模式和组件使用方式,以实现高效的任务管理和流畅的用户交互。

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

推荐阅读更多精彩内容