Skip to content

Commit

Permalink
update: 兼容 AndroidX
Browse files Browse the repository at this point in the history
  • Loading branch information
GitLqr committed Dec 8, 2021
1 parent 77d442d commit 41c0a2e
Show file tree
Hide file tree
Showing 8 changed files with 405 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public class LoaderActivityInjector extends BaseInjector {
'android.app.ActivityGroup' : 'com.qihoo360.replugin.loader.a.PluginActivityGroup',
'android.support.v4.app.FragmentActivity' : 'com.qihoo360.replugin.loader.a.PluginFragmentActivity',
'android.support.v7.app.AppCompatActivity': 'com.qihoo360.replugin.loader.a.PluginAppCompatActivity',
'androidx.fragment.app.FragmentActivity' : 'com.qihoo360.replugin.loader.a.PluginFragmentActivity',
'androidx.appcompat.app.AppCompatActivity': 'com.qihoo360.replugin.loader.a.PluginAppCompatActivity',
'androidx.fragment.app.FragmentActivity' : 'com.qihoo360.replugin.loader.a.PluginFragmentActivityAndroidX',
'androidx.appcompat.app.AppCompatActivity': 'com.qihoo360.replugin.loader.a.PluginAppCompatActivityAndroidX',
'android.preference.PreferenceActivity' : 'com.qihoo360.replugin.loader.a.PluginPreferenceActivity',
'android.app.ExpandableListActivity' : 'com.qihoo360.replugin.loader.a.PluginExpandableListActivity'
]
Expand Down
1 change: 1 addition & 0 deletions replugin-plugin-library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
provided 'com.android.support:appcompat-v7:23.4.0'
provided 'androidx.appcompat:appcompat:1.1.0'
}

project.ext.RP_ARTIFACT_ID = 'replugin-plugin-lib'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.qihoo360.replugin.compat;

/**
* 兼容层配置
*
* @author LQR
* @since 2021/12/8
*/
public final class CompatConfig {

private static volatile CompatConfig sInstance;

public static final boolean DEPENDENCY_ANDROIDX;
public static final boolean DEPENDENCY_SUPPORT;

static {
DEPENDENCY_ANDROIDX = findClassByClassName("androidx.fragment.app.FragmentActivity");
DEPENDENCY_SUPPORT = findClassByClassName("android.support.v4.app.FragmentActivity");
}

private CompatConfig() {
}

public static CompatConfig getInstance() {
if (sInstance == null) {
synchronized (CompatConfig.class) {
if (sInstance == null) {
sInstance = new CompatConfig();
}
}
}
return sInstance;
}

private static boolean findClassByClassName(String className) {
boolean hasDependency;
try {
Class.forName(className);
hasDependency = true;
} catch (ClassNotFoundException e) {
hasDependency = false;
}
return hasDependency;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ protected void onRestoreInstanceState(Bundle savedInstanceState) {
// 1、可能无法恢复系统级View的保存的状态;
// 2、如果自己代码处理不当,可能会出现异常。故自己代码一定要用SecExtraUtils来获取Bundle数据
if (LogRelease.LOGR) {
LogRelease.e("PluginFragmentActivity", "o r i s: p=" + getPackageCodePath() + "; " + e.getMessage(), e);
LogRelease.e("PluginAppCompatActivity", "o r i s: p=" + getPackageCodePath() + "; " + e.getMessage(), e);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*
* Copyright (C) 2005-2017 Qihoo 360 Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed To in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package com.qihoo360.replugin.loader.a;

import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;

import com.qihoo360.replugin.RePluginInternal;
import com.qihoo360.replugin.helper.LogRelease;
import com.qihoo360.replugin.loader.PluginResource;

import java.lang.reflect.Field;

/**
* @author RePlugin Team
*/
public abstract class PluginAppCompatActivityAndroidX extends AppCompatActivity {

private PluginResource pluginResource;

@Override
protected void attachBaseContext(Context newBase) {
newBase = RePluginInternal.createActivityContext(this, newBase);
pluginResource = new PluginResource(newBase);
super.attachBaseContext(newBase);
}

@Override
public Resources getResources() {
if (pluginResource != null){
return pluginResource;
}
return super.getResources();
}

@Override
public Context getBaseContext() {

return super.getBaseContext();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
//
RePluginInternal.handleActivityCreateBefore(this, savedInstanceState);

super.onCreate(savedInstanceState);

//
RePluginInternal.handleActivityCreate(this, savedInstanceState);
}

@Override
protected void onDestroy() {
//
RePluginInternal.handleActivityDestroy(this);

super.onDestroy();
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
//
RePluginInternal.handleRestoreInstanceState(this, savedInstanceState);

try {
super.onRestoreInstanceState(savedInstanceState);
} catch (Throwable e) {
// Added by Jiongxuan Zhang
// Crash Hash: B1F67129BC6A67C882AF2BBE62202BF0
// java.lang.IllegalArgumentException: Wrong state class异常
// 原因:恢复现场时,Activity坑位找错了。通常是用于占坑的Activity的层级过深导致
// 举例:假如我们只有一个坑位可用,A和B分别是清理和通讯录的两个Activity
// 如果进程重启,系统原本恢复B,却走到了A,从而出现此问题
// 解决:将其Catch住,这样系统在找ViewState时不会出错。
// 后遗症:
// 1、可能无法恢复系统级View的保存的状态;
// 2、如果自己代码处理不当,可能会出现异常。故自己代码一定要用SecExtraUtils来获取Bundle数据
if (LogRelease.LOGR) {
LogRelease.e("PluginAppCompatActivityAndroidX", "o r i s: p=" + getPackageCodePath() + "; " + e.getMessage(), e);
}
}
}

@Override
public void startActivity(Intent intent) {
//
if (RePluginInternal.startActivity(this, intent)) {
// 这个地方不需要回调startActivityAfter,因为RePluginInternal最终还是会回调回来,最终还是要走super.startActivity()
return;
}

super.startActivity(intent);
}

@Override
public void startActivityForResult(Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}

@Override
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
//
if (RePluginInternal.startActivityForResult(this, intent, requestCode, options)) {
return;
}

if (Build.VERSION.SDK_INT >= 16) {
super.startActivityForResult(intent, requestCode, options);
} else {
super.startActivityForResult(intent, requestCode);
}
}

/**
* 这里的做法是支持Fragment中调用startActivityForResult特性
* <p>
* 由于卫士的插件需要hook住XXX-Activity的startActivity和startActivityForResult接口
* 但早期版本的support-v4在startActivityFromFragment中直接调用了super.startActivityForResult, 因此这里还需要hook住这个点
* 但新版的support-v4中Fragment最终的调用链还是会走到本XXX-Activity的startActivityForResult接口,因此不需要适配startActivityFromFragment(Fragment fragment, Intent intent, int requestCode, @Nullable Bundle options)接口
*
* @param fragment
* @param intent
* @param requestCode
*/
@Override
public void startActivityFromFragment(Fragment fragment, Intent intent, int requestCode) {
if (requestCode == -1) {
startActivityForResult(intent, -1);
} else if ((requestCode & -65536) != 0) {
throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");
} else {
int newRequestCode = -1;
try {
Field f = Fragment.class.getDeclaredField("mIndex");
boolean acc = f.isAccessible();
if (!acc) {
f.setAccessible(true);
}
Object o = f.get(fragment);
if (!acc) {
f.setAccessible(acc);
}
int index = (Integer) o;
newRequestCode = ((index + 1) << 16) + (requestCode & '\uffff');
} catch (Throwable e) {
// Do Noting
}
startActivityForResult(intent, newRequestCode);
}
}

@Override
public String getPackageCodePath() {
return super.getPackageCodePath();
}
}
Loading

0 comments on commit 41c0a2e

Please sign in to comment.