1.Python 脚本收集 Activity 启动时间
2.Android源码阅读分析:ActivityManagerService分析(一)——启动流程
3.activity的启动启动生命周期和启动模式是什么?
4.Android Framework源码面试——Activity启动流程
5.Android Activity Deeplink启动来源获取源码分析
6.Android N å大ç»ä»¶çå·¥ä½åç
Python 脚本收集 Activity 启动时间
使用场景包括启动应用程序或其中的某个页面。
完整命令是源码原理:adb shell am start -W com.coral.aop/.hook.HookInstrumentationActivity
此命令通过adb执行手机中/system/bin目录下的shell脚本,而am命令则执行同目录下的启动启动am脚本文件。通过adb shell am ls /system/bin命令可列出该目录下所有脚本文件。源码原理其他命令请查阅官方adb命令文档。启动启动
查看am脚本内容:#!/system/bin/sh,源码原理apifox源码如果输入参数非"instrument",启动启动执行cmd activity "$@";否则将base设为/system,源码原理export CLASSPATH=$base/framework/am.jar,启动启动执行app_process $base/bin com.android.commands.am.Am "$@"。源码原理
该脚本主要通过app_process命令启动framework下的启动启动am.jar包中Am类入口的main()方法。确认该脚本功能需查看Framework底层源码,源码原理代码库可从GitHub下载。启动启动app_process主要启动zygote或Java程序,源码原理通过定位cmds/am/com/android/commands/am/Am.java,启动启动分析源码得知am start命令启动Activity。
总结,通过am start启动应用中的某个页面,最终通过AMS启动并管理Activity。am start -W命令启动应用后,终端输出参数含义如下:Starting:启动Activity的c文件编译源码Intent;Status:timeout或ok;Activity:启动的Activity(如果在onCreate销毁或crash则为下一个展示的Activity);ThisTime:表示一连串Activity的最后一个Activity的启动耗时;TotalTime:表示新应用启动耗时,包括新进程启动和Activity启动;WaitTime:总耗时,包括前一个应用Activity pause时间和新应用启动时间。
Android源码阅读分析:ActivityManagerService分析(一)——启动流程
本文深入解析了Android源码中的ActivityManagerService,即AMS的核心功能与启动流程。AMS作为管理Android四大组件的关键组件,其重要性不言而喻。本篇将从AMS的创建与启动逻辑开始分析,为理解其内部机制打下基础。
AMS的创建始于SystemServer的startBootstrapServices方法。此方法通过SystemServiceManager的startService方法启动Lifecycle类实例,从而创建AMS对象。Lifecycle作为适配器,连接了AMS与SystemService之间的交互。再通过Lifecycle的构造器,创建出AMS实例。
创建过程中,AMS线程、UI线程、CpuTracker线程和系统目录被初始化,同时StackSupervisor与ActivityStarter也得以创建,阳江旅行世界源码完成AMS对象的创建。
随后,ActivityManagerService的startService(SystemService)方法执行,完成服务的注册与启动。Lifecycle的onStart方法调用ActivityManagerService的start方法,启动关键操作。
在SystemServer的startBootstrapServices方法中,创建完AMS后,执行其setSystemProcess方法,为系统进程启动Application实例与服务注册。然后,SystemServer继续调用startBootstrapServices、startCoreServices与startOtherServices方法,启动更多系统服务与持久化进程,完成桌面Activity的启动与广播发布。
文中总结了AMS创建与启动的关键步骤,并预告后续文章将深入探讨AMS的具体使用、对四大组件的管理以及内存管理等内容。通过本篇解析,读者能更直观地理解Android系统中AMS的软件rsi源码公式核心功能与作用。
activity的生命周期和启动模式是什么?
本文深入探讨了Android中Activity的生命周期和启动模式,旨在帮助开发者更全面地理解这两个关键概念。
首先,让我们聚焦Activity的生命周期方法,这些方法在特定的事件触发时执行。在普通情况下,Activity生命周期的执行顺序通常遵循一个标准流程。当屏幕横竖屏切换时,Activity的生命周期会呈现不同的执行顺序。在横竖屏切换时,Activity先被销毁后重建,执行过程中涉及`onPause()`、`onSaveInstanceState()`、`onStart()`和`onRestoreInstanceState()`方法。在销毁时,`onSaveInstanceState()`被调用,开发者有机会保存需要恢复的信息。当Activity重建时,`onRestoreInstanceState()`接收在前一次执行时保存的信息,用于恢复必要的宜昌直播源码开发数据。
当系统内存不足导致低优先级的Activity被回收时,生命周期方法的执行顺序与横竖屏切换时相似,同样会执行`onSaveInstanceState()`和`onRestoreInstanceState()`方法,以确保数据的完整性和恢复性。
接下来,我们探讨Activity的四种启动模式,这些模式影响了Activity在任务栈中的行为。默认情况下,使用`ApplicationContext`启动`standard`模式的Activity会导致错误,因为此模式的Activity默认会进入启动它的Activity所属的任务栈,而非使用`Activity`类型的`Context`时的情况。解决这一问题的关键是通过指定`FLAG_ACTIVITY_NEW_TASK`标志在使用`ApplicationContext`启动Activity时,这样创建一个新栈以正确地启动Activity。
在理解了`singleInstance`和`singleTask`的区别之后,我们发现它们在启动行为上存在显著差异。`singleTask`模式允许在启动新的`Activity`时,如果目标`Activity`已经在栈中存在,则直接使用栈顶的实例,而不会重新创建新的实例。相比之下,`singleInstance`模式在启动Activity时会创建一个新的任务栈,并且在栈顶创建实例,确保每次启动时都是新实例。
本文最后推荐了由阿里高级架构师编写的《Android八大模块进阶资料》,该资料旨在帮助开发者系统化整理和掌握Android开发的知识点。资料以PDF文档的形式提供,包含由资深专家精心编写的笔记和源码解析合集、开源框架合集等内容。通过这套资料,开发者能够更深入地理解Android开发的各个方面,从而提高编程效率和代码质量。
Android Framework源码面试——Activity启动流程
面试官常问关于Activity启动模式的问题,但这涉及的知识点远不止四种模式。默认启动模式会因Intent Flag的设置而发生变化,面试时仅凭流程描述往往难以全面理解。
设置FLAG_ACTIVITY_NEW_TASK在Service中启动Activity时,Activity的启动行为会有所不同。不同场景下,Activity的启动表现各不相同。以singleInstance属性为例,即使设置了,使用Intent.FLAG_ACTIVITY_CLEAR_TASK启动时,并非完全遵循只复用实例的原则。
此外,不同Intent Flag的叠加使用也有各自的特性和表现。单一讨论启动模式的原理不易全面,理解需要结合实际项目、阅读源码或实验验证。
面试中,面试官可能会提出深入的、场景化的关于Activity启动的问题。例如,在Service中启动Activity时,FLAG_ACTIVITY_NEW_TASK的作用是什么?设置singleInstance后,使用FLAG_ACTIVITY_CLEAR_TASK启动时的行为如何?不同Intent Flag的组合使用又会产生哪些不同的结果?
理解这些知识点不仅需要对Android框架有深入的了解,还需要通过实践去验证和理解。比如,尝试在实际项目中使用不同的Intent Flag,观察Activity的启动行为,这样能更好地理解其背后的原理。
Android Activity Deeplink启动来源获取源码分析
Deeplink在业务模块中作为外部应用的入口提供,不同跳转类型可能会导致应用提供不一致的服务,通常通过反射调用Activity中的mReferrer字段获取跳转来源的包名。然而,mReferrer存在被伪造的风险,可能导致业务逻辑出错或经济损失。因此,我们需要深入分析mReferrer的来源,并寻找更为安全的获取方法。
为了深入了解mReferrer的来源,我们首先使用搜索功能在Activity类中查找mReferrer,发现其在Attach方法中进行赋值。进一步通过断点调试跟踪调用栈,发现Attach方法是由ActivityThread.performLaunchActivity调用的。而performLaunchActivity在调用Attach时,传入的referrer参数实际上是一个ActivityClientRecord对象的referrer属性。深入分析后,发现referrer是在ActivityClientRecord的构造函数中被赋值的。通过进一步的调试发现,ActivityClientRecord的实例化来自于LaunchActivityItem的mReferrer属性。接着,我们分析了mReferrer的来源,发现它最终是由ActivityStarter的setCallingPackage方法注入的。而这个setCallingPackage方法的调用者是ActivityTaskManagerService的startActivity方法,进一步追踪调用链路,我们发现其源头是在App进程中的ActivityTaskManager.getService()方法调用。
在分析了远程服务Binder调用的过程后,我们发现获取IActivityTaskManager.Stub的方法是ActivityTaskManager.getService()。这使得我们能够追踪到startActivity方法的调用,进而找到发起Deeplink的应用调用的具体位置。通过这个过程,我们确定了mReferrer实际上是通过Activity的getBasePackageName()方法获取的。
为了防止包名被伪造,我们注意到ActivityRecord中还包含PID和Uid。通过使用Uid结合包管理器的方法来获取对应的包名,可以避免包名被伪造。通过验证Uid的来源,我们发现Uid实际上是通过Binder.getCallingUid方法获取的,且Binder进程是无法被应用层干涉的,因此Uid是相对安全的。接下来,我们可以通过Uid来置换包名,进一步提高安全性。
总结,mReferrer容易被伪造,应谨慎使用。通过使用Uid来获取包名,可以提供一种更为安全的获取方式。此过程涉及对源代码的深入分析和调试,作者Chen Long为vivo互联网客户端团队成员。
Android N å大ç»ä»¶çå·¥ä½åç
æ¬æ侧é讲解android N ç³»ç»ä¸å大ç»ä»¶çå·¥ä½åçï¼ä¸åç³»ç»åçç¥æå·®å«ãéè¿åæå大ç»ä»¶çå·¥ä½æµç¨å 深对Android Frameworkçç解ï¼ä¹ä¸ºæ件åå¼åæä¸åºç¡ã
Activity
å±ç¤ºä¸ä¸ªçé¢å¹¶åç¨æ·äº¤äºï¼å®æ®æ¼çæ¯ä¸ä¸ªåå°çé¢çè§è²ã
Service
计ç®åç»ä»¶ï¼ç¨äºåå°æ§è¡ä¸ç³»å计ç®ä»»å¡ï¼å·¥ä½å¨ä¸»çº¿ç¨ï¼èæ¶æä½éè¦å¦èµ·çº¿ç¨ï¼ å为å¯å¨ç¶æåç»å®ç¶æã
BroadcastReceiver
æ¶æ¯åç»ä»¶ï¼ä¸»è¦ç¨äºä¸åç»ä»¶æè ä¸ååºç¨ä¹é´çæ¶æ¯ä¼ éï¼å®å·¥ä½å¨ç³»ç»å é¨ï¼ä¸éåæ§è¡èæ¶æä½ï¼æä½è¶ è¿5sï¼ä¼åºç°ANRã
ContentProvider
æ°æ®å ±äº«åç»ä»¶ï¼ç¨äºåå ¶ä»ç»ä»¶æè åºç¨å ±äº«æ°æ®ï¼ä¸»è¦æ§è¡CURDæä½ã
æ们å¯å¨ä¸ä¸ªactivityæ两ç§æ¹æ³ï¼
第ä¸ç§ï¼Activityç´æ¥å¯å¨æ¹å¼ï¼ï¼
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
第äºç§ï¼Contextå¯å¨æ¹å¼ï¼
Intent intent = new Intent(this, MainActivity.class);
getApplicationContext().startActivity(intent);
ä¸åçå¯å¨æ¹å¼Activityçå·¥ä½æµç¨æç¹å·®å«ã
两ç§å¯å¨é½ä¼è°ç¨å°Instrumentationç±»ä¸çexecStartActivityçæ¹æ³ï¼ç³»ç»æç»æ¯éè¿ActivityThreadä¸çperformLaunchActivityå®æActivityçå建åå¯å¨ã
performLaunchActivityæ¹æ³ä¸»è¦å®æ以ä¸å·¥ä½ï¼
1ãéè¿ActivityClientRecord对象è·åå¯å¨activityçç»ä»¶ä¿¡æ¯
2ãéè¿mInstrumentation对象çnewActivityæ¹æ³è°ç¨classloaderå®æactivityçå建
3ãéè¿r.packageInfo(LoadedApk 对象)çmakeApplicationæ¹æ³å°è¯å建Application对象
4ãå建ContextImpl对象并è°ç¨Activityçattachæ¹æ³å®æä¸äºæ°æ®çåå§å
5ãè°ç¨ActivityçonCreateæ¹æ³
å¨Activityå¯å¨çè¿ç¨ä¸ï¼Appè¿ç¨ä¼é¢ç¹å°ä¸AMSè¿ç¨è¿è¡éä¿¡ï¼
Appè¿ç¨ä¼å§æAMSè¿ç¨å®æActivityçå½å¨æç管ç以åä»»å¡æ ç管çï¼è¿ä¸ªéä¿¡è¿ç¨AMSæ¯Server端ï¼Appè¿ç¨éè¿ææAMSçclient代çIActivityManagerå®æéä¿¡è¿ç¨ï¼
AMSè¿ç¨å®æçå½å¨æ管ç以åä»»å¡æ 管çåï¼ä¼ææ§å¶æ交ç»Appè¿ç¨ï¼è®©Appè¿ç¨å®æActivity类对象çå建ï¼ä»¥åçå½å¨æåè°ï¼è¿ä¸ªéä¿¡è¿ç¨ä¹æ¯éè¿Binderå®æçï¼Appæå¨server端çBinder对象åå¨äºActivityThreadçå é¨ç±»ApplicationThreadï¼AMSæå¨clientéè¿ææIApplicationThreadç代ç对象å®æ对äºAppè¿ç¨çéä¿¡ã
Serviceæ两ç§å¯å¨æ¹å¼ï¼startService()åbindService()ï¼ä¸¤ç§ç¶æå¯ä»¥å¹¶å:
startServiceæµç¨
bindServiceæµç¨
BroadcastReceiverçå·¥ä½è¿ç¨ä¸»è¦å æ¬å¹¿æç注åãåéåæ¥æ¶:
å¨æ注åè¿ç¨ï¼
åéè¿ç¨
éæ注åæ¯ç±PackageManagerServiceï¼PMSï¼å¨åºç¨å®è£ çæ¶åå®ææ´ä¸ªæ³¨åè¿ç¨çï¼é¤å¹¿æ以å¤ï¼å ¶ä»ä¸å¤§ç»ä»¶ä¹é½æ¯å¨åºç¨å®è£ æ¶ç±PMS解æ并注åçã
æ¯ä¸ªè¿ç¨çå ¥å£é½æ¯ActivityThead.main()ï¼Appçå¯å¨æµç¨å¦ä¸ï¼
ä»æºç ä¸å¯ä»¥çåºï¼
åºç¨å¯å¨çå ¥å£ä¸ºActivityThreadçmainæ¹æ³ï¼mainæ¹æ³ä¼å建ActivityThreadå®ä¾å¹¶å建主线ç¨æ¶æ¯éåã
attachæ¹æ³ä¸è¿ç¨è°ç¨AMSçattachApplicationæ¹æ³ï¼å¹¶æä¾ApplicationThreadç¨äºåAMSçéä¿¡ã
attachApplicationæ¹æ³ä¼éè¿bindApplicationæ¹æ³åHæ¥è°åActivityThreadçhandleBindApplicationï¼è¿ä¸ªæ¹æ³ä¼å å建Applicationï¼åå è½½ContentProviderï¼ç¶åæä¼åè°ApplicationçonCreateæ¹æ³ã
ç±ä¸å¾å¯ä»¥çåºï¼å¨ContentProviderçå¯å¨è¿ç¨ä¸ä¼´éçappè¿ç¨çå¯å¨ã
ContentProviderçå ¶ä»CURDæä½å¦insertï¼deleteï¼updateè·queryçæµç¨ç±»ä¼¼ã
Activityçåºç¡ç¥è¯(ä¸)
ä¸ç¯æ»ç»äºActivityçä¸äºç¥è¯,ç°å¨ç»§ç»å¯¹Activityçç¥è¯è¿è¡æ¢³ç,å æ¬Activityç´æ¥ä¼ éæ°æ®,Activityççå½å¨æ,Activityçå¯å¨æ¨¡å¼ç.
1.intentä¼ éæ°æ®:
使ç¨startActivityæ¹æ³,intentçputExtra()æ¹æ³,以é®å¼å¯¹çå½¢å¼ä¼ éæ°æ®,该æ¹æ³æå¾å¤éè½½æ¹æ³,å¯ä»¥æ ¹æ®ä¼ éæ°æ®çä¸åç±»åéæ©åéçæ¹æ³.é¤äºæputExtra()æ¹æ³å¤,è¿æputExtras()æ¹æ³,ä¼ éçåæ°æ¯Bundle.
å¦æä¼ éçæ¯å¯¹è±¡,è¿ä¸ªå¯¹è±¡è¦å®ç°åºåå,ä¹å°±æ¯å®ç°Parcelableæè Serializableæ¥å£.
å¦æå¸æ被å¯å¨ç页é¢è¿åæ°æ®,éè¦ä½¿ç¨startActivityForResult()æ¹æ³,è¿ä¸ªæ¹æ³ä¸éè¦è®¾ç½®è®¿é®å·,ç¨æ¥åºåä¸åç访é®è .并ä¸å¨å¯å¨é¡µéåonActivityResultæ¹æ³ç¨æ¥æ¥æ¶è¿åçæ°æ®,
2.两ç§æ åµä¸çActivityççå½å¨æ.
æ£å¸¸æ åµä¸ççå½å¨æ,æ£å¸¸æ åµæ¯æç¨æ·çæ£å¸¸æä½ä¸çActivityççå½å¨æ.åé¢ä¼åæå¼å¸¸æ åµä¸ççå½å¨æ.
onCreate: Activity第ä¸æ¬¡å建æ¶åçåè°,主è¦æ¯å¨è¿ä¸ªæ¹æ³è¿è¡åå§åå·¥ä½,æ¯å¦åå§åæ§ä»¶åäºä»¶ç»å®å·¥ä½.
onStart:Activityä»ä¸å¯è§ç¶æåæå¯è§ç¶æ.
onResume:Activityåæåå°,å¯ä»¥åç¨æ·äº¤äº.
onPause:Activityå¯è§ä½æ¯ä¸è½åç¨æ·äº¤äº.
onStop:Activityä»å¯è§åå¾ä¸å¯è§,æ为åå°Activity.
onDestroy:Activityéæ¯æ¶è°ç¨.
onRestart:Activityä»åå°åæåå°Activity.
å¨å¯å¨Activityå两个Activityä¹é´è·³è½¬æ¶,å¯ä»¥ç¥éActivityççå½å¨æååè¿ç¨,æ两个说æ:(1)å¨ä¸¤ä¸ªActivity跳转æ¶,第ä¸ä¸ªActivtyçonPause,onStopæ¹æ³å第äºä¸ªActivityççå½å¨ææ¹æ³è°ç¨æ¶æº.
第ä¸ä¸ªActivityå æ§è¡onPauseæ¹æ³,第äºä¸ªActivityæè½å建.è¿ä¹å°±æå³çå¨onPauseæ¹æ³ä¸ä¸è½æ§è¡å¤ªèæ¶çæä½,å¦åä¼å½±å第äºä¸ªActivityçå建.å¨æºç (ActivityStack)ä¸æè¿æ ·ç注é:
(2)onStartåonResume,onPauseåonStopè¿ä¸¤å¯¹æ¹æ³çå®è´¨ä¸åå¤:onStartåonStopè¿ä¸¤ä¸ªæ¹æ³æ¯ä»Activityçå¯è§æ§æ¥åºåç,onResumeåonPauseæ¯ä»Activityæ¯å¦å¤äºåå°,æ¯å¦å¯ä»¥åç¨æ·äº¤äºæ¥åºåç,注æå¨onPauseè°ç¨æ¶Activityè¿æ¯å¯è§ç,è°ç¨æ¶æºæ¯å¦å¼¹åºdialogæ¶,ä¸é¢çActivityæ¯å¯è§ç.è¿ä¸ªæ¶åè°ç¨çæ¯onPauseæ¹æ³.
å¼å¸¸æ åµä¸Activityççå½å¨æ:å¼å¸¸æ åµä¸æ¯æèµæºç¸å ³é ç½®åçååæåå°Activity被系ç»åæ¶æ¶Activityççå½å¨æ.åå°Activity被系ç»åæ¶çæ åµæ¯è¾é¾å¤ç°,å¨èµæºç¸å ³é ç½®åçååæ¶ååå°Activity被åæ¶æ¶ççå½å¨ææ§è¡è¿ç¨æ¯ä¸æ ·ç,æ¯è¾å®¹æå¤ç°çå°±æ¯æ¨ªç«å±åæ¢æ¶ççå½å¨ææ§è¡è¿ç¨.å¨ AndroidManifestçActivityç»ä»¶ä¸é ç½®android:screenOrientationæ ç¾,å½è®¾ç½®å¯ä»¥æ¨ªç«æ¹åéçæ¹åæåºå¨æ¥è°èæ¶,å¨åæ¢æ¶ä¼åºç°å éæ¯Activityåå建çè¿ç¨.
è¿ç¨:
å¨è¿ç§æ åµä¸æå¯è½ä¼ææ°æ®ç丢失,ç³»ç»æä¾ç¨æ¥ä¿åæ°æ®åè¿åæ°æ®çæ¹æ³:onSaveInstanceStateåonRestoreInstanceState.ç¨æ¹æ³åæ°Bundleå¯ä»¥ä¿ååè¿åæ°æ®.
å¯ä»¥æ ¹æ®éè¦è®¾ç½®android:screenOrientationæ ç¾,设å®activityçæ¹å,å¦æactivityçæ¹åæ¯éè¦æ¨ªç«å±åæ¢,ä½æ¯ä¸å®¹è®¸éæ¯Activity,å¯ä»¥è®¾ç½®å¦ä¸æ ç¾,å½è¿äºæ åµ(常ç¨ç)åçååæ¯ä¸ä¼éæ°èµ°Activityççå½å¨ææ¹æ³,åªä¼è°ç¨onConfigurationChanged,å¯ä»¥æ ¹æ®æ åµå¨è¿ä¸ªæ¹æ³éæ´æ°æä½.
åæ¢æ¶çlogè¾åº
3.Activityçåç§å¯å¨æ¨¡å¼
æ å:æ¯Activityçé»è®¤å¯å¨æ¨¡å¼,对äºAndroidManifestçActivityèç¹ä¸çandroid:launchMode="standard"æ ç¾.
ç¹å®:æ¯æ¬¡å¯å¨é½ä¼éæ°å建æ°çActivity.
singleTop:对åºçAndroidManifesçActivityèç¹ä¸çandroid:launchMode="singleTop"æ ç¾
ç¹ç¹:å½æ¤æ¨¡å¼çActivityå¤äºæ 顶æ¶,ä¸ä¼éæ°å建æ°çActivity,ä¼è°ç¨onNewIntentæ¹æ³,å¦ææ´æ°Activityçintent,éè¦è°ç¨ setIntent()æ¹æ³,å ·ä½ççå½å¨æè¿ç¨
singleTask:å¨activityæ ä¸å·²ç»æéè¦åå¯å¨çactivityæ¶,ä¼å æ¸ é¤ä½äºéè¦å¯å¨activityä¹ä¸çactivity,ä¾å¦:å¯å¨é¡ºåºmainActivity-activityA -activityB-activityA,å ¶ä¸activityAæ¯singleTaskçå¯å¨æ¨¡å¼:
singleInstance:å¨ä¸ä¸ªæ ä¸åç¬åå¨çactivity.
å ³äºactivityæ :æ¯æç¨æ¥ç®¡çactivityä¸ç§"å è¿å åº"çéåç»æ,æ¥çactivity对åºæ çæ¹æ³:ActivityçgetTaskId()æ¹æ³,åä¸ä¸ªæ çidå¼æ¯ç¸åç.adb shell dumpsys activityå¨ç»ç«¯æ¥çæ ç»æ,æ¯å¦è¿æ¯ä¸é¢çactivityå¯å¨é¡ºåº,ä¸åæ¯ActivityAè¿æ¯è®¾ç½®æsingleInstance,è¿æ¯çæ ç»æ:æ两个TaskRecord,å ¶ä¸ActivityBåMainActivityä½äºåä¸ä¸ªæ ä¸.
4.Activityå¼åä¸ä½¿ç¨æå·§:
<1>å®ä¹ä¸ä¸ªç¶Activity,å¨å建æ°çActivityæ¶ç»§æ¿è¿ä¸ªactivityå³å¯,å°ä¸äºactivityçå ¬å ±è®¾ç½®å¯ä»¥è®¾ç½®å¨ç¶activityä¸,æ¯å¦è·åæ¯ä¸ªActivityçåå,设置activityççªä½å±æ§,åä¸ç®¡çactivityççå½å¨æç,
<2>å¨å¯å¨çactivityä¸å®ä¹éææ¹æ³,å¯å¨æ¡ä»¶ä¼æ¾èæè§:
<3>管çactivityç±»,ç¨æ¥ä¸é®éåºapp.å¨ç¶ç±»Activityçå建åéæ¯æ¶ç¨æ¥æ·»å å移é¤Activity,å¨éè¦ä¸é®éåºçå°æ¹è°ç¨éæfinishAllActivityæ¹æ³.
2024-11-29 00:12
2024-11-28 23:41
2024-11-28 23:28
2024-11-28 22:57
2024-11-28 22:52
2024-11-28 22:37