2024年最全Android点将台:颜值担当[-Activity-](1),2024年最新快点来学吧

学习分享

①「Android面试真题解析大全」PDF完整高清版+②「Android面试知识体系」学习思维导图压缩包

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

2019-01-19 14:43:32.910 : DialogActivity–onStart:
2019-01-19 14:43:32.912 : DialogActivity–onResume:

3.2.DialogActivity返回键到LifeCycleActivity:

2019-01-19 14:44:45.771 : DialogActivity–onPause:
2019-01-19 14:44:45.812 : LifeCycleActivity–onResume:
2019-01-19 14:44:45.874 : DialogActivity–onStop:
2019-01-19 14:44:45.874 : DialogActivity–onDestroy:


4.LifeCycleActivity旋转屏幕(相当于关闭再开启):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2019-01-19 14:46:28.619 : LifeCycleActivity–onPause:
2019-01-19 14:46:28.639 : LifeCycleActivity–onStop:
2019-01-19 14:46:28.639 : LifeCycleActivity–onDestroy:
2019-01-19 14:46:28.743 : LifeCycleActivity–onCreate:
2019-01-19 14:46:28.744 : LifeCycleActivity–onStart:
2019-01-19 14:46:28.751 : LifeCycleActivity–onResume:

activity生命周期测试总览(电脑上查看原图效果最佳)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


5、保存数据:

onStop之前,会调用onSaveInstanceState 其中有一个Bundle对象可以用来储存数据
该对象便是onCreate中的Bundle对象savedInstanceState,下图旋转屏时使用onSaveInstanceState

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

override
fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.ac_lifecycle)
title = “LifeCycleActivity”
if (savedInstanceState != null) {
title = savedInstanceState.getString(“name”)
}
}

override fun onSaveInstanceState(outState: Bundle?) {
super.onSaveInstanceState(outState)
Log.e(TAG, "LifeCycleActivity–onSaveInstanceState: ")
}


二、生命周期方法解释:

之所谓生命周期,就是从生到死有明确的回调函数
函数在不同状态下由安卓框架层进行回调,简化开发流程。
让开发者使用时只需要关注Activity状态,根据状态构建逻辑,而无需深入底层实现。
Activity主要有7个生命周期回调函数,如下,是最经典的Activity生命周期图示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

创建:onCreate():
|—可用于初始化工作,如setContentView界面资源、初始化数据
启动:onStart():
|—可见但无法交互
恢复:onResume():
|—恢复播放动画、音乐、视频等
暂停:onPause():
|—可做数据存储、停止动画、音乐、视频等
停止:onStop():
|—此时Activity不可见,可做视情况做些重量级回收工作,避免被Killed
销毁:onDestroy():
|—回收工作、资源释放
重现:onRestart():
|—可做一些恢复工作


三、Activity间的数据传递

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.实体类:Person

/**

  • 作者:张风捷特烈
  • 时间:2018/4/26:12:13
  • 邮箱:1981462002@qq.com
  • 说明:简单实体Person
    */
    class Person(var name: String?, var age: Int) : Serializable {
    override fun toString(): String {
    return “Person{” +
    “name='” + name + ‘’'.toString() +
    “, age=” + age +
    ‘}’.toString()
    }
    }

2.传递基本数据类型、Serializable对象、Parcelable对象

注意Bundle不能传递过大数据

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

---->[FromActivity点击]-----------
id_btn_for_result.setOnClickListener {
val intent = Intent(this, ToActivity::class.java)
val bundle = Bundle()
bundle.putSerializable(“person”, Person(“form”, 24))
val bitmap = BitmapFactory.decodeResource(resources, R.mipmap.wall_a)
bundle.putParcelable(“bitmap”, bitmap)
intent.putExtra(“from”, bundle)
intent.putExtra(“title”, “张风捷特烈”)
startActivity(intent)

---->[ToActivity接收使用]-----------
val title = intent.getStringExtra(“title”)
if (title != null) {
this.title = title
}
val extra = intent.getBundleExtra(“from”)
if (extra != null) {
val from = extra.get(“person”) as Person
val icon = extra.get(“bitmap”) as Bitmap
id_tv_result.text = from.toString()
id_iv_icon.setImageBitmap(icon)
}


3.FromActivity使用startActivityForResult打开ToActivity接返回值

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

---->[FromActivity]-----------
companion object {
private const val DATA_CODE = 0x0001
}
//点击时
id_btn_for_result.setOnClickListener {
val intent = Intent(this, ToActivity::class.java)
startActivityForResult(intent, DATA_CODE)
}
//回调
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
when (requestCode) {
DATA_CODE -> if (resultCode == Activity.RESULT_OK) {
val dataFormTarget = data.getStringExtra(“data”)
val personData = data.getBundleExtra(“To”)
val person = personData.get(“person”) as Person
id_tv_result_back.text = (“dataFormTarget:” + dataFormTarget

  • “\nperson:” + person.toString())
    }
    }
    }

---->[ToActivity传递数据给FromActivity]-----------
private fun backWithData() {
val jt = Person(“捷特”, 24)
val intent = Intent()
intent.putExtra(“data”, “我是ToActivity的数据”)
val bundle = Bundle()
bundle.putSerializable(“person”, jt)
intent.putExtra(“To”, bundle)
setResult(Activity.RESULT_OK, intent)
}


4.打开图库并设置图片

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

//点击图片
id_iv_icon.setOnClickListener {
val intent = Intent(Intent.ACTION_PICK)
intent.type = “image/*”;
startActivityForResult(intent, 0)
}

//处理结果
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 0 && resultCode == Activity.RESULT_OK) {//成功
val selectedImage = data?.data ?: return
val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
val cursor = contentResolver.query(// 获取选择照片的数据视图
selectedImage, filePathColumn, null, null, null
)
cursor.moveToFirst()
// 从数据视图中获取已选择图片的路径
val columnIndex = cursor.getColumnIndex(filePathColumn[0])
val picturePath = cursor.getString(columnIndex)
cursor.close()
id_iv_icon.setImageBitmap(BitmapFactory.decodeFile(picturePath))
}
}


三、Activity的四种启动模式

Activity任务栈:Activity的活动序列

standard:标准栈
singleTop:顶复用栈
singleTask:对象唯一栈
singleInstance:单独实例栈


1.standard: 标准栈

当启动一个Activity,创建该Activity的新实例。入栈处于栈顶
测试:Activity1、2皆为standard

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

依次打开Activity1、2、2、1、2
E/TASK_ID: Activity1 Task id is 89
E/TASK_ID: Activity2 Task id is 89
E/TASK_ID: Activity2 Task id is 89
E/TASK_ID: Activity1 Task id is 89
E/TASK_ID: Activity2 Task id is 89
依次返回
E/TASK_ID: Activity2 销毁
E/TASK_ID: Activity1 销毁
E/TASK_ID: Activity2 销毁
E/TASK_ID: Activity2 销毁
E/TASK_ID: Activity1 销毁


2:singleTop模式:顶复用栈

在启动活动时若栈顶已经是该Activity,则直接使用它,不创建实例
测试:Activity1为standard, Activity2 为singleTop

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

依次打开Activity1、2、2、1、2
E/TASK_ID: Activity1 Task id is 82
E/TASK_ID: Activity2 Task id is 82
E/TASK_ID: Activity1 Task id is 82
E/TASK_ID: Activity2 Task id is 82
依次返回
E/TASK_ID: Activity2 销毁
E/TASK_ID: Activity1 销毁
E/TASK_ID: Activity2 销毁
E/TASK_ID: Activity1 销毁


3:singleTask模式:对象唯一栈

整个栈中没有相同的实例,两次相同实例之间的Activity会被杀死(够霸道,我喜欢)
测试:Activity1为standard, Activity2 为singleTask

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

依次打开Activity1、2、2、1、2
E/TASK_ID: Activity1 Task id is 94
E/TASK_ID: Activity2 Task id is 94
E/TASK_ID: Activity1 Task id is 94
E/TASK_ID: Activity1 销毁
依次返回
E/TASK_ID: Activity2 销毁
E/TASK_ID: Activity1 销毁


4:singleInstance 单独实例栈

启用一个新的活动栈来管理这个活动(够豪,够任性)
测试:Activity1为standard, Activity2 singleInstance

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

依次打开Activity1、2、2、1、2
E/TASK_ID: Activity1 Task id is 115
E/TASK_ID: Activity2 Task id is 116
E/TASK_ID: Activity1 Task id is 115
依次返回
E/TASK_ID: Activity2 销毁
E/TASK_ID: Activity1 销毁
E/TASK_ID: Activity1 销毁


注意一点:
singleTask模式和singleTop模式时,非第一次启动,不会调用onCreate方法!
但会走onNewIntent方法


四、Activity的跳转动画

这里只是简单的四个平移动画,需要的更酷炫的效果道理是一样的
关于动画的更多知识,这里不废话了,可详见:Android 动画 Animator 家族使用指南

默认修改
)

|

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

|


1.代码实现Activity跳转

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

/**

  • 作者:张风捷特烈
  • 时间:2019/1/20/020:18:25
  • 邮箱:1981462002@qq.com
  • 说明:红色Activity
    */
    class RedActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val view = View(this)
    view.setBackgroundColor(Color.RED)
    title = “RedActivity”
    view.setOnClickListener { v ->
    startActivity(Intent(this, BlueActivity::class.java))
    overridePendingTransition(R.anim.open_enter, R.anim.open_exit);
    }
    setContentView(view)
    }
    override fun onBackPressed() {
    super.onBackPressed()
    overridePendingTransition(R.anim.open_enter, R.anim.open_exit);
    }
    }

/**

  • 作者:张风捷特烈
  • 时间:2019/1/20/020:18:25
  • 邮箱:1981462002@qq.com
  • 说明:绿色Activity
    */
    class BlueActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val view = View(this)
    view.setBackgroundColor(Color.BLUE)
    title = “BlueActivity”
    view.setOnClickListener { v ->
    startActivity(Intent(this, RedActivity::class.java))
    overridePendingTransition(R.anim.close_enter, R.anim.close_exit)
    }
    setContentView(view)
    }
    override fun onBackPressed() {
    super.onBackPressed()//右移入—右移出
    overridePendingTransition(R.anim.close_enter, R.anim.close_exit)
    }
    }

2.跳转动画

---->[open_enter.xml]----------------------

<?xml version="1.0" encoding="utf-8"?>


---->[open_exit.xml]----------------------

<?xml version="1.0" encoding="utf-8"?>


---->[close_enter.xml----------------------

<?xml version="1.0" encoding="utf-8"?>


---->[close_exit.xml]----------------------

<?xml version="1.0" encoding="utf-8"?>


这样就可以了


3.另外还可以配置动画的style

用起来比在代码里方便些


五、Acticity的启动源码分析

一直想总结一下Activity的启动流程(),这里从Activity的生命周期入手
本文所讲述的启动流程主要是ActivityThread的H在接收到消息之后,即handleMessage
至于消息如何传递过来的将在跨进程通信篇讲述

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


1.谁是幕后黑手?

翻一下源码可以看出Context只是一个抽象类,定义了很多抽象方法
而ContextWrapper作为实现类将所有的工作甩手给了一个mBase的Context成员变量
ContextThemeWrapper寥寥百行代码,也不会是幕后黑手,现在台面上只有mBase

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


2.Activity是如何创建的?

相信应该没有人去new Activity(),framework 层是如何创建Activity的实例呢?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

---->[ActivityThread]-------
final H mH = new H();

---->[ActivityThread$H#handleMessage]-------
public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY: {//启动Activity
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, “activityStart”);
//r:记录Activity的一些描述信息
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
//通过r来获取包信息
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
//开启的核心方法(划重点)
handleLaunchActivity(r, null, “LAUNCH_ACTIVITY”);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

---->[ActivityThread#handleLaunchActivity]-------
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
//在这里返回来Activity的对象
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations®;
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
//略…
}

---->[ActivityThread#performLaunchActivity]-------
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//略…
ComponentName component = r.intent.getComponent();
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//此处可见是mInstrumentation创建的Activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
//略…
return activity;
}

---->[Instrumentation#newActivity]-------
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
//通过类加载器生成Activity实例
return (Activity)cl.loadClass(className).newInstance();
}


3.Application实例化及onCreate()方法调用

实现移到刚才创建Activity的performLaunchActivity方法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

---->[ActivityThread#performLaunchActivity]-------
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//略…
ComponentName component = r.intent.getComponent();
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
//略…
try {
//创建Activity之后通过ActivityClientRecord的packageInfo对象的makeApplication
//来创建Application,packageInfo是一个LoadedApk类的对象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
//略…
}

---->[LoadedApk#makeApplication]-------
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
//略…

try {
java.lang.ClassLoader cl = getClassLoader();
//略…
//这里ContextImpl出场了
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
//这里通过mInstrumentation的newApplication方法创建Application对象
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
//将创建的Application设置到appContext上
appContext.setOuterContext(app);
}
//略…
//mActivityThread将当前app加入mAllApplications列表中
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {
try {
//这时调用application的OnCreate方法
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!instrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()

  • ": " + e.toString(), e);
    }
    }
    }
    return app;
    }

---->[Instrumentation#newApplication]-------
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
//也是通过反射获取Application实例
return newApplication(cl.loadClass(className), context);
}

---->[Instrumentation#callApplicationOnCreate]-------
public void callApplicationOnCreate(Application app) {
app.onCreate();//直接调用onCreate onCreate
}


4.Activity的Context的创建及onCreate()方法的调用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

---->[ActivityThread#performLaunchActivity]-------
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
//Activity的一些配置信息
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "

  • r.activityInfo.name + " with config " + config);
    Window window = null;
    if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
    window = r.mPendingRemoveWindow;
    r.mPendingRemoveWindow = null;
    r.mPendingRemoveWindowManager = null;
    }
    //将Activity和window绑定
    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, window);

if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}

activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}

---->[ActivityThread#createBaseContextForActivity]-------
private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
//略…
//看这里appContext是ContextImpl类对象,Activity的Context幕后黑手出现了

最后

最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2019-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。

还有 高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,也可以分享给身边好友一起学习。

一起互勉~

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

state);
}

---->[ActivityThread#createBaseContextForActivity]-------
private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
//略…
//看这里appContext是ContextImpl类对象,Activity的Context幕后黑手出现了

最后

最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2019-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。

还有 高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,也可以分享给身边好友一起学习。

[外链图片转存中…(img-qmfZ2HWz-1715883866210)]

[外链图片转存中…(img-NoVSaW9s-1715883866210)]

一起互勉~

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 26
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值