| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> Android点将台:颜值担当[-Activity-],腾讯T3大佬亲自讲解 -> 正文阅读 |
|
[移动开发]Android点将台:颜值担当[-Activity-],腾讯T3大佬亲自讲解 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IauVDY3x-1630139606963)(https://user-gold-cdn.xitu.io/2019/4/23/16a4a95c617de576?imageView2/0/w/1280/h/960/ignore-error/1)]
三、Activity间的数据传递[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7GfiFIRh-1630139606965)(https://user-gold-cdn.xitu.io/2019/4/23/16a4a95c616bac32?imageView2/0/w/1280/h/960/ignore-error/1)] 1.实体类:
|
默认 | 修改 |
---|---|
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VNv8QDE4-1630139606975)(https://user-gold-cdn.xitu.io/2019/4/23/16a4a95cba698d0a?imageView2/0/w/1280/h/960/format/png/ignore-error/1)]
|
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kbPXm5PF-1630139606976)(https://user-gold-cdn.xitu.io/2019/4/23/16a4a95cc5c4fb8d?imageView2/0/w/1280/h/960/format/png/ignore-error/1)]
|
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UQbS74YH-1630139606976)(https://user-gold-cdn.xitu.io/2019/4/23/16a4a95cee8f8430?imageView2/0/w/1280/h/960/ignore-error/1)]
/**
* 作者:张风捷特烈<br></br>
* 时间:2019/1/20/020:18:25<br></br>
* 邮箱:1981462002@qq.com<br></br>
* 说明:红色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);
}
}
/**
* 作者:张风捷特烈<br></br>
* 时间:2019/1/20/020:18:25<br></br>
* 邮箱:1981462002@qq.com<br></br>
* 说明:绿色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)
}
}
---->[open_enter.xml]----------------------
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<!--左移入-->
<translate
android:duration="500"
android:fromXDelta="100%p"
android:toXDelta="0%p"/>
</set>
---->[open_exit.xml]----------------------
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<!--左移出-->
<translate
android:duration="500"
android:fromXDelta="0%p"
android:toXDelta="-100%p"/>
</set>
---->[close_enter.xml----------------------
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<!--右移入-->
<translate
android:duration="500"
android:fromXDelta="-100%p"
android:toXDelta="0%p"/>
</set>
---->[close_exit.xml]----------------------
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator">
<!--右移出-->
<translate
android:duration="500"
android:fromXDelta="0%p"
android:toXDelta="100%p"/>
</set>
这样就可以了
另外
还可以配置动画的style用起来比在代码里方便些
<!--配置Activity进出动画-->
<style name="TranAnim_Activity" parent="@android:style/Animation.Activity">
<item name="android:activityOpenEnterAnimation">@anim/open_enter</item>
<item name="android:activityOpenExitAnimation">@anim/open_exit</item>
<item name="android:activityCloseEnterAnimation">@anim/close_enter</item>
<item name="android:activityCloseExitAnimation">@anim/close_exit</item>
</style>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowAnimationStyle">@style/TranAnim_Activity</item>
</style>
一直想总结一下Activity的启动流程(),这里从Activity的生命周期入手
本文所讲述的启动流程主要是ActivityThread的H在接收到消息之后,即handleMessage
至于消息如何传递过来的将在跨进程通信篇讲述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZjHXbjyU-1630139606977)(https://user-gold-cdn.xitu.io/2019/4/23/16a4a95c3ab40672?imageView2/0/w/1280/h/960/ignore-error/1)]
翻一下源码可以看出Context只是一个抽象类,定义了很多抽象方法
而ContextWrapper作为实现类将所有的工作甩手给了一个mBase的Context成员变量
ContextThemeWrapper寥寥百行代码,也不会是幕后黑手,现在台面上只有mBase
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-acmUEn7Z-1630139606977)(https://user-gold-cdn.xitu.io/2019/4/23/16a4a95d07838d7c?imageView2/0/w/1280/h/960/ignore-error/1)]
相信应该没有人去
new Activity()
,framework 层是如何创建Activity的实例呢?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q8iHsr8f-1630139606977)(https://user-gold-cdn.xitu.io/2019/4/23/16a4a95d1f384259?imageView2/0/w/1280/h/960/ignore-error/1)]
---->[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(r);
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();
}
实现移到刚才创建Activity的
performLaunchActivity
方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3aypjl6u-1630139606979)(https://user-gold-cdn.xitu.io/2019/4/23/16a4a95d040a5aab?imageView2/0/w/1280/h/960/ignore-error/1)]
---->[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
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bY0YIk7m-1630139606980)(https://user-gold-cdn.xitu.io/2019/4/23/16a4a95d2a035a70?imageView2/0/w/1280/h/960/ignore-error/1)]
---->[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幕后黑手出现了
ContextImpl appContext = ContextImpl.createActivityContext(
this, r.packageInfo, r.token, displayId, r.overrideConfig);
appContext.setOuterContext(activity);
Context baseContext = appContext;
final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
// For debugging purposes, if the activity's package name contains the value of
// the "debug.use-second-display" system property as a substring, then show
// its content on a secondary display if there is one.
String pkgName = SystemProperties.get("debug.second-display.pkg");
if (pkgName != null && !pkgName.isEmpty()
&& r.packageInfo.mPackageName.contains(pkgName)) {
for (int id : dm.getDisplayIds()) {
if (id != Display.DEFAULT_DISPLAY) {
Display display =
dm.getCompatibleDisplay(id, appContext.getDisplayAdjustments(id));
baseContext = appContext.createDisplayContext(display);
break;
}
}
}
return baseContext;
}
---->[ContextImpl#createActivityContext]-------
static ContextImpl createActivityContext(ActivityThread mainThread,
LoadedApk packageInfo, IBinder activityToken, int displayId,
Configuration overrideConfiguration) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
return new ContextImpl(null, mainThread, packageInfo, activityToken, null, 0,
null, overrideConfiguration, displayId);
}
---->[Instrumentation#callActivityOnCreate]-------
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}
---->[Activity#performCreate]-------
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
restoreHasCurrentPermissionRequest(icicle);
onCreate(icicle, persistentState);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
---->[Activity#attach]-----------------
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window) {
attachBaseContext(context);
mFragments.attachHost(null /*parent*/);
//这里的Window实现类是PhoneWindow
mWindow = new PhoneWindow(this, window);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
ead aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window) {
attachBaseContext(context);
mFragments.attachHost(null /*parent*/);
//这里的Window实现类是PhoneWindow
mWindow = new PhoneWindow(this, window);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 13:48:34- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |