Activity
- Activity的启动流程
正常手机到打开App的流程 :Launcher启动——>应用进程启动——>Application的启动——>Activity的启动。
Activity启动流程:
主要负责的类:
Instrumentation:负责调用Activity和Application生命周期。
ActivityTaskManagerService:负责Activity管理和调度等工作。(注:Android 10 新增)
ActivityManagerService:负责管理四大组件和进程,包括生命周期和状态切换。
ActivityTaskManagerInternal:ActivityTaskManagerService对外提供的一个抽象类,真正的实现在 ActivityTaskManagerService#LocalService。
ActivityThread:管理应用程序进程中主线程的执行。
ActivityStackSupervisor:负责所有Activity栈的管理。
TransactionExecutor:主要作用是执行ClientTransaction。
ClientLifecycleManager:生命周期的管理调用。
- 启动模式(四种)
Standard 标准模式(默认):每次启动一个Activity都会又一次创建一个新的实例入栈,无论这个实例是否存在。
SingleTop 栈顶复用模式:须要创建的Activity已经处于栈顶时,此时会直接复用栈顶的Activity。不会再创建新的Activity;若 须要创建的Activity不处于栈顶,此时会又一次创建一个新的Activity入栈,同Standard模式一样。
SingleTask 栈内复用模式:若须要创建的Activity已经处于栈中时,此时不会创建新的Activity,而是将存在栈中的Activity上 面的其他Activity所有销毁,使它成为栈顶。
SingleInstance 单实例模式(少用):SingleInstance比較特殊,是全局单例模式,是一种加强的SingleTask模式。它除了 具有它所有特性外,还加强了一点:具有此模式的Activity仅仅能单独位于一个任务栈中。
使用:
1、在 Manifest.xml中指定Activity启动模式
<activity android:name="..activity.MultiportActivity" android:launchMode="singleTask"/>
2、启动Activity时。在Intent中指定启动模式去创建Activity
Intent intent = new Intent();
intent.setClass(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
- 生命周期 (含onNewIntent())
官方的生命周期图
onNewIntent()是在配合SingleTask模式下使用的,当栈中的唯一Activity实例进入到onPause()或者onStop()后,在启动当前Activity时,执行函数onNewIntent()->onRestart()->onStart()->onResume()。
注意点:
1、内存吃紧的情况下,系统可能会kill掉后台运行的 Activity ,系统就会调用 onCreate 方法,而不调用 onNewIntent 方法, 解决方法就是在 onCreate 和 onNewIntent 方法中调用同一个处理数据的方法。
2、若没有在onNewIntent()里面设置setIntent(),则getIntent()获取的intent都只会是最初那个intent。(源码中的注释:Note that {@link #getIntent} still returns the original Intent. You * can use {@link #setIntent} to update it to this new Intent.)
- Activity与Window、View的关系
关系总图:
1、Window(抽象,具体实现是PhoneWindow) 是 Android 中窗口的宏观定义,主要是管理 View 的创建,以及与 ViewRootImpl的交互,将 Activity 与 View 解耦。
2、一个 Activity 对应一个 Window 也就是 PhoneWindow,一个 PhoneWindow 持有一个 DecorView 的实例(内部类),DecorView 本身是一个 FrameLayout。
3、所以在Activity中我们可以获取到WindowManager的实例,并实现对当前所有View的添加、更新、删除。
4、在Activity中通过setContentView所设置的布局文件其实就是被加到内容栏之中的,成为其唯一子View,就是上面的id为content的FrameLayout中,在代码中可以通过content来得到对应加载的布局。
//1、获取到DecorView中的ID为content的FrameLayout,即为我们自己设置的布局的父布局
ViewGroup content = (ViewGroup)findViewById(android.R.id.content);
//2、获取到自己的布局
ViewGroup rootView = (ViewGroup) content.getChildAt(0);
- 与Fragment的关系
Fragment由FragmentManager管理,受Activity控制,必须依赖于Activity。
Fragment的生命周期:
onAttach() -->onCreate() -->onCreateView() --->onActivityCreate() --->onStart() --->onResume() --->onPause() --->onStop() --->onDestroyView() --->onDestroy() --->onDetach();
Service
- Service的启动(两种startService和bindService)
两种启动方式的生命周期:
区别:
startService启动,service会一直无限期运行下去,只有外部调用了stopService()或stopSelf()方法时,该Service才会停止运行并销毁。
bindService启动,服务的生命周期与其绑定的client息息相关。当client销毁时,client会自动与Service解除绑定。也可以主动解除绑定。没有绑定后,Service会自动销毁。
- IPC(AIDL)、IntentService
1、Service分为本地服务Local Service和远程Service(区别在于是否和调用者运行在同一进程中)。
2、远程Service使用AIDL(Android Interface Definition Language,即Android接口定义语言)进行IPC(Inter-Process Communication,即跨进程通信)通信服务。(适用场景:多个应用程序共享同一个后台服务)。
3、在服务端声明远程服务的时候,按需看是否需要删除这个语句。(私有进程的意思)
android:process=":remote"
4、IntentService是继承了Service,使用方法与Service相同,不同之处在于IntentService内部自己维护了工作线程,可以操作耗时操作。在onHandleIntent()函数中执行耗时操作。
ContentProvider
ContentProvider的作用是为不同的应用之间数据共享,提供统一的接口。ContentProvider是个接口,通过实现它来实现对数据的增删改查。(到目前为止,没用过这个组件)
BroadcastRecevier
- 广播分类:静态、有序、本地、粘性(Android5.0开始已经弃用)。
有序广播:有序是相对于接收者而言的。(先接收者可以对广播进行截断)发送者:sendOrderedBroadcast(intent)即可。
系统广播:
- 本地广播LocalBroadcastRecevier的使用。
应用内广播,更加高效和安全。
用法:
接收方需要先注册好:
LocalBroadcastManager localBroadcastManager =
LocalBroadcastManager.getInstance(this);
IntentFilter intentFilter = new IntentFilter(CommConstant.LOCALBROADCASTNAME);
//注册本地广播监听器
//这里使用到的,可以使用成员变量
localBroadcastManager.registerReceiver(broadcastReceiver, intentFilter);
//回调函数
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//从intent中获取广播数据 执行需要的操作
}
};
发送方执行发送:
LocalBroadcastManager localBroadcastManager=
LocalBroadcastManager.getInstance(this);
Intent intent=new Intent(CommConstant.LOCALBROADCASTNAME);//这里要与上面注册的要一样
intent.putExtra(CommConstant.UPDATEBALANCE,balance);//发送数据
localBroadcastManager.sendBroadcast(intent);//发送本地广播