组件 | 描述 |
---|---|
Activity(活动) | 在应用中的一个Activity可以用来表示一个界面,意思可以理解为“活动”,即一个活动开始,代表 Activity组件启动,活动结束,代表一个Activity的生命周期结束。一个Android应用必须通过Activity来运行和启动,Activity的生命周期交给系统统一管理。 |
Service(服务) | Service它可以在后台执行长时间运行操作而没有用户界面的应用组件,不依赖任何用户界面,例如后台播放音乐,后台下载文件等。 |
Broadcast Receiver(广播接收器) | 一个用于接收广播信息,并做出对应处理的组件。比如我们常见的系统广播:通知时区改变、电量低、用户改变了语言选项等。 |
Content Provider(内容提供者) | 作为应用程序之间唯一的共享数据的途径,Content Provider主要的功能就是存储并检索数据以及向其他应用程序提供访问数据的接口。Android内置的许多数据都是使用Content Provider形式,供开发者调用的(如视频,音频,图片,通讯录等) |
1.activity的切换
<!---声明实现应用部分可视化界面的 Activity,必须使用 AndroidManifest 中的 <activity> 元素表示所有 Activity。系统不会识别和运行任何未进行声明的Activity。-----><activity android:label="@string/app_name" android:name="com.zj.wuaipojie.ui.MainActivity" android:exported="true"> <!--当前Activity是否可以被另一个Application的组件启动:true允许被启动;false不允许被启动--><!---指明这个activity可以以什么样的意图(intent)启动---><intent-filter> <!--表示activity作为一个什么动作启动,android.intent.action.MAIN表示作为主activity启动---><action android:name="android.intent.action.MAIN" /> <!--这是action元素的额外类别信息,android.intent.category.LAUNCHER表示这个activity为当前应用程序优先级最高的Activity--><category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.zj.wuaipojie.ui.ChallengeFirst" /><activity android:name="com.zj.wuaipojie.ui.ChallengeFifth" android:exported="true" /> <activity android:name="com.zj.wuaipojie.ui.ChallengeFourth" android:exported="true" /> <activity android:name="com.zj.wuaipojie.ui.ChallengeThird" android:exported="false" /> <activity android:name="com.zj.wuaipojie.ui.ChallengeSecond" android:exported="false" /> <activity android:name="com.zj.wuaipojie.ui.AdActivity" />
启动广告流程: 启动Activity->广告Activity->主页Activity
修改方法: 1.修改加载时间 2.Acitivity切换定位,修改Intent的Activity类名
switch (position) { case 0: Intent intent = new Intent(); intent.setClass(it.getContext(), ChallengeFirst.class); it.getContext().startActivity(intent); return; case 1: Intent intent2 = new Intent(); intent2.setClass(it.getContext(), ChallengeSecond.class); it.getContext().startActivity(intent2); return; case 2: Intent intent3 = new Intent(); //new一个Intent,intent3.setClass(it.getContext(), AdActivity.class); //传入要切换的Acitivity的类名it.getContext().startActivity(intent3); //启动对应的Activityreturn; case 3: Intent intent4 = new Intent(); intent4.setClass(it.getContext(), ChallengeFourth.class); it.getContext().startActivity(intent4); return; default: return; }
2.Activity生命周期
函数名称 | 描述 |
---|---|
onCreate() | 一个Activity启动后第一个被调用的函数,常用来在此方法中进行Activity的一些初始化操作。例如创建View,绑定数据,注册监听,加载参数等。 |
onStart() | 当Activity显示在屏幕上时,此方法被调用但此时还无法进行与用户的交互操作。 |
onResume() | 这个方法在onStart()之后调用,也就是在Activity准备好与用户进行交互的时候调用,此时的Activity一定位于Activity栈顶,处于运行状态。 |
onPause() | 这个方法是在系统准备去启动或者恢复另外一个Activity的时候调用,通常在这个方法中执行一些释放资源的方法,以及保存一些关键数据。 |
onStop() | 这个方法是在Activity完全不可见的时候调用的。 |
onDestroy() | 这个方法在Activity销毁之前调用,之后Activity的状态为销毁状态。 |
onRestart() | 当Activity从停止stop状态恢进入start状态时调用状态。 |
3.弹窗定位&堆栈分析
修改方法:
1.修改xml中的versiocode
2.Hook弹窗(推荐算法助手开启弹窗定位)
3.修改dex弹窗代码
4.抓包修改响应体(也可以路由器拦截)
4.布局优化
1.开发者助手抓布局
2.MT管理器xml搜索定位
3.修改xml代码
android:visibility="gone"
Activity生命周期:
一、如何创建Activity(活动)
1.Activity(活动)
2.新建一个类继承自Activity(活动)
二、Activity(活动)的声明周期从创建到销毁的过程所要执行的方法
1.创建Activity(活动)所要执行的方法 a.onCreate() 这个方法你已经看到过很多次了,每个活动中我们都重写了这个方法,它会在活动 第一次被创建的时候调用。你应该在这个方法中完成活动的初始化操作,比如说加载布 局、绑定事件等。 b.onStart() 这个方法在活动由不可见变为可见的时候调用。 c.onResume() 这个方法在活动准备好和用户进行交互的时候调用。此时的活动一定位于返回栈的 栈顶,并且处于运行状态。
2.Activity(活动)被销毁时所执行的方法 a.onPause() 这个方法在系统准备去启动或者恢复另一个活动的时候调用。我们通常会在这个方 法中将一些消耗 CPU 的资源释放掉,以及保存一些关键数据,但这个方法的执行速度 一定要快,不然会影响到新的栈顶活动的使用。 b.onStop() 这个方法在活动完全不可见的时候调用。它和 onPause()方法的主要区别在于,如 果启动的新活动是一个对话框式的活动,那么 onPause()方法会得到执行,而 onStop() 方法并不会执行。 c.onDestroy() 这个方法在活动被销毁之前调用,之后活动的状态将变为销毁状态。
3.onRestart() 这个方法在活动由停止状态变为运行状态之前调用,也就是活动被重新启动了。
三、生命周期的分类
- 完整生存期 活动在 onCreate()方法和 onDestroy()方法之间所经历的,就是完整生存期。一般情 况下,一个活动会在 onCreate()方法中完成各种初始化操作,而在 onDestroy()方法中完 成释放内存的操作。
- 可见生存期 活动在 onStart()方法和 onStop()方法之间所经历的,就是可见生存期。在可见生存 期内,活动对于用户总是可见的,即便有可能无法和用户进行交互。我们可以通过这两 个方法,合理地管理那些对用户可见的资源。比如在 onStart()方法中对资源进行加载, 而在 onStop()方法中对资源进行释放, 从而保证处于停止状态的活动不会占用过多内存。
- 前台生存期 活动在 onResume()方法和 onPause()方法之间所经历的,就是前台生存期。在前台 生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行相互的,我们平时 看到和接触最多的也这个状态下的活动。
四.活动的注册
Activity的四种启动方式:
一、Activity(活动)的管理模式 Android采用Task来管理多个Activity。当启动一个APP时,Android就会为之创建一个Task,然后每启动一个activity,则把当前的activity压到栈顶。比如以此启动页面A->B->C,栈里面的结构如下所示 C------栈顶 B A------栈底 按返回键的时候,从栈顶弹出页面依次为C->B->A
二、Activity(活动)的四种启动模式 1.standard模式 它是活动默认的启动模式,在不进行显示制定的情况下,所有活动都会自动使用这种启动模式。每次通过此模式来启动activity时,Android总会为目标activity启动一个新的实例。 举个例子:activity A为standard模式,activity B为standard模式,activity C为standard模式,从A->B->C依次启动activity: C为栈顶 B A为栈底 按返回键的时候,从栈顶弹出页面依次为C->B->A
2.singleTop模式 I.比如Activity B启动模式为singleTop,Activity A为standard,此时从A页面跳转B页面,A->B时,会先在栈中查看栈顶是否存在B,存在的话,则复用栈顶B,调用onNewIntent方法,而不是重新new一个新的B。如果栈中不存在B,则会创建B。 II.再继续从B页面跳转B页面的时候,及A->B->B时,因为栈顶已经存在B了,则直接复用栈顶的B,调用onNewIntent方法,此时栈如下所示: B------栈顶 A------栈底
补充:
onNewIntent()
是 Android 开发中的一个方法,当一个活动(Activity)已经在前台运行时接收到一个新的意图(Intent)时,该方法会被调用。通常情况下,这种情况发生在活动使用 FLAG_ACTIVITY_SINGLE_TOP
标志启动多次时。
这里是 onNewIntent()
方法的基本解释:
- 当一个活动已经在前台运行时,如果收到一个新的意图,Android 不会重新创建这个活动,而是调用
onNewIntent()
方法,并将新的意图传递给活动。 - 您可以在您的活动中重写
onNewIntent()
方法,根据需要处理新的意图。这使您可以根据新的意图更新活动的状态或执行任何必要的操作。
以下是一个示例,展示了如何在您的 Android 活动中使用 onNewIntent()
方法:
javaCopy code
@Override
protected void onNewIntent(Intent intent) {super.onNewIntent(intent);// 在这里处理新的意图String action = intent.getAction();if (action != null && action.equals("my_custom_action")) {// 根据自定义动作执行某些操作}
}
在这个示例中,如果活动接收到一个具有自定义动作 "my_custom_action"
的新意图,它会相应地执行一些特定的操作。
3.singleTask模式
singleTask
是 Android 活动(Activity)的启动模式之一,在清单文件(AndroidManifest.xml)中通过 android:launchMode="singleTask"
进行设置。当一个活动以 singleTask
模式启动时,系统会检查当前的任务栈中是否已经存在该活动的实例。如果存在,系统会将该任务栈移动到栈顶,并调用该活动的 onNewIntent()
方法,传递新的 Intent;如果不存在,系统会创建一个新的任务栈,并在其顶部放置该活动的实例。
使用这种加载模式的activity在同一个Task内只有一个实例,当系统采用此singleTask模式启动activity时,可以分为三种情况: a. 如果将要启动的activity不存在,系统将会创建目标activity实例,并将它加入到Task栈顶。 b.如果将要启动的activity已经位于Task栈顶,此时与singleTop模式的行为相同。 c. 如果将要启动的activity已经存在,但没有位于Task栈顶,系统将会把位于该activity上面的所有activity移出Task栈,从而使得目标activity转入栈顶。
模式的特点包括:
- 单一实例:在一个任务栈中只会存在一个该活动的实例。如果该活动已经存在于任务栈中,系统不会创建新的实例,而是调用已存在的实例。
- 任务栈位置:无论从何处启动该活动,它都会成为任务栈的根活动(Root Activity),并且该任务栈中的其他活动会被销毁。
- onNewIntent() 的调用:当活动已经存在且收到新的 Intent 时,系统会调用该活动的
onNewIntent()
方法来处理新的 Intent。 - 适用场景:适用于需要确保只有一个实例存在且可以接收全局 Intent 的情况,例如应用的主界面或者特定的处理程序。
要使用 singleTask
模式,只需在清单文件中声明活动时添加 android:launchMode="singleTask"
属性即可。
xmlCopy code
<activityandroid:name=".YourActivity"android:launchMode="singleTask">...
</activity>
需要注意的是,使用 singleTask
模式需要慎重考虑,因为它可能会导致应用的行为与用户预期不符。特别是在多任务栈的情况下,可能会产生意想不到的结果。因此,建议在了解其工作原理并明确适用场景后再使用该启动模式。
4.singleInstance模式 假设我们的程序中有一个活动是允许其他程序调用的,如果我们想实现其他程序和我们的程序可以共享这个活动的实例,应该如何实现呢?
使用前面三种启动模式肯定是做不到的,因为每个应用程序都会有自己的返回栈,同一个活动在不同的返回栈中入栈时必然是创建了新的实例。而使用singleInstance 模式就可以解决这个问题,在这种模式下会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,都共用的同一个返回栈,也就解决了共享活动实例的问题。 此加载模式下,无论从哪个Task中启动目标activity,只会创建一个目标activity实例,并会使用一个全新的Task栈来装载该activity实例。当系统采用singleInstance模式启动activity时
可以分为两种情况: a.如果将要启动的activity不存在,系统会先创建一个全新的Task、再创建目标activity的实例,并将它加入新的Task的栈顶。 b. 如果将要启动的activity已经存在,无论它位于哪个应用程序中,无论它位于哪个Task中,系统将会把该activity所在的Task转到前台,从而使用该activity显示出来。
补充:
singleInstance
通过在清单文件(AndroidManifest.xml)中设置 android:launchMode="singleInstance"
来定义。使用 singleInstance
模式启动的活动会在一个新的任务栈中启动,并且这个任务栈中只会包含该活动的一个实例。如果其他活动尝试启动具有 singleInstance
启动模式的活动,它们会被放置在不同的任务栈中。
singleInstance
模式的特点:
- 独立任务栈:使用
singleInstance
模式启动的活动会在一个新的任务栈中启动,该任务栈只包含这个活动的一个实例。 - 唯一实例:在整个系统中,只有一个该活动的实例存在。如果已经存在一个实例,系统会使用现有实例,并调用其
onNewIntent()
方法来传递新的 Intent;如果不存在,系统会创建一个新的任务栈并启动新的活动实例。 - 任务栈位置:无论从何处启动该活动,它都会成为新任务栈的根活动(Root Activity)。
- 适用场景:适用于需要确保只有一个实例存在,且该实例具有独立的任务栈的情况,例如应用中的全局服务或需要始终在特定环境中运行的活动。
要使用 singleInstance
模式,只需在清单文件中声明活动时添加 android:launchMode="singleInstance"
属性即可。
xmlCopy code
<activityandroid:name=".YourActivity"android:launchMode="singleInstance">...
</activity>
singleInstance
模式提供了一种强大的机制来管理活动的生命周期和任务栈。
Activity与Activity之间的传值
一、Activity的跳转方式 1.startActivity(intent) 2.startActivityForResult(intent,code)
二、Activity与Activity之间的数据传递(Intent(媒介)) 1.Intent概念 意思是一个Intent是对一个即将进行的操作的抽象,Intent的字面意识就是”意图”,Android应用程序中的三种其他应用程序基本组件——Activity, Service和Broadcast Receiver,都是使用称为intent的消息来”激活”的。
- 如果是两个相邻activity之间的传值,使用Intent传值
3.使用startActivityForResult(intent,code)实现回传值
补充:
在Android开发中,有多种方法可以在Activity之间传递数据:
-
Intent:可以使用Intent来传递数据。您可以将数据放入Intent的extras中,然后通过startActivity()启动另一个Activity。在目标Activity中,您可以使用getIntent()来获取传递的Intent,并使用getExtras()来检索数据。
发送数据:
javaCopy code Intent intent = new Intent(this, TargetActivity.class); intent.putExtra("key", value); // key为传递数据的标识符,value为要传递的数据 startActivity(intent);
接收数据:
javaCopy code Intent intent = getIntent(); if (intent != null) {String data = intent.getStringExtra("key");// 使用传递的数据 }
-
Bundle:类似于Intent,您可以在Intent中放入Bundle来传递数据。Bundle是一个键值对集合,可以存储各种数据类型。
发送数据:
javaCopy code Intent intent = new Intent(this, TargetActivity.class); Bundle bundle = new Bundle(); bundle.putString("key", value); // key为传递数据的标识符,value为要传递的数据 intent.putExtras(bundle); startActivity(intent);
接收数据:
javaCopy code Intent intent = getIntent(); Bundle bundle = intent.getExtras(); if (bundle != null) {String data = bundle.getString("key");// 使用传递的数据 }
-
静态变量:您可以使用静态变量在不同的Activity之间传递数据。这种方法简单直接,但需要注意内存泄漏和生命周期管理。
-
SharedPreferences:如果要在多个Activity之间共享数据,您可以使用SharedPreferences来保存数据。
-
数据库:如果要存储大量结构化数据,并且需要在多个Activity之间共享,您可以使用SQLite数据库或其他数据库解决方案。
选择使用哪种方法取决于您的具体需求和应用场景。通常来说,对于简单的数据传递,Intent或Bundle是最常用的方式。