Activity A
启动另外一个Activity B
,回调以下: Activity A 的onPause()
→ Activity B的onCreate()
→ onStart()
→ onResume()
→ Activity A的onStop()
; 若是B是透明主题又或则是个DialogActivity
,则不会回调A的onStop
;如何将一个 Activity 设置成窗口的样式? 只须要给咱们的 Activity 配置以下属性便可:
android:theme="@android:style/Theme.Dialog"
html
Activity 的 onSaveInstanceState() 和 onRestoreInstanceState()并非生命周期方法,它们不一样于 onCreate()、onPause()等生命周期方法,它们并不必定会被触发。java
lateinit var textView: TextView [注1]
var gameState: String? = null override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
gameState = savedInstanceState?.getString(GAME_STATE_KEY)
setContentView(R.layout.activity_main)
textView = findViewById(R.id.text_view)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
textView.text = savedInstanceState?.getString(TEXT_VIEW_KEY)
}
override fun onSaveInstanceState(outState: Bundle?) {
outState?.run {
putString(GAME_STATE_KEY, gameState)
putString(TEXT_VIEW_KEY, textView.text.toString())
}
super.onSaveInstanceState(outState)
}
复制代码
Koltin中属性在声明的同时也要求要被初始化,不然会报错。 例如如下代码:linux
private var name0: String //报错
private var name1: String = "xiaoming" //不报错
private var name2: String? = null //不报错
复制代码
但是有的时候,我并不想声明一个类型可空的对象,并且我也没办法在对象一声明的时候就为它初始化,那么这时就须要用到Kotlin提供的延迟初始化。 Kotlin中有两种延迟初始化的方式。一种是lateinit var,一种是by lazy。
android
LaunchMode | 说明 |
---|---|
standard | 系统在启动它的任务中建立 activity 的新实例 |
singleTop | 若是activity的实例已存在于当前任务的顶部,则系统经过调用其onNewIntent(),不然会建立新实例 |
singleTask | 系统建立新 task 并在 task 的根目录下实例化 activity。但若是 activity 的实例已存在于单独的任务中,则调用其 onNewIntent() 方法,其上面的实例会被移除栈。一次只能存在一个 activity 实例 |
singleInstance | 相同 singleTask,activity始终是其task的惟一成员; 任何由此开始的activity 都在一个单独的 task 中打开[注2] |
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
//step 1: 建立LoadedApk对象
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
... //component初始化过程
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//step 2: 建立Activity对象
Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
...
//step 3: 建立Application对象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
//step 4: 建立ContextImpl对象
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
//step5: 将Application/ContextImpl都attach到Activity对象
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor);
...
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
if (r.isPersistable()) {
//step 6: 执行回调onCreate
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart(); //执行回调onStart
r.stopped = false;
}
if (!r.activity.mFinished) {
//执行回调onRestoreInstanceState
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
...
r.paused = true;
mActivities.put(r.token, r);
}
return activity;
}
复制代码
Android instrumentation是Android系统里面的一套控制方法或者”钩子“。 这些钩子能够在正常的生命周期(正常是由操做系统控制的)以外控制Android控件的运行。 它们同时能够控制Android如何加载应用程序。git
Base class for implementing实现 application instrumentation code工具代码. When running with instrumentation turned on, this class will be instantiated for被实例化 you before any of the application code, allowing you to monitor all of the interaction交互 the system has with the application. An Instrumentation implementation is described to the system through an AndroidManifest.xml's tag.github
AMS是系统的引导服务,应用进程的启动、切换和调度、四大组件的启动和管理都须要AMS的支持。面试
ActivityStarter是加载Activity的控制类,收集全部的逻辑来决定如何将Intent和Flags转为Activity并将其与Task和Stack关联。算法
AMS 经过操做ActivityStackSupervisor来管理Activitysql
ActivityStack从名称来看是跟栈相关的类,其实它是一个管理类,用来管理系统全部Activity的各类状态。它由ActivityStackSupervisor来进行管理的,而ActivityStackSupervisor在AMS中的构造方法中被建立。数据库
它是ActivityThread的私有内部类,也是一个Binder对象。在此处它是做为IApplicationThread对象的server端等待client端 的请求而后进行处理,最大的client就是AMS.
能够在后台执行长时间运行操做而没有用户界面的应用组件
Service 分为两种工做状态,一种是启动状态,主要用于执行后台计算;另外一种是绑定状态,主要用于其余组件和 Service 的交互。
对于同一 app 来讲,默认状况下 Service 和 Activity 是在同一个线程中的,main Thread (UI Thread)。
一样 建议结合源码去看,这里给出调用链
@UnsupportedAppUsage
private void handleCreateService(CreateServiceData data) {
···
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
}
···
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
service.onCreate();
mServices.put(data.token, service);
try {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
···
}
复制代码
Proxying代理 implementation实现 of Context that simply简单的 delegates委托 all of its calls to another Context. Can be subclassed to归为 modify修改 behavior without changing the original Context.
ContextImpl做为Context的抽象类,实现了全部的方法,咱们常见的getResources(),getAssets(),getApplication()等等的具体实现都是在ContextImpl的
这块内容太多,好比能够看看这个 AMP/AMN/AMS AT/ATP/ATN
Zygote 是android系统应用中一个至关重要的进程,其主要功能是执行Android应用程序。在android系统中运行新的应用,须要跟Zygote进程(拥有应用程序运行时所须要的各类元素和条件)结合后才能执行。
Zygote进程运行时,会初始化Dalvik虚拟机,并启动它。android的应用程序是由java编写的,不能直接以本地进程的形态运行在linux上,只能运行在Dalvik虚拟机中。而且每一个应用程序都运行在各自的虚拟机中,应用程序每次运行都要从新初始化并启动虚拟机,这就至关耗时。在android中,应用程序运行前,Zygote进程经过共享已运行的虚拟机的代码与内存信息,缩短应用程序运行所耗费的时间。而且,它会事先将应用程序要使用的android Fromework中的类和资源加载到内存中,并组织造成所用资源的连接信息。新运行的 android 应用程序在使用所须要的资源时没必要每次从新造成资源的连接信息,这样提升程序运行速度。
在android中,使用Zygote进程的目的?对于手机,为了是应用程序在有限的资源型有更快的运行响应速度,提升资源利用率和设备使用时间。android使用Zygote来有效的减小系统负担,提升运行速度。
若是仅仅只是为了开启一个后台任务,那么可使用startService方法。
若是想获取Service中提供的代理对象,那么必须经过bindService方法,进行绑定服务。 使用场景好比:音乐播放器,第三方支付等。
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
···
if (s != null) {
try {
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try {
if (!data.rebind) {
IBinder binder = s.onBind(data.intent);
ActivityManager.getService().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
···
}
}
复制代码
值 | 说明 |
---|---|
START_NOT_STICKY | 若是系统在 onStartCommand() 返回后终止服务,则除非有挂起 Intent 要传递,不然系统不会重建服务。这是最安全的选项,能够避免在没必要要时以及应用可以轻松重启全部未完成的做业时运行服务 |
START_STICKY | 若是系统在 onStartCommand() 返回后终止服务,则会重建服务并调用 onStartCommand(),但不会从新传递最后一个 Intent。相反,除非有挂起 Intent 要启动服务(在这种状况下,将传递这些 Intent ),不然系统会经过空 Intent 调用 onStartCommand()。这适用于不执行命令、但无限期运行并等待做业的媒体播放器(或相似服务 |
START_REDELIVER_INTENT | 若是系统在 onStartCommand() 返回后终止服务,则会重建服务,并经过传递给服务的最后一个 Intent 调用 onStartCommand()。任何挂起 Intent 均依次传递。这适用于主动执行应该当即恢复的做业(例以下载文件)的服务 |
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
复制代码
Notification notification = new Notification(icon, text, System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, title, mmessage, pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
复制代码
IntentService是Service的子类,是一个异步的,会自动中止的服务,很好解决了传统的Service中处理完耗时操做忘记中止并销毁Service的问题
一种普遍运用在应用程序之间传输信息的机制,经过发送Intent来传送咱们的数据
内部通讯实现机制:经过android系统的Binder机制.
LocalBroadcastManager.getInstance(MainActivity.this).registerReceiver(receiver, filter);
复制代码
public class MyBroadCastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("MyBroadCastReceiver", "收到信息,内容是 : " + intent.getStringExtra("info") + "");
}
}
复制代码
<receiver android:name=".MyBroadCastReceiver">
<intent-filter>
<action android:name="myBroadcast.action.call"/>
</intent-filter>
</receiver>
复制代码
//onCreate建立广播接收者对象
mReceiver = new MyBroadCastReceiver();
//注册按钮
public void click(View view) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("myBroadcast.action.call");
registerReceiver(mReceiver, intentFilter);
}
复制代码
@Override
protected void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
复制代码
ContentProvider 管理对结构化数据集的访问。它们封装数据,并提供用于定义数据安全性的机制。 内容提供程序是链接一个进程中的数据与另外一个进程中运行的代码的标准界面。
ContentProvider 没法被用户感知,对于一个 ContentProvider 组件来讲,它的内部须要实现增删该查这四种操做,它的内部维持着一份数据集合,这个数据集合既能够是数据库实现,也能够是其余任何类型,如 List 和 Map,内部的 insert、delete、update、query 方法须要处理好线程同步,由于这几个方法是在 Binder 线程池中被调用的。
ContentProvider 经过 Binder 向其余组件乃至其余应用提供数据。当 ContentProvider 所在的进程启动时,ContentProvider 会同时启动并发布到 AMS 中,须要注意的是,这个时候 ContentProvider 的 onCreate 要先于 Application 的 onCreate 而执行。
// Queries the user dictionary and returns results
mCursor = getContentResolver().query(
UserDictionary.Words.CONTENT_URI, // The content URI of the words table
mProjection, // The columns to return for each row
mSelectionClause // Selection criteria
mSelectionArgs, // Selection criteria
mSortOrder); // The sort order for the returned rows
复制代码
public class Installer extends ContentProvider {
@Override
public boolean onCreate() {
return true;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
return null;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
}
复制代码
[🔥 面试必备:高频算法题汇总「图文解析 + 教学视频 + 范例代码」之 字符串处理+动态规划 合集!🔥 (juejin.im/post/5daad1…)
按期分享Android开发
湿货,追求文章幽默与深度
的完美统一。
仓库地址:超级干货!精心概括视频、归类、总结
,各位路过的老铁支持一下!给个 Star !