-
-
[原创]安卓逆向之插件化技术学习
-
发表于: 2025-4-25 15:14 14826
-
从12年的概念提出,到16年的把花齐放,件化技术引领着Android技术的进步。
现在出现的flutter 等等 已经让插件化技术变得没那么重要
大型应用模块化拆分、按需加载功能、第三方服务集成
多开app,无需安装运行app的框架
我所了解到virtualapp,edxposed等等,可以说实现安卓app的多开,那时候我就想自己实现一个简单的demo,可以多开简单的app就够了。
于是开始了的安卓学习之旅,本以为学完了安卓基础,就可以自己完成开发,结果就只能望着android studio 发呆 ------原来这个是高级的开发知识。
继而开始了我的安卓源码学习之路。
读了很多教程与安卓开发的书籍才知道,要实现多开要先学会插件化开发
那我们一起进入这个旅程吧------------
源码基于 安卓12
从开发者熟悉的的startActivity开始
继续跟踪这个方法
然后就是startActivityForResult方法
主要的代码就是这个玩意了 :mInstrumentation.execStartActivity
这里就调用 ActivityTaskManager.getService().startActivity方法了 这里就开始 与 ams沟通
AMS 的内部就不记录了
后面会调用 ActivityThread的 H 对象 进行沟通
我查看了TransactionExecutor 的类
这里就进入
继续跟进
这里进行一个简单的总结
开发者常用的startActivity(Intent intent)
方法,实际上调用的是startActivity(Intent intent, Bundle options)
,将options
设为null
。
在startActivity(Intent intent, Bundle options)
方法中,会先处理与自动填充(Autofill)相关的逻辑。若满足特定条件,会在启动的 Activity 上应用自动填充恢复机制。之后,根据options
是否为null
,调用startActivityForResult(intent, -1, options)
或startActivityForResult(intent, -1)
方法 。
当mParent
为null
时,会调用mInstrumentation.execStartActivity
方法,并传入一系列参数,包括当前上下文、应用线程、Activity 令牌等。同时,如果启动请求需要结果(requestCode >= 0
),会标记mStartedActivity
为true
,以避免在结果返回前 Activity 闪烁。
当mParent
不为null
时,会调用mParent.startActivityFromChild
方法,同样会根据options
是否为null
进行不同的处理。
在mInstrumentation.execStartActivity
方法中,首先会处理ActivityMonitor
相关逻辑,检查是否有匹配的监视器并进行相应操作。
接着,通过ActivityTaskManager.getService().startActivity
方法与 Activity 管理服务(AMS)进行跨进程通信,将启动 Activity 的请求发送给 AMS。AMS 接收到请求后,会进行一系列系统层面的处理,如任务调度、Activity 栈管理等,不过网页中未详细记录 AMS 内部的处理过程。
AMS 处理完启动请求后,会通过 ActivityThread 的H
对象发送消息。H
类接收到EXECUTE_TRANSACTION
消息后,会调用mTransactionExecutor.execute(transaction)
方法。
performLifecycleSequence
方法根据不同的生命周期状态(如ON_CREATE
、ON_START
等),调用mTransactionHandler
相应的方法来处理 Activity 的生命周期转换。例如,在ON_CREATE
状态时,会调用mTransactionHandler.handleLaunchActivity
方法。
handleLaunchActivity
方法会进行一些准备工作,如取消垃圾回收任务、处理配置变更等,然后调用performLaunchActivity
方法来实际启动 Activity。
performLaunchActivity
方法负责创建 Activity 实例,首先获取 Activity 的相关信息,如ActivityInfo
、PackageInfo
等。接着,使用ClassLoader
加载 Activity 类,并通过mInstrumentation.newActivity
方法创建 Activity 实例。然后,创建应用上下文ContextImpl
,并将 Activity 与上下文、应用等进行关联。最后,调用mInstrumentation.callActivityOnCreate
方法,触发 Activity 的onCreate
方法,完成 Activity 的初始化。
我使用侵入式 hook ,这样才会显得我不专业,但也显得 我们的攻击方式很明确
欺上瞒下的思路。
与PathClassLoader不同,DexClassLoader支持从APK、JAR或ZIP文件中加载Dex文件,无需预装到系统
通过构造函数指定插件Dex路径、优化目录、父加载器等参数,实现动态加载:
双亲委派模型:优先通过父加载器加载类,避免重复加载。若未找到,则调用findClass
方法从Dex中解析类
Dex文件解析:Dex文件包含所有类的索引信息,通过DexPathList
将Dex转换为Element数组,逐个加载类
从这里可以了解到,要实现dex的加载 可以利用双亲委派机制,或者修改 dexClassloader的DexPathList
,我这里有两个思路:
思路一: 我觉得可以加载 dexclassloader 直接把 原来的dexclassloader的父亲classloader 修改为插件classloader 以链表的样子插入进去
思路二: 可以让直接 将插件dexclassloader 的DexPathList
copy到 程序的dexclassloader 的DexPathList
中去
这里 加载外部dex 结束
这里还有资源的加载 我写到另一个文章中去了
这里我出现的问题好多
比如 资源冲突等等
其实这里可以使用io重定向解决是比较好的方式 ,但是 楼主 为了简单省事,我的处理方案就是 提前加载so文件
这里 Service 的加载 与activity差不的,只不过 service 没有 生命周期,与ams交互 感觉就是走个形式,那这里 我也就走个形式 :
这样做 只能启动一个 service 因为会把之前的覆盖掉!
反正我也只是学习 涨涨见识 。 就这样无论吞枣的过去吧 哈哈。
后面还有 广播 内容提供者的插件化 这些 我了解原理了 就不写了
网络上还有一堆 好文 关于插件化的。
就这样, 劈里啪啦的代码一顿乱写,就把这个残疾版的玩具多开app写出来了。也是 对我半个月学习的总结吧。当然 这个项目写的很垃圾 完全不能与 网上大佬相比。
要提升 我的想法也很多,比如
加入 去签名的逻辑 我之前写的文章,
在 用io重定向将文件进行隔离,设置好activityThread类的对象 ,
这里 是我Vapp的项目地址 :
支持 安卓12 ,可以加载 安卓android studio 编写出来的小demo 实际测试 很多app都加载不了
5687
5688
/**
5689 * Same as {@link #startActivity(Intent, Bundle)} with no options
5690 * specified.
5691 *
5692 * @param intent The intent to start.
5693 *
5694 * @throws android.content.ActivityNotFoundException
5695 *
5696 * @see #startActivity(Intent, Bundle)
5697 * @see #startActivityForResult
5698 */
5699 @Override
5700
public
void
startActivity(Intent intent) {
5701
this
.startActivity(intent, null);
5702 }
5687
5688
/**
5689 * Same as {@link #startActivity(Intent, Bundle)} with no options
5690 * specified.
5691 *
5692 * @param intent The intent to start.
5693 *
5694 * @throws android.content.ActivityNotFoundException
5695 *
5696 * @see #startActivity(Intent, Bundle)
5697 * @see #startActivityForResult
5698 */
5699 @Override
5700
public
void
startActivity(Intent intent) {
5701
this
.startActivity(intent, null);
5702 }
5704
/**
5705 * Launch a new activity. You will not receive any information about when
5706 * the activity exits. This implementation overrides the base version,
5707 * providing information about
5708 * the activity performing the launch. Because of this additional
5709 * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not
5710 * required; if not specified, the new activity will be added to the
5711 * task of the caller.
5712 *
5713 * <p>This method throws {@link android.content.ActivityNotFoundException}
5714 * if there was no Activity found to run the given Intent.
5715 *
5716 * @param intent The intent to start.
5717 * @param options Additional options for how the Activity should be started.
5718 * See {@link android.content.Context#startActivity(Intent, Bundle)}
5719 * Context.startActivity(Intent, Bundle)} for more details.
5720 *
5721 * @throws android.content.ActivityNotFoundException
5722 *
5723 * @see #startActivity(Intent)
5724 * @see #startActivityForResult
5725 */
5726 @Override
5727
public
void
startActivity(Intent intent, @Nullable Bundle options) {
5728
if
(mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)
5729 && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY)) {
5730
if
(TextUtils.equals(getPackageName(),
5731 intent.resolveActivity(getPackageManager()).getPackageName())) {
5732
// Apply Autofill restore mechanism on the started activity by startActivity()
5733 final IBinder token =
5734 mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);
5735
// Remove restore ability from current activity
5736 mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);
5737 mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY);
5738
// Put restore token
5739 intent.putExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN, token);
5740 intent.putExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY,
true
);
5741 }
5742 }
5743
if
(options != null) {
5744 startActivityForResult(intent, -1, options);
5745 }
else
{
5746
// Note we want to go through this call for compatibility with
5747
// applications that may have overridden the method.
5748 startActivityForResult(intent, -1);
5749 }
5750 }
5704
/**
5705 * Launch a new activity. You will not receive any information about when
5706 * the activity exits. This implementation overrides the base version,
5707 * providing information about
5708 * the activity performing the launch. Because of this additional
5709 * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not
5710 * required; if not specified, the new activity will be added to the
5711 * task of the caller.
5712 *
5713 * <p>This method throws {@link android.content.ActivityNotFoundException}
5714 * if there was no Activity found to run the given Intent.
5715 *
5716 * @param intent The intent to start.
5717 * @param options Additional options for how the Activity should be started.
5718 * See {@link android.content.Context#startActivity(Intent, Bundle)}
5719 * Context.startActivity(Intent, Bundle)} for more details.
5720 *
5721 * @throws android.content.ActivityNotFoundException
5722 *
5723 * @see #startActivity(Intent)
5724 * @see #startActivityForResult
5725 */
5726 @Override
5727
public
void
startActivity(Intent intent, @Nullable Bundle options) {
5728
if
(mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)
5729 && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY)) {
5730
if
(TextUtils.equals(getPackageName(),
5731 intent.resolveActivity(getPackageManager()).getPackageName())) {
5732
// Apply Autofill restore mechanism on the started activity by startActivity()
5733 final IBinder token =
5734 mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);
5735
// Remove restore ability from current activity
5736 mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);
5737 mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY);
5738
// Put restore token
5739 intent.putExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN, token);
5740 intent.putExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY,
true
);
5741 }
5742 }
5743
if
(options != null) {
5744 startActivityForResult(intent, -1, options);
5745 }
else
{
5746
// Note we want to go through this call for compatibility with
5747
// applications that may have overridden the method.
5748 startActivityForResult(intent, -1);
5749 }
5750 }
public
void
startActivityForResult(@RequiresPermission Intent intent,
int
requestCode,
5400 @Nullable Bundle options) {
5401
if
(mParent == null) {
5402 options = transferSpringboardActivityOptions(options);
5403 Instrumentation.ActivityResult ar =
5404 mInstrumentation.execStartActivity(
5405
this
, mMainThread.getApplicationThread(), mToken,
this
,
5406 intent, requestCode, options);
5407
if
(ar != null) {
5408 mMainThread.sendActivityResult(
5409 mToken, mEmbeddedID, requestCode, ar.getResultCode(),
5410 ar.getResultData());
5411 }
5412
if
(requestCode >= 0) {
5413
// If this start is requesting a result, we can avoid making
5414
// the activity visible until the result is received. Setting
5415
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
5416
// activity hidden during this time, to avoid flickering.
5417
// This can only be done when a result is requested because
5418
// that guarantees we will get information back when the
5419
// activity is finished, no matter what happens to it.
5420 mStartedActivity =
true
;
5421 }
5422
5423 cancelInputsAndStartExitTransition(options);
5424
// TODO Consider clearing/flushing other event sources and events for child windows.
5425 }
else
{
5426
if
(options != null) {
5427 mParent.startActivityFromChild(
this
, intent, requestCode, options);
5428 }
else
{
5429
// Note we want to go through this method for compatibility with
5430
// existing applications that may have overridden it.
5431 mParent.startActivityFromChild(
this
, intent, requestCode);
5432 }
5433 }
5434 }
public
void
startActivityForResult(@RequiresPermission Intent intent,
int
requestCode,
5400 @Nullable Bundle options) {
5401
if
(mParent == null) {
5402 options = transferSpringboardActivityOptions(options);
5403 Instrumentation.ActivityResult ar =
5404 mInstrumentation.execStartActivity(
5405
this
, mMainThread.getApplicationThread(), mToken,
this
,
5406 intent, requestCode, options);
5407
if
(ar != null) {
5408 mMainThread.sendActivityResult(
5409 mToken, mEmbeddedID, requestCode, ar.getResultCode(),
5410 ar.getResultData());
5411 }
5412
if
(requestCode >= 0) {
5413
// If this start is requesting a result, we can avoid making
5414
// the activity visible until the result is received. Setting
5415
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
5416
// activity hidden during this time, to avoid flickering.
5417
// This can only be done when a result is requested because
5418
// that guarantees we will get information back when the
5419
// activity is finished, no matter what happens to it.
5420 mStartedActivity =
true
;
5421 }
5422
5423 cancelInputsAndStartExitTransition(options);
5424
// TODO Consider clearing/flushing other event sources and events for child windows.
5425 }
else
{
5426
if
(options != null) {
5427 mParent.startActivityFromChild(
this
, intent, requestCode, options);
5428 }
else
{
5429
// Note we want to go through this method for compatibility with
5430
// existing applications that may have overridden it.
5431 mParent.startActivityFromChild(
this
, intent, requestCode);
5432 }
5433 }
5434 }
1710
public
ActivityResult execStartActivity(
1711 Context who, IBinder contextThread, IBinder token, Activity target,
1712 Intent intent,
int
requestCode, Bundle options) {
1713 IApplicationThread whoThread = (IApplicationThread) contextThread;
1714 Uri referrer = target != null ? target.onProvideReferrer() : null;
1715
if
(referrer != null) {
1716 intent.putExtra(Intent.EXTRA_REFERRER, referrer);
1717 }
1718
if
(mActivityMonitors != null) {
1719 synchronized (mSync) {
1720 final
int
N = mActivityMonitors.size();
1721
for
(
int
i=0; i<N; i++) {
1722 final ActivityMonitor am = mActivityMonitors.get(i);
1723 ActivityResult result = null;
1724
if
(am.ignoreMatchingSpecificIntents()) {
1725 result = am.onStartActivity(intent);
1726 }
1727
if
(result != null) {
1728 am.mHits++;
1729
return
result;
1730 }
else
if
(am.match(who, null, intent)) {
1731 am.mHits++;
1732
if
(am.isBlocking()) {
1733
return
requestCode >= 0 ? am.getResult() : null;
1734 }
1735
break
;
1736 }
1737 }
1738 }
1739 }
1740
try
{
1741 intent.migrateExtraStreamToClipData(who);
1742 intent.prepareToLeaveProcess(who);
1743
int
result = ActivityTaskManager.getService().startActivity(whoThread,
1744 who.getOpPackageName(), who.getAttributionTag(), intent,
1745 intent.resolveTypeIfNeeded(who.getContentResolver()), token,
1746 target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
1747 checkStartActivityResult(result, intent);
1748 }
catch
(RemoteException e) {
1749
throw
new
RuntimeException(
"Failure from system"
, e);
1750 }
1751
return
null;
1752 }
1710
public
ActivityResult execStartActivity(
1711 Context who, IBinder contextThread, IBinder token, Activity target,
1712 Intent intent,
int
requestCode, Bundle options) {
1713 IApplicationThread whoThread = (IApplicationThread) contextThread;
1714 Uri referrer = target != null ? target.onProvideReferrer() : null;
1715
if
(referrer != null) {
1716 intent.putExtra(Intent.EXTRA_REFERRER, referrer);
1717 }
1718
if
(mActivityMonitors != null) {
1719 synchronized (mSync) {
1720 final
int
N = mActivityMonitors.size();
1721
for
(
int
i=0; i<N; i++) {
1722 final ActivityMonitor am = mActivityMonitors.get(i);
1723 ActivityResult result = null;
1724
if
(am.ignoreMatchingSpecificIntents()) {
1725 result = am.onStartActivity(intent);
1726 }
1727
if
(result != null) {
1728 am.mHits++;
1729
return
result;
1730 }
else
if
(am.match(who, null, intent)) {
1731 am.mHits++;
1732
if
(am.isBlocking()) {
1733
return
requestCode >= 0 ? am.getResult() : null;
1734 }
1735
break
;
1736 }
1737 }
1738 }
1739 }
1740
try
{
1741 intent.migrateExtraStreamToClipData(who);
1742 intent.prepareToLeaveProcess(who);
1743
int
result = ActivityTaskManager.getService().startActivity(whoThread,
1744 who.getOpPackageName(), who.getAttributionTag(), intent,
1745 intent.resolveTypeIfNeeded(who.getContentResolver()), token,
1746 target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
1747 checkStartActivityResult(result, intent);
1748 }
catch
(RemoteException e) {
1749
throw
new
RuntimeException(
"Failure from system"
, e);
1750 }
1751
return
null;
1752 }
@Override
public
void
scheduleTransaction(ClientTransaction transaction) {
mH.sendMessage(H.EXECUTE_TRANSACTION, transaction);
// 发送消息到应用进程
}
@Override
public
void
scheduleTransaction(ClientTransaction transaction) {
mH.sendMessage(H.EXECUTE_TRANSACTION, transaction);
// 发送消息到应用进程
}
case
EXECUTE_TRANSACTION:
2213 final ClientTransaction transaction = (ClientTransaction) msg.obj;
2214 mTransactionExecutor.execute(transaction);
2215
if
(isSystem()) {
2216
// Client transactions inside system process are recycled on the client side
2217
// instead of ClientLifecycleManager to avoid being cleared before this
2218
// message is handled.
2219 transaction.recycle();
2220 }
2221
// TODO(lifecycler): Recycle locally scheduled transactions.
case
EXECUTE_TRANSACTION:
2213 final ClientTransaction transaction = (ClientTransaction) msg.obj;
2214 mTransactionExecutor.execute(transaction);
2215
if
(isSystem()) {
2216
// Client transactions inside system process are recycled on the client side
2217
// instead of ClientLifecycleManager to avoid being cleared before this
2218
// message is handled.
2219 transaction.recycle();
2220 }
2221
// TODO(lifecycler): Recycle locally scheduled transactions.
/** Transition the client through previously initialized state sequence. */
205
private
void
performLifecycleSequence(ActivityClientRecord r, IntArray path,
206 ClientTransaction transaction) {
207 final
int
size = path.size();
208
for
(
int
i = 0, state; i < size; i++) {
209 state = path.get(i);
210
if
(DEBUG_RESOLVER) {
211 Slog.d(TAG, tId(transaction) +
"Transitioning activity: "
212 + getShortActivityName(r.token, mTransactionHandler)
213 +
" to state: "
+ getStateName(state));
214 }
215
switch
(state) {
216
case
ON_CREATE:
217 mTransactionHandler.handleLaunchActivity(r, mPendingActions,
218 null
/* customIntent */
);
219
break
;
220
case
ON_START:
221 mTransactionHandler.handleStartActivity(r, mPendingActions,
222 null
/* activityOptions */
);
223
break
;
224
case
ON_RESUME:
225 mTransactionHandler.handleResumeActivity(r,
false
/* finalStateRequest */
,
226 r.isForward,
"LIFECYCLER_RESUME_ACTIVITY"
);
227
break
;
228
case
ON_PAUSE:
229 mTransactionHandler.handlePauseActivity(r,
false
/* finished */
,
230
false
/* userLeaving */
, 0
/* configChanges */
, mPendingActions,
231
"LIFECYCLER_PAUSE_ACTIVITY"
);
232
break
;
233
case
ON_STOP:
234 mTransactionHandler.handleStopActivity(r, 0
/* configChanges */
,
235 mPendingActions,
false
/* finalStateRequest */
,
236
"LIFECYCLER_STOP_ACTIVITY"
);
237
break
;
238
case
ON_DESTROY:
239 mTransactionHandler.handleDestroyActivity(r,
false
/* finishing */
,
240 0
/* configChanges */
,
false
/* getNonConfigInstance */
,
241
"performLifecycleSequence. cycling to:"
+ path.get(size - 1));
242
break
;
243
case
ON_RESTART:
244 mTransactionHandler.performRestartActivity(r,
false
/* start */
);
245
break
;
246
default
:
247
throw
new
IllegalArgumentException(
"Unexpected lifecycle state: "
+ state);
248 }
249 }
250 }
/** Transition the client through previously initialized state sequence. */
205
private
void
performLifecycleSequence(ActivityClientRecord r, IntArray path,
206 ClientTransaction transaction) {
207 final
int
size = path.size();
208
for
(
int
i = 0, state; i < size; i++) {
209 state = path.get(i);
210
if
(DEBUG_RESOLVER) {
211 Slog.d(TAG, tId(transaction) +
"Transitioning activity: "
212 + getShortActivityName(r.token, mTransactionHandler)
213 +
" to state: "
+ getStateName(state));
214 }
215
switch
(state) {
216
case
ON_CREATE:
217 mTransactionHandler.handleLaunchActivity(r, mPendingActions,
218 null
/* customIntent */
);
219
break
;
220
case
ON_START:
221 mTransactionHandler.handleStartActivity(r, mPendingActions,
222 null
/* activityOptions */
);
223
break
;
224
case
ON_RESUME:
225 mTransactionHandler.handleResumeActivity(r,
false
/* finalStateRequest */
,
226 r.isForward,
"LIFECYCLER_RESUME_ACTIVITY"
);
227
break
;
228
case
ON_PAUSE:
229 mTransactionHandler.handlePauseActivity(r,
false
/* finished */
,
230
false
/* userLeaving */
, 0
/* configChanges */
, mPendingActions,
231
"LIFECYCLER_PAUSE_ACTIVITY"
);
232
break
;
233
case
ON_STOP:
234 mTransactionHandler.handleStopActivity(r, 0
/* configChanges */
,
235 mPendingActions,
false
/* finalStateRequest */
,
236
"LIFECYCLER_STOP_ACTIVITY"
);
237
break
;
238
case
ON_DESTROY:
239 mTransactionHandler.handleDestroyActivity(r,
false
/* finishing */
,
240 0
/* configChanges */
,
false
/* getNonConfigInstance */
,
241
"performLifecycleSequence. cycling to:"
+ path.get(size - 1));
242
break
;
243
case
ON_RESTART:
244 mTransactionHandler.performRestartActivity(r,
false
/* start */
);
245
break
;
246
default
:
247
throw
new
IllegalArgumentException(
"Unexpected lifecycle state: "
+ state);
248 }
249 }
250 }
mTransactionHandler.handleLaunchActivity(r, mPendingActions,
218 null
/* customIntent */
);
mTransactionHandler.handleLaunchActivity(r, mPendingActions,
218 null
/* customIntent */
);
/**
3758 * Extended implementation of activity launch. Used when server requests a launch or relaunch.
3759 */
3760 @Override
3761
public
Activity handleLaunchActivity(ActivityClientRecord r,
3762 PendingTransactionActions pendingActions, Intent customIntent) {
3763
// If we are getting ready to gc after going to the background, well
3764
// we are back active so skip it.
3765 unscheduleGcIdler();
3766 mSomeActivitiesChanged =
true
;
3767
3768
if
(r.profilerInfo != null) {
3769 mProfiler.setProfiler(r.profilerInfo);
3770 mProfiler.startProfiling();
3771 }
3772
3773
if
(r.mPendingFixedRotationAdjustments != null) {
3774
// The rotation adjustments must be applied before handling configuration, so process
3775
// level display metrics can be adjusted.
3776 overrideApplicationDisplayAdjustments(r.token, adjustments ->
3777 adjustments.setFixedRotationAdjustments(r.mPendingFixedRotationAdjustments));
3778 }
3779
3780
// Make sure we are running with the most recent config.
3781 mConfigurationController.handleConfigurationChanged(null, null);
3782
3783
if
(localLOGV) Slog.v(
3784 TAG,
"Handling launch of "
+ r);
3785
3786
// Initialize before creating the activity
3787
if
(ThreadedRenderer.sRendererEnabled
3788 && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
3789 HardwareRenderer.preload();
3790 }
3791 WindowManagerGlobal.initialize();
3792
3793
// Hint the GraphicsEnvironment that an activity is launching on the process.
3794 GraphicsEnvironment.hintActivityLaunch();
3795
3796 final Activity a = performLaunchActivity(r, customIntent);
3797
3798
if
(a != null) {
3799 r.createdConfig =
new
Configuration(mConfigurationController.getConfiguration());
3800 reportSizeConfigurations(r);
3801
if
(!r.activity.mFinished && pendingActions != null) {
3802 pendingActions.setOldState(r.state);
3803 pendingActions.setRestoreInstanceState(
true
);
3804 pendingActions.setCallOnPostCreate(
true
);
3805 }
3806 }
else
{
3807
// If there was an error, for any reason, tell the activity manager to stop us.
3808 ActivityClient.getInstance().finishActivity(r.token, Activity.RESULT_CANCELED,
3809 null
/* resultData */
, Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
3810 }
3811
3812
return
a;
3813 }
/**
3758 * Extended implementation of activity launch. Used when server requests a launch or relaunch.
3759 */
3760 @Override
3761
public
Activity handleLaunchActivity(ActivityClientRecord r,
3762 PendingTransactionActions pendingActions, Intent customIntent) {
3763
// If we are getting ready to gc after going to the background, well
3764
// we are back active so skip it.
3765 unscheduleGcIdler();
3766 mSomeActivitiesChanged =
true
;
3767
3768
if
(r.profilerInfo != null) {
3769 mProfiler.setProfiler(r.profilerInfo);
3770 mProfiler.startProfiling();
3771 }
3772
3773
if
(r.mPendingFixedRotationAdjustments != null) {
3774
// The rotation adjustments must be applied before handling configuration, so process
3775
// level display metrics can be adjusted.
3776 overrideApplicationDisplayAdjustments(r.token, adjustments ->
3777 adjustments.setFixedRotationAdjustments(r.mPendingFixedRotationAdjustments));
3778 }
3779
3780
// Make sure we are running with the most recent config.
3781 mConfigurationController.handleConfigurationChanged(null, null);
3782
3783
if
(localLOGV) Slog.v(
3784 TAG,
"Handling launch of "
+ r);
3785
3786
// Initialize before creating the activity
3787
if
(ThreadedRenderer.sRendererEnabled
3788 && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
3789 HardwareRenderer.preload();
3790 }
3791 WindowManagerGlobal.initialize();
3792
3793
// Hint the GraphicsEnvironment that an activity is launching on the process.
3794 GraphicsEnvironment.hintActivityLaunch();
3795
3796 final Activity a = performLaunchActivity(r, customIntent);
3797
3798
if
(a != null) {
3799 r.createdConfig =
new
Configuration(mConfigurationController.getConfiguration());
3800 reportSizeConfigurations(r);
3801
if
(!r.activity.mFinished && pendingActions != null) {
3802 pendingActions.setOldState(r.state);
3803 pendingActions.setRestoreInstanceState(
true
);
3804 pendingActions.setCallOnPostCreate(
true
);
3805 }
3806 }
else
{
3807
// If there was an error, for any reason, tell the activity manager to stop us.
3808 ActivityClient.getInstance().finishActivity(r.token, Activity.RESULT_CANCELED,
3809 null
/* resultData */
, Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
3810 }
3811
3812
return
a;
3813 }
3512
/** Core implementation of activity launch. */
3513
private
Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
3514 ActivityInfo aInfo = r.activityInfo;
3515
if
(r.packageInfo == null) {
3516 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
3517 Context.CONTEXT_INCLUDE_CODE);
3518 }
3519
3520 ComponentName component = r.intent.getComponent();
3521
if
(component == null) {
3522 component = r.intent.resolveActivity(
3523 mInitialApplication.getPackageManager());
3524 r.intent.setComponent(component);
3525 }
3526
3527
if
(r.activityInfo.targetActivity != null) {
3528 component =
new
ComponentName(r.activityInfo.packageName,
3529 r.activityInfo.targetActivity);
3530 }
3531
3532 ContextImpl appContext = createBaseContextForActivity(r);
3533 Activity activity = null;
3534
try
{
3535 java.lang.ClassLoader cl = appContext.getClassLoader();
3536 activity = mInstrumentation.newActivity(
3537 cl, component.getClassName(), r.intent);
3538 StrictMode.incrementExpectedActivityCount(activity.getClass());
3539 r.intent.setExtrasClassLoader(cl);
3540 r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
3541 appContext.getAttributionSource());
3542
if
(r.state != null) {
3543 r.state.setClassLoader(cl);
3544 }
3545 }
catch
(Exception e) {
3546
if
(!mInstrumentation.onException(activity, e)) {
3547
throw
new
RuntimeException(
3548
"Unable to instantiate activity "
+ component
3549 +
": "
+ e.toString(), e);
3550 }
3551 }
3552
3553
try
{
3554 Application app = r.packageInfo.makeApplication(
false
, mInstrumentation);
3555
3556
if
(localLOGV) Slog.v(TAG,
"Performing launch of "
+ r);
3557
if
(localLOGV) Slog.v(
3558 TAG, r +
": app="
+ app
3559 +
", appName="
+ app.getPackageName()
3560 +
", pkg="
+ r.packageInfo.getPackageName()
3561 +
", comp="
+ r.intent.getComponent().toShortString()
3562 +
", dir="
+ r.packageInfo.getAppDir());
3563
3564
if
(activity != null) {
3565 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
3566 Configuration config =
3567
new
Configuration(mConfigurationController.getCompatConfiguration());
3568
if
(r.overrideConfig != null) {
3569 config.updateFrom(r.overrideConfig);
3570 }
3571
if
(DEBUG_CONFIGURATION) Slog.v(TAG,
"Launching activity "
3572 + r.activityInfo.name +
" with config "
+ config);
3573 Window window = null;
3574
if
(r.mPendingRemoveWindow != null && r.mPreserveWindow) {
3575 window = r.mPendingRemoveWindow;
3576 r.mPendingRemoveWindow = null;
3577 r.mPendingRemoveWindowManager = null;
3578 }
3579
3580
// Activity resources must be initialized with the same loaders as the
3581
// application context.
3582 appContext.getResources().addLoaders(
3583 app.getResources().getLoaders().toArray(
new
ResourcesLoader[0]));
3584
3585 appContext.setOuterContext(activity);
3586 activity.attach(appContext,
this
, getInstrumentation(), r.token,
3587 r.ident, app, r.intent, r.activityInfo, title, r.parent,
3588 r.embeddedID, r.lastNonConfigurationInstances, config,
3589 r.referrer, r.voiceInteractor, window, r.configCallback,
3590 r.assistToken, r.shareableActivityToken);
3591
3592
if
(customIntent != null) {
3593 activity.mIntent = customIntent;
3594 }
3595 r.lastNonConfigurationInstances = null;
3596 checkAndBlockForNetworkAccess();
3597 activity.mStartedActivity =
false
;
3598
int
theme = r.activityInfo.getThemeResource();
3599
if
(theme != 0) {
3600 activity.setTheme(theme);
3601 }
3602
3603
if
(r.mActivityOptions != null) {
3604 activity.mPendingOptions = r.mActivityOptions;
3605 r.mActivityOptions = null;
3606 }
3607 activity.mLaunchedFromBubble = r.mLaunchedFromBubble;
3608 activity.mCalled =
false
;
3609
if
(r.isPersistable()) {
3610 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
3611 }
else
{
3612 mInstrumentation.callActivityOnCreate(activity, r.state);
3613 }
3614
if
(!activity.mCalled) {
3615
throw
new
SuperNotCalledException(
3616
"Activity "
+ r.intent.getComponent().toShortString() +
3617
" did not call through to super.onCreate()"
);
3618 }
3619 r.activity = activity;
3620 mLastReportedWindowingMode.put(activity.getActivityToken(),
3621 config.windowConfiguration.getWindowingMode());
3622 }
3623 r.setState(ON_CREATE);
3624
3625
// updatePendingActivityConfiguration() reads from mActivities to update
3626
// ActivityClientRecord which runs in a different thread. Protect modifications to
3627
// mActivities to avoid race.
3628 synchronized (mResourcesManager) {
3629 mActivities.put(r.token, r);
3630 }
3631
3632 }
catch
(SuperNotCalledException e) {
3633
throw
e;
3634
3635 }
catch
(Exception e) {
3636
if
(!mInstrumentation.onException(activity, e)) {
3637
throw
new
RuntimeException(
3638
"Unable to start activity "
+ component
3639 +
": "
+ e.toString(), e);
3640 }
3641 }
3642
3643
return
activity;
3644 }
3512
/** Core implementation of activity launch. */
3513
private
Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
3514 ActivityInfo aInfo = r.activityInfo;
3515
if
(r.packageInfo == null) {
3516 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
3517 Context.CONTEXT_INCLUDE_CODE);
3518 }
3519
3520 ComponentName component = r.intent.getComponent();
3521
if
(component == null) {
3522 component = r.intent.resolveActivity(
3523 mInitialApplication.getPackageManager());
3524 r.intent.setComponent(component);
3525 }
3526
3527
if
(r.activityInfo.targetActivity != null) {
3528 component =
new
ComponentName(r.activityInfo.packageName,
3529 r.activityInfo.targetActivity);
3530 }
3531
3532 ContextImpl appContext = createBaseContextForActivity(r);
3533 Activity activity = null;
3534
try
{
3535 java.lang.ClassLoader cl = appContext.getClassLoader();
3536 activity = mInstrumentation.newActivity(
3537 cl, component.getClassName(), r.intent);
3538 StrictMode.incrementExpectedActivityCount(activity.getClass());
3539 r.intent.setExtrasClassLoader(cl);
3540 r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
3541 appContext.getAttributionSource());
3542
if
(r.state != null) {
3543 r.state.setClassLoader(cl);
3544 }
3545 }
catch
(Exception e) {
3546
if
(!mInstrumentation.onException(activity, e)) {
3547
throw
new
RuntimeException(
3548
"Unable to instantiate activity "
+ component
3549 +
": "
+ e.toString(), e);
3550 }
3551 }
3552
3553
try
{
3554 Application app = r.packageInfo.makeApplication(
false
, mInstrumentation);
3555
3556
if
(localLOGV) Slog.v(TAG,
"Performing launch of "
+ r);
3557
if
(localLOGV) Slog.v(
3558 TAG, r +
": app="
+ app
3559 +
", appName="
+ app.getPackageName()
3560 +
", pkg="
+ r.packageInfo.getPackageName()
3561 +
", comp="
+ r.intent.getComponent().toShortString()
3562 +
", dir="
+ r.packageInfo.getAppDir());
3563
3564
if
(activity != null) {
3565 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
3566 Configuration config =
3567
new
Configuration(mConfigurationController.getCompatConfiguration());
3568
if
(r.overrideConfig != null) {
3569 config.updateFrom(r.overrideConfig);
3570 }
3571
if
(DEBUG_CONFIGURATION) Slog.v(TAG,
"Launching activity "
3572 + r.activityInfo.name +
" with config "
+ config);
3573 Window window = null;
3574
if
(r.mPendingRemoveWindow != null && r.mPreserveWindow) {
3575 window = r.mPendingRemoveWindow;
3576 r.mPendingRemoveWindow = null;
3577 r.mPendingRemoveWindowManager = null;
3578 }
3579
赞赏
- [原创]安卓逆向之插件化技术学习 14827
- [原创]窥探Proot原理 29875
- [原创]安卓签名校验-探讨 59287
- [原创]某加固so层脱壳 51345
- [原创] NP签名校验分析 46465