下面列出了android.content.Intent#setExtrasClassLoader ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void recoverActivityStack() {
ArrayList<Intent> intents = getRecoveryIntents();
if (intents != null && !intents.isEmpty()) {
ArrayList<Intent> availableIntents = new ArrayList<>();
for (Intent tmp : intents) {
if (tmp != null && RecoveryUtil.isIntentAvailable(this, tmp)) {
tmp.setExtrasClassLoader(getClassLoader());
availableIntents.add(tmp);
}
}
if (!availableIntents.isEmpty()) {
availableIntents.get(0).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
availableIntents.get(availableIntents.size() - 1).putExtra(RECOVERY_MODE_ACTIVE, true);
startActivities(availableIntents.toArray(new Intent[availableIntents.size()]));
overridePendingTransition(0, 0);
finish();
return;
}
}
restart();
}
private void sendIntent2Process(String target, Intent intent, boolean sync) throws RemoteException {
if (LOG) {
LogDebug.d(PLUGIN_TAG, "sendIntent2Process target=" + target + " intent=" + intent);
}
if (TextUtils.equals(target, IPC.getPluginHostProcessName())) {
intent.setExtrasClassLoader(getClass().getClassLoader());
if (sync) {
LocalBroadcastHelper.sendBroadcastSyncUi(mContext, intent);
} else {
LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
}
return;
}
if (TextUtils.isEmpty(target)) {
intent.setExtrasClassLoader(getClass().getClassLoader());
if (sync) {
LocalBroadcastHelper.sendBroadcastSyncUi(mContext, intent);
} else {
LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
}
}
PluginProcessMain.sendIntent2Process(target, intent, sync);
}
public void setEnterActivityOptions(Activity activity, ActivityOptions options) {
final Window window = activity.getWindow();
if (window == null) {
return;
}
// ensure Decor View has been created so that the window features are activated
window.getDecorView();
if (window.hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
&& options != null && mEnterActivityOptions == null
&& mEnterTransitionCoordinator == null
&& options.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
mEnterActivityOptions = options;
mIsEnterTriggered = false;
if (mEnterActivityOptions.isReturning()) {
restoreExitedViews();
int result = mEnterActivityOptions.getResultCode();
if (result != 0) {
Intent intent = mEnterActivityOptions.getResultData();
if (intent != null) {
intent.setExtrasClassLoader(activity.getClassLoader());
}
activity.onActivityReenter(result, intent);
}
}
}
}
/**
* 为插件中的Service设置代理
*
* @param mIntent 需要设置代理的Service的Intent
* @param targetService 目标的ServiceInfo,包含插件包名和跳转Service的名称
*/
private static void setServiceProxy(Intent mIntent, ServiceInfo targetService) {
String mPackageName = targetService.packageName;
String serviceName = targetService.name;
PluginLoadedApk mLoadedApk = PluginManager.getPluginLoadedApkByPkgName(mPackageName);
if (null == mLoadedApk) {
PluginDebugLog.runtimeFormatLog(TAG,
"setServiceProxy failed, %s, PluginLoadedApk is null", mPackageName);
return;
}
PluginDebugLog.runtimeFormatLog(TAG, "setServiceProxy serviceInfo: " + targetService.toString());
mIntent.setExtrasClassLoader(mLoadedApk.getPluginClassLoader());
mIntent.addCategory(IntentConstant.EXTRA_TARGET_CATEGORY + System.currentTimeMillis())
.putExtra(IntentConstant.EXTRA_TARGET_IS_PLUGIN_KEY, true)
.putExtra(IntentConstant.EXTRA_TARGET_CLASS_KEY, serviceName)
.putExtra(IntentConstant.EXTRA_TARGET_PACKAGE_KEY, mLoadedApk.getPluginPackageName());
try {
mIntent.setClass(mLoadedApk.getHostContext(),
Class.forName(matchServiceProxyByFeature(mLoadedApk.getProcessName())));
IntentUtils.setProxyInfo(mIntent, mPackageName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private void recoverActivityStack(Intent o) {
ArrayList<Intent> intents = getRecoveryIntents(o);
if (intents != null && !intents.isEmpty()) {
ArrayList<Intent> availableIntents = new ArrayList<>();
for (Intent tmp : intents) {
if (tmp != null && RecoveryUtil.isIntentAvailable(this, tmp)) {
tmp.setExtrasClassLoader(getClassLoader());
availableIntents.add(tmp);
}
}
if (!availableIntents.isEmpty()) {
availableIntents.get(0).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
availableIntents.get(availableIntents.size() - 1).putExtra(RECOVERY_MODE_ACTIVE, true);
startActivities(availableIntents.toArray(new Intent[availableIntents.size()]));
stopSelf();
return;
}
}
restart();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQCODE_EDIT_DATA) {
if (resultCode == Activity.RESULT_OK) {
data.setExtrasClassLoader(RemoteOperationData.class.getClassLoader());
passed_data = data.getParcelableExtra(RemotePlugin.EXTRA_DATA);
}
} else
super.onActivityResult(requestCode, resultCode, data);
}
private IBinder handleOnBindOne(Intent intent) throws Exception {
ServiceInfo info = ApkManager.getInstance().resolveServiceInfo(intent, 0);
if (info != null) {
Service service = (Service) this.mNameService.get(info.name);
if (service != null) {
intent.setExtrasClassLoader(getClassLoader(info.applicationInfo));
return service.onBind(intent);
}
}
return null;
}
private void handleOnRebindOne(Intent intent) throws Exception {
ServiceInfo info = ApkManager.getInstance().resolveServiceInfo(intent, 0);
if (info != null) {
Service service = (Service) this.mNameService.get(info.name);
if (service != null) {
intent.setExtrasClassLoader(getClassLoader(info.applicationInfo));
service.onRebind(intent);
}
}
}
private void deliverNewIntents(ActivityClientRecord r,
List<Intent> intents) {
final int N = intents.size();
for (int i=0; i<N; i++) {
Intent intent = intents.get(i);
intent.setExtrasClassLoader(r.activity.getClassLoader());
r.activity.mFragments.noteStateNotSaved();
mInstrumentation.callActivityOnNewIntent(r.activity, intent);
}
}
/**
* @hide 内部方法,插件框架使用
* 插件的Activity的onCreate调用前调用此方法
* @param activity
* @param savedInstanceState
*/
public void handleActivityCreateBefore(Activity activity, Bundle savedInstanceState) {
if (LOG) {
LogDebug.d(PLUGIN_TAG, "activity create before: " + activity.getClass().getName() + " this=" + activity.hashCode() + " taskid=" + activity.getTaskId());
}
// 对FragmentActivity做特殊处理
if (savedInstanceState != null) {
//
savedInstanceState.setClassLoader(activity.getClassLoader());
//
try {
savedInstanceState.remove("android:support:fragments");
} catch (Throwable e) {
if (LOGR) {
LogRelease.e(PLUGIN_TAG, "a.c.b1: " + e.getMessage(), e);
}
}
}
// 对FragmentActivity做特殊处理
Intent intent = activity.getIntent();
if (intent != null) {
intent.setExtrasClassLoader(activity.getClassLoader());
activity.setTheme(getThemeId(activity, intent));
}
}
private void handleOnRebindOne(Intent intent) throws Exception {
ServiceInfo info = PluginManager.getInstance().resolveServiceInfo(intent, 0);
if (info != null) {
Service service = mNameService.get(info.name);
if (service != null) {
ClassLoader classLoader = getClassLoader(info.applicationInfo);
intent.setExtrasClassLoader(classLoader);
service.onRebind(intent);
}
}
}
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context, int flags) {
IIntentReceiver rd = null;
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
try {
final Intent intent = ActivityManager.getService().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
broadcastPermission, userId, flags);
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
intent.prepareToEnterProcess();
}
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
protected static Intent createBaseIntent(
@NonNull Context context,
@NonNull Class<? extends Activity> target,
@NonNull FlowParameters flowParams) {
Intent intent = new Intent(
checkNotNull(context, "context cannot be null"),
checkNotNull(target, "target activity cannot be null"))
.putExtra(ExtraConstants.FLOW_PARAMS,
checkNotNull(flowParams, "flowParams cannot be null"));
intent.setExtrasClassLoader(AuthUI.class.getClassLoader());
return intent;
}
@Override
public void callActivityOnNewIntent(Activity activity, Intent intent) {
PluginInjector.injectInstrumetionFor360Safe(activity, this);
if (intent != null) {
intent.setExtrasClassLoader(activity.getClassLoader());
}
real.callActivityOnNewIntent(activity, intent);
}
@Override
public void callActivityOnNewIntent(Activity activity, Intent intent) {
PluginInjector.injectInstrumetionFor360Safe(activity, this);
if (intent != null) {
intent.setExtrasClassLoader(activity.getClassLoader());
}
super.callActivityOnNewIntent(activity, intent);
}
@Override
public void callActivityOnCreate(Activity activity, Bundle icicle) {
if (icicle != null && icicle.getParcelable("android:support:fragments") != null) {
if (ProcessUtil.isPluginProcess()) {
if (AnnotationProcessor.getPluginContainer(activity.getClass()) != null) {
// 加了注解的Activity正在自动恢复且页面包含了Fragment。直接清除fragment,
// 防止如果被恢复的fragment来自插件时,在某些情况下会使用宿主的classloader加载插件fragment
// 导致classnotfound问题
icicle.clear();
icicle = null;
}
}
}
PluginInjector.injectInstrumetionFor360Safe(activity, this);
PluginInjector.injectActivityContext(activity);
Intent intent = activity.getIntent();
if (intent != null) {
intent.setExtrasClassLoader(activity.getClassLoader());
}
if (icicle != null) {
icicle.setClassLoader(activity.getClassLoader());
}
if (ProcessUtil.isPluginProcess()) {
installPluginViewFactory(activity);
if (activity instanceof WaitForLoadingPluginActivity) {
//NOTHING
} else {
AndroidWebkitWebViewFactoryProvider.switchWebViewContext(activity);
}
if (activity.isChild()) {
//修正TabActivity中的Activity的ContextImpl的packageName
Context base = activity.getBaseContext();
while(base instanceof ContextWrapper) {
base = ((ContextWrapper)base).getBaseContext();
}
if (HackContextImpl.instanceOf(base)) {
HackContextImpl impl = new HackContextImpl(base);
String packageName = FairyGlobal.getHostApplication().getPackageName();
String packageName1 = activity.getPackageName();
impl.setBasePackageName(packageName);
impl.setOpPackageName(packageName);
}
}
}
try {
real.callActivityOnCreate(activity, icicle);
} catch (RuntimeException e) {
throw new RuntimeException(
" activity : " + activity.getClassLoader() +
" pluginContainer : " + AnnotationProcessor.getPluginContainer(activity.getClass()) +
", process : " + ProcessUtil.isPluginProcess(), e);
}
monitor.onActivityCreate(activity);
}
static Context resolveReceiverForClassLoader(final Object msgObj) {
if (ProcessUtil.isPluginProcess()) {
PluginInjector.hackHostClassLoaderIfNeeded();
HackReceiverData hackReceiverData = new HackReceiverData(msgObj);
final Intent intent = hackReceiverData.getIntent();
//className要么是真组件,要么是stub,要么是exact的组件
String className = intent.getComponent().getClassName();
//当是stub或者exact时,需要处理className,供classloader使用
if (PluginManagerProviderClient.isStub(className)) {
String realReceiverClassName = null;
String[] targetClassName = null;
if (PluginManagerProviderClient.isExact(className, PluginDescriptor.BROADCAST)) {
realReceiverClassName = className;
} else {
String action = intent.getAction();
if (action != null) {
targetClassName = action.split(CLASS_SEPARATOR);
realReceiverClassName = targetClassName[0];
}
}
if (realReceiverClassName == null) {
// Intent的目标Component是Stub,
// 但是没用找到对应的插件,
// 正常情况下后续流程会抛出Stub ClassNotFound,
// 这里加容错防crash
LogUtil.w("返回容错标记, 交给HostClassLoader处理");
intent.setComponent(new ComponentName(intent.getComponent().getPackageName(), CLASS_PREFIX_RECEIVER_NOT_FOUND));
hackReceiverData.getInfo().name = intent.getComponent().getClassName();
return null;
}
@SuppressWarnings("rawtypes")
Class clazz = PluginLoader.loadPluginClassByName(realReceiverClassName);
if (clazz != null) {
intent.setExtrasClassLoader(clazz.getClassLoader());
if (targetClassName != null) {
//由于之前intent被修改过 这里再吧Intent还原到原始的intent
if (targetClassName.length > 1) {
intent.setAction(targetClassName[1]);
} else {//length等于1的情况是因为原始的intent可能不是通过Action过来的,而是直接通过Component过来的
intent.setAction(null);
}
} else {
//isExact 无需对intent进行恢复
}
// HostClassLoader检测到这个特殊标记后会进行替换,得到真实的className
intent.setComponent(new ComponentName(intent.getComponent().getPackageName(), CLASS_PREFIX_RECEIVER + realReceiverClassName));
// TODO 部分9.0的设备上,改name没用??HMA-AL00 JSN-AL00? Redmi Note 7 Pro;Redmi K20 Pro; EML-AL00; MI 6X;
hackReceiverData.getInfo().name = intent.getComponent().getClassName();
//v0.0.58以后4.x的系统上需要setIntent,否则反序列化对象可能出现classloader问题
//if (Build.VERSION.SDK_INT >= 21) {
if (intent.getExtras() != null) {
hackReceiverData.setIntent(new PluginReceiverIntent(intent));
}
//}
return PluginLoader.getDefaultPluginContext(clazz);
} else {
// Intent的目标Component是Stub,
// 但是没用找到对应的插件,
// 正常情况下后续流程会抛出Stub ClassNotFound,
// 这里加容错防crash
LogUtil.w("返回容错标记, 交给HostClassLoader处理");
intent.setComponent(new ComponentName(intent.getComponent().getPackageName(), CLASS_PREFIX_RECEIVER_NOT_FOUND));
hackReceiverData.getInfo().name = intent.getComponent().getClassName();
return null;
}
}
}
return null;
}
public final Runnable getRunnable() {
return () -> {
final BroadcastReceiver receiver = mReceiver;
final boolean ordered = mOrdered;
if (ActivityThread.DEBUG_BROADCAST) {
int seq = mCurIntent.getIntExtra("seq", -1);
Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
+ " seq=" + seq + " to " + mReceiver);
Slog.i(ActivityThread.TAG, " mRegistered=" + mRegistered
+ " mOrderedHint=" + ordered);
}
final IActivityManager mgr = ActivityManager.getService();
final Intent intent = mCurIntent;
if (intent == null) {
Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched
+ ": run() previously called at "
+ Log.getStackTraceString(mPreviousRunStacktrace));
}
mCurIntent = null;
mDispatched = true;
mPreviousRunStacktrace = new Throwable("Previous stacktrace");
if (receiver == null || intent == null || mForgotten) {
if (mRegistered && ordered) {
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing null broadcast to " + mReceiver);
sendFinished(mgr);
}
return;
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess();
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
receiver.onReceive(mContext, intent);
} catch (Exception e) {
if (mRegistered && ordered) {
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing failed broadcast to " + mReceiver);
sendFinished(mgr);
}
if (mInstrumentation == null ||
!mInstrumentation.onException(mReceiver, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Error receiving broadcast " + intent
+ " in " + mReceiver, e);
}
}
if (receiver.getPendingResult() != null) {
finish();
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
};
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (DEBUG) {
Log.d(TAG, "onStartCommand(Intent intent, int flags, int startId) : intent="
+ ((intent == null) ? "null." : intent.toString())
+ "; flags=" + flags + "; startId=" + startId);
}
if (mIActivityManagerProxy == null) {
// 容错,不能支持Service了
return 0;
}
if (intent == null) {
return START_STICKY;
}
// 调用super,返回值用super的
int ret = super.onStartCommand(intent, flags, startId);
// 调用插件的onStartCommand方法
int targetRet = 0;
ComponentName target = getTargetComponent(intent);
if (target == null) {
if (mServices.isEmpty()) {
stopSelf();
}
return ret;
}
// 插件SDK不能支持百度PushService,暂时先屏蔽了。
if (TextUtils.equals(target.getClassName(), "com.baidu.android.pushservice.PushService")) {
return ret;
}
// 获取SR
ServiceRecord sr = mServices.get(target.toString());
if (sr == null) {
sr = loadTarget(intent, target, false);
}
// SR还是空的,可能是load失败了
if (sr == null) {
if (mServices.isEmpty()) {
stopSelf();
}
return ret;
}
// 解决andorid 5.0 service get Serializable extra 找不到class的问题。
intent.setExtrasClassLoader(ProxyEnvironment.getInstance(target.getPackageName()).getDexClassLoader());
targetRet = sr.service.onStartCommand(intent, flags, startId);
// 处理插件返回的ret
switch (targetRet) {
case Service.START_STICKY_COMPATIBILITY:
case Service.START_STICKY: {
sr.stopIfKilled = false;
break;
}
case Service.START_NOT_STICKY: {
if (sr.lastStartId == startId) {
sr.stopIfKilled = true;
}
break;
}
case Service.START_REDELIVER_INTENT: {
sr.lastIntent = new Intent(intent);
sr.stopIfKilled = false;
// 更新Intent
updateServicesToSp();
break;
}
default:
throw new IllegalArgumentException("Unknown service start result: " + targetRet);
}
updateServicesToSp();
return ret;
}
/**
* 在插件Activity的onCreate调用前调用该方法
*/
void handleActivityOnCreateBefore(Activity activity, Bundle savedInstanceState) {
if (PluginDebugLog.isDebug()) {
PluginDebugLog.runtimeLog(TAG, "activity handleActivityOnCreateBefore() is called(): " + activity.getClass().getName());
}
if (mPlugin == null) {
// 通过插件的Intent再去查找一遍
String pkgName = IntentUtils.parsePkgNameFromActivity(activity);
if (!TextUtils.isEmpty(pkgName)) {
mPlugin = PluginManager.getPluginLoadedApkByPkgName(pkgName);
}
}
ClassLoader cl = mPlugin != null ? mPlugin.getPluginClassLoader() : activity.getClassLoader();
// 修正Intent的ClassLoader,解决序列化的问题
Intent intent = activity.getIntent();
intent.setExtrasClassLoader(cl);
IntentUtils.resetAction(intent); //恢复Intent的Action
// 对FragmentActivity做特殊处理,不保留Fragment的恢复数据
if (savedInstanceState != null) {
savedInstanceState.setClassLoader(cl);
savedInstanceState.remove(SUPPORT_FRAGMENTS_TAG);
savedInstanceState.remove(FRAGMENTS_TAG);
}
// 替换Application,不然插件内无法监听LifeCycle
if (mPlugin != null) {
ReflectionUtils.on(activity).setNoException("mApplication", mPlugin.getPluginApplication());
}
// 再次确保Activity的Base Context已经被替换了
Context mBase = activity.getBaseContext();
if (mBase instanceof PluginContextWrapper) {
PluginDebugLog.runtimeLog(TAG, "activity " + activity.getClass().getName() + " base context already be replaced");
} else if (mPlugin != null) {
mBase = new PluginContextWrapper(mBase, mPlugin);
// 反射替换mBase成员变量
ReflectionUtils.on(activity, ContextWrapper.class).set("mBase", mBase);
ReflectionUtils.on(activity, ContextThemeWrapper.class).setNoException("mBase", mBase);
}
// 给LayoutInflater设置privateFactory
LayoutInflaterCompat.setPrivateFactory(activity.getLayoutInflater());
// 修改Activity的ActivityInfo和主题信息
PluginActivityControl.changeActivityInfo(activity, activity.getClass().getName(), mPlugin);
}