Skip to content

Commit d20dcaf

Browse files
committed
Update Core For PluginManager and Bugs
1 parent 9cbb788 commit d20dcaf

File tree

10 files changed

+305
-70
lines changed

10 files changed

+305
-70
lines changed

PluginCore/src/com/plugin/core/PluginAppTrace.java

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22

33
import android.app.Service;
44
import android.content.Context;
5+
import android.content.pm.ServiceInfo;
56
import android.os.Handler;
67
import android.os.IBinder;
78
import android.os.Message;
89

910
import com.plugin.core.app.ActivityThread;
11+
import com.plugin.core.manager.PluginManagerHelper;
1012
import com.plugin.util.LogUtil;
13+
import com.plugin.util.ProcessUtil;
1114
import com.plugin.util.RefInvoker;
1215

1316
import java.util.Map;
@@ -67,53 +70,65 @@ private Result beforeHandle(Message msg) {
6770
}
6871

6972
private static Result beforeReceiver(Message msg) {
70-
Class clazz = PluginIntentResolver.resolveReceiverForClassLoader(msg.obj);
73+
if (ProcessUtil.isPluginProcess()) {
74+
Class clazz = PluginIntentResolver.resolveReceiverForClassLoader(msg.obj);
7175

72-
if (clazz != null) {
73-
PluginInjector.hackHostClassLoaderIfNeeded();
76+
if (clazz != null) {
77+
PluginInjector.hackHostClassLoaderIfNeeded();
7478

75-
Context baseContext = PluginLoader.getApplicatoin().getBaseContext();
76-
Context newBase = PluginLoader.getDefaultPluginContext(clazz);
79+
Context baseContext = PluginLoader.getApplicatoin().getBaseContext();
80+
Context newBase = PluginLoader.getDefaultPluginContext(clazz);
7781

78-
PluginInjector.replaceReceiverContext(baseContext, newBase);
82+
PluginInjector.replaceReceiverContext(baseContext, newBase);
7983

80-
Result result = new Result();
81-
result.baseContext = baseContext;
84+
Result result = new Result();
85+
result.baseContext = baseContext;
8286

83-
return result;
84-
} else {
85-
//宿主的receiver的context不需要处理,在framework中receiver的context本身是对appliction的包装。
86-
//而宿主的application的base已经本更换过了
87+
return result;
88+
} else {
89+
//宿主的receiver的context不需要处理,在framework中receiver的context本身是对appliction的包装。
90+
//而宿主的application的base已经本更换过了
91+
}
8792
}
93+
8894
return null;
8995
}
9096

9197
private static Result beforeCreateService(Message msg) {
92-
String serviceName = PluginIntentResolver.resolveServiceForClassLoader(msg.obj);
98+
Result result = new Result();
99+
if (ProcessUtil.isPluginProcess()) {
100+
String serviceName = PluginIntentResolver.resolveServiceForClassLoader(msg.obj);
101+
102+
if (serviceName.startsWith(PluginIntentResolver.CLASS_PREFIX)) {
103+
PluginInjector.hackHostClassLoaderIfNeeded();
104+
}
93105

94-
if (serviceName.startsWith(PluginIntentResolver.CLASS_PREFIX)) {
95-
PluginInjector.hackHostClassLoaderIfNeeded();
106+
result.serviceName = serviceName;
107+
} else {
108+
ServiceInfo info = (ServiceInfo) RefInvoker.getFieldObject(msg.obj, "android.app.ActivityThread$CreateServiceData", "info");
109+
result.serviceName = info.name;
96110
}
97-
Result result = new Result();
98-
result.serviceName = serviceName;
99111

100112
return result;
101113
}
102114

103115
private static Result beforeStopService(Message msg) {
104-
//销毁service时回收映射关系
105-
Object activityThread = ActivityThread.currentActivityThread();
106-
if (activityThread != null) {
107-
Map<IBinder, Service> services = ActivityThread.getAllServices();
108-
if (services != null) {
109-
Service service = services.get(msg.obj);
110-
if (service != null) {
111-
String pluginServiceClassName = service.getClass().getName();
112-
LogUtil.d("STOP_SERVICE", pluginServiceClassName);
113-
PluginStubBinding.unBindStubService(pluginServiceClassName);
116+
if (ProcessUtil.isPluginProcess()) {
117+
//销毁service时回收映射关系
118+
Object activityThread = ActivityThread.currentActivityThread();
119+
if (activityThread != null) {
120+
Map<IBinder, Service> services = ActivityThread.getAllServices();
121+
if (services != null) {
122+
Service service = services.get(msg.obj);
123+
if (service != null) {
124+
String pluginServiceClassName = service.getClass().getName();
125+
LogUtil.d("STOP_SERVICE", pluginServiceClassName);
126+
PluginManagerHelper.unBindStubService(pluginServiceClassName);
127+
}
114128
}
115129
}
116130
}
131+
117132
return null;
118133
}
119134

@@ -134,21 +149,22 @@ private static void afterHandle(Message msg, Result result) {
134149
}
135150

136151
private static void afterReceiver(Result result) {
137-
if (result != null && result.baseContext != null) {
138-
RefInvoker.setFieldObject(result.baseContext, "android.app.ContextImpl", "mReceiverRestrictedContext", null);
152+
if (ProcessUtil.isPluginProcess()) {
153+
if (result != null && result.baseContext != null) {
154+
RefInvoker.setFieldObject(result.baseContext, "android.app.ContextImpl", "mReceiverRestrictedContext", null);
155+
}
139156
}
140157
}
141158

142159
private static void afterCreateService(Result result) {
143-
if (result != null) {
144-
if (result.serviceName.startsWith(PluginIntentResolver.CLASS_PREFIX)) {
145-
//拿到创建好的service,重新 设置mBase和mApplicaiton
146-
//由于这步操作是再service得oncreate之后执行,所以再插件service得oncreate中不应尝试通过此service的context执行操作
147-
PluginInjector.replacePluginServiceContext(result.serviceName.replace(PluginIntentResolver.CLASS_PREFIX, ""));
148-
} else {
149-
//注入一个无害的BaseContext, 主要是为了重写宿主Service的sentBroadCast和startService方法
150-
PluginInjector.replaceHostServiceContext(result.serviceName);
151-
}
160+
161+
if (result.serviceName.startsWith(PluginIntentResolver.CLASS_PREFIX)) {
162+
//拿到创建好的service,重新 设置mBase和mApplicaiton
163+
//由于这步操作是再service得oncreate之后执行,所以再插件service得oncreate中不应尝试通过此service的context执行操作
164+
PluginInjector.replacePluginServiceContext(result.serviceName.replace(PluginIntentResolver.CLASS_PREFIX, ""));
165+
} else {
166+
//注入一个无害的BaseContext, 主要是为了重写宿主Service的sentBroadCast和startService方法
167+
PluginInjector.replaceHostServiceContext(result.serviceName);
152168
}
153169
}
154170

PluginCore/src/com/plugin/core/PluginInjector.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ static void injectActivityContext(Activity activity) {
111111
FragmentContainer fragmentContainer = AnnotationProcessor.getFragmentContainer(activity.getClass());
112112
// 如果是打开插件中的activity, 或者是打开的用来显示插件fragment的宿主activity
113113
if (ProcessUtil.isPluginProcess() && (fragmentContainer != null ||
114-
PluginStubBinding.isStubActivity(intent.getComponent().getClassName()))) {
114+
PluginManagerHelper.isStubActivity(intent.getComponent().getClassName()))) {
115115
// 为了不需要重写插件Activity的attachBaseContext方法为:
116116
// 我们在activityoncreate之前去完成attachBaseContext的事情
117117

@@ -313,9 +313,11 @@ static void resetWindowConfig(final Context pluginContext, final PluginDescripto
313313

314314
RefInvoker.setFieldObject(service, Service.class.getName(), "mApplication", plugin.pluginApplication);
315315

316-
RefInvoker.setFieldObject(service, Service.class, "mClassName", PluginStubBinding.bindStubService(service.getClass().getName()));
316+
RefInvoker.setFieldObject(service, Service.class, "mClassName", PluginManagerHelper.bindStubService(service.getClass().getName()));
317317

318-
break;
318+
//这里不退出循环,是因为在多进程情况下,杀死插件进程,自动恢复service时有个bug导致一个service同时存在多个service实例
319+
//这里做个遍历保护
320+
//break;
319321
}
320322

321323
}

PluginCore/src/com/plugin/core/PluginInstrumentionWrapper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public Activity newActivity(ClassLoader cl, String className, Intent intent) thr
7272
IllegalAccessException, ClassNotFoundException {
7373
if (ProcessUtil.isPluginProcess()) {
7474
// 将PluginStubActivity替换成插件中的activity
75-
if (PluginStubBinding.isStubActivity(className)) {
75+
if (PluginManagerHelper.isStubActivity(className)) {
7676

7777
String action = intent.getAction();
7878

@@ -97,7 +97,7 @@ public Activity newActivity(ClassLoader cl, String className, Intent intent) thr
9797
//添加一个标记符
9898
intent.addCategory(RELAUNCH_FLAG + className);
9999
}
100-
} else if (PluginStubBinding.isExact(className, PluginDescriptor.ACTIVITY)) {
100+
} else if (PluginManagerHelper.isExact(className, PluginDescriptor.ACTIVITY)) {
101101
//这个逻辑是为了支持外部app唤起配置了stub_exact的插件Activity
102102
Class clazz = PluginLoader.loadPluginClassByName(className);
103103
if (clazz != null) {

PluginCore/src/com/plugin/core/PluginIntentResolver.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class PluginIntentResolver {
2222
public static void resolveService(Intent service) {
2323
ArrayList<String> classNameList = PluginLoader.matchPlugin(service, PluginDescriptor.SERVICE);
2424
if (classNameList != null && classNameList.size() > 0) {
25-
String stubServiceName = PluginStubBinding.bindStubService(classNameList.get(0));
25+
String stubServiceName = PluginManagerHelper.bindStubService(classNameList.get(0));
2626
if (stubServiceName != null) {
2727
service.setComponent(new ComponentName(PluginLoader.getApplicatoin().getPackageName(), stubServiceName));
2828
}
@@ -38,7 +38,7 @@ public static ArrayList<Intent> resolveReceiver(final Intent intent) {
3838
for(String className: classNameList) {
3939
Intent newIntent = new Intent(intent);
4040
newIntent.setComponent(new ComponentName(PluginLoader.getApplicatoin().getPackageName(),
41-
PluginStubBinding.bindStubReceiver()));
41+
PluginManagerHelper.bindStubReceiver()));
4242
//hackReceiverForClassLoader检测到这个标记后会进行替换
4343
newIntent.setAction(className + CLASS_SEPARATOR + (intent.getAction() == null ? "" : intent.getAction()));
4444
result.add(newIntent);
@@ -51,7 +51,7 @@ public static ArrayList<Intent> resolveReceiver(final Intent intent) {
5151

5252
/* package */static Class resolveReceiverForClassLoader(Object msgObj) {
5353
Intent intent = (Intent) RefInvoker.getFieldObject(msgObj, "android.app.ActivityThread$ReceiverData", "intent");
54-
if (intent.getComponent().getClassName().equals(PluginStubBinding.bindStubReceiver())) {
54+
if (intent.getComponent().getClassName().equals(PluginManagerHelper.bindStubReceiver())) {
5555
String action = intent.getAction();
5656
LogUtil.d("action", action);
5757
if (action != null) {
@@ -87,7 +87,7 @@ public static ArrayList<Intent> resolveReceiver(final Intent intent) {
8787
/* package */static String resolveServiceForClassLoader(Object msgObj) {
8888
ServiceInfo info = (ServiceInfo) RefInvoker.getFieldObject(msgObj, "android.app.ActivityThread$CreateServiceData", "info");
8989
//通过映射查找
90-
String targetClassName = PluginStubBinding.getBindedPluginServiceName(info.name);
90+
String targetClassName = PluginManagerHelper.getBindedPluginServiceName(info.name);
9191
//TODO 或许可以通过这个方式来处理service
9292
//info.applicationInfo = XXX
9393

@@ -111,7 +111,7 @@ public static void resolveActivity(Intent intent) {
111111

112112
PluginActivityInfo pluginActivityInfo = pd.getActivityInfos().get(className);
113113

114-
String stubActivityName = PluginStubBinding.bindStubActivity(className, Integer.parseInt(pluginActivityInfo.getLaunchMode()));
114+
String stubActivityName = PluginManagerHelper.bindStubActivity(className, Integer.parseInt(pluginActivityInfo.getLaunchMode()));
115115

116116
intent.setComponent(
117117
new ComponentName(PluginLoader.getApplicatoin().getPackageName(), stubActivityName));

PluginCore/src/com/plugin/core/PluginLauncher.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.plugin.core;
22

33

4+
import android.app.Activity;
45
import android.app.Application;
56
import android.app.Instrumentation;
67
import android.app.Service;
@@ -9,13 +10,16 @@
910
import android.content.Intent;
1011
import android.content.IntentFilter;
1112
import android.content.res.Resources;
13+
import android.os.Build;
14+
import android.os.Bundle;
1215
import android.os.Handler;
1316
import android.os.IBinder;
1417
import android.os.Looper;
1518

1619
import com.plugin.content.LoadedPlugin;
1720
import com.plugin.content.PluginDescriptor;
1821
import com.plugin.core.app.ActivityThread;
22+
import com.plugin.core.app.AndroidAppApplication;
1923
import com.plugin.core.localservice.LocalServiceManager;
2024
import com.plugin.core.manager.PluginActivityMonitor;
2125
import com.plugin.core.manager.PluginManagerHelper;
@@ -161,6 +165,11 @@ private Application callPluginApplicationOnCreate(Context pluginContext, DexClas
161165
// 所以这里直接屏蔽掉插件的crashHandler
162166
//TODO 或许也可以做成消息链进行分发?
163167
Thread.setDefaultUncaughtExceptionHandler(old);
168+
169+
if (Build.VERSION.SDK_INT >= 14) {
170+
application.registerActivityLifecycleCallbacks(new LifecycleCallbackBrige());
171+
}
172+
164173
}
165174

166175
return application;
@@ -247,4 +256,40 @@ public boolean isRunning(String packageName) {
247256
return loadedPluginMap.get(packageName) != null;
248257
}
249258

259+
static class LifecycleCallbackBrige implements android.app.Application.ActivityLifecycleCallbacks {
260+
@Override
261+
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
262+
AndroidAppApplication.dispatchActivityCreated(PluginLoader.getApplicatoin(), activity, savedInstanceState);
263+
}
264+
265+
@Override
266+
public void onActivityStarted(Activity activity) {
267+
AndroidAppApplication.dispatchActivityStarted(PluginLoader.getApplicatoin(), activity);
268+
}
269+
270+
@Override
271+
public void onActivityResumed(Activity activity) {
272+
AndroidAppApplication.dispatchActivityResumed(PluginLoader.getApplicatoin(), activity);
273+
}
274+
275+
@Override
276+
public void onActivityPaused(Activity activity) {
277+
AndroidAppApplication.dispatchActivityPaused(PluginLoader.getApplicatoin(), activity);
278+
}
279+
280+
@Override
281+
public void onActivityStopped(Activity activity) {
282+
AndroidAppApplication.dispatchActivityStopped(PluginLoader.getApplicatoin(), activity);
283+
}
284+
285+
@Override
286+
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
287+
AndroidAppApplication.dispatchActivitySaveInstanceState(PluginLoader.getApplicatoin(), activity, outState);
288+
}
289+
290+
@Override
291+
public void onActivityDestroyed(Activity activity) {
292+
AndroidAppApplication.dispatchActivityDestroyed(PluginLoader.getApplicatoin(), activity);
293+
}
294+
}
250295
}

PluginCore/src/com/plugin/core/PluginLoader.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ public void run() {
6767
AndroidWebkitWebViewFactoryProvider.installProxy();
6868
}
6969
});
70-
PluginInjector.injectHandlerCallback();
7170
}
7271

72+
PluginInjector.injectHandlerCallback();
7373
PluginInjector.injectInstrumentation();
7474
PluginInjector.injectBaseContext(sApplication);
7575

@@ -107,7 +107,10 @@ public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
107107

108108
@Override
109109
public void onActivityDestroyed(Activity activity) {
110-
PluginStubBinding.unBindLaunchModeStubActivity(activity.getClass().getName(), activity.getIntent());
110+
Intent intent = activity.getIntent();
111+
if (intent != null && intent.getComponent() != null) {
112+
PluginManagerHelper.unBindLaunchModeStubActivity(intent.getComponent().getClassName(), activity.getClass().getName());
113+
}
111114
}
112115
});
113116
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.plugin.core.app;
2+
3+
import android.app.Activity;
4+
import android.app.Application;
5+
import android.os.Bundle;
6+
7+
import com.plugin.util.RefInvoker;
8+
9+
/**
10+
* Created by cailiming on 16/3/11.
11+
*/
12+
public class AndroidAppApplication {
13+
14+
public static void dispatchActivityCreated(Application application, Activity activity, Bundle savedInstanceState) {
15+
RefInvoker.invokeMethod(application, Application.class, "dispatchActivityCreated", new Class[]{Activity.class, Bundle.class}, new Object[]{activity, savedInstanceState});
16+
}
17+
18+
public static void dispatchActivityStarted(Application application, Activity activity) {
19+
RefInvoker.invokeMethod(application, Application.class, "dispatchActivityStarted", new Class[]{Activity.class}, new Object[]{activity});
20+
}
21+
22+
public static void dispatchActivityResumed(Application application, Activity activity) {
23+
RefInvoker.invokeMethod(application, Application.class, "dispatchActivityResumed", new Class[]{Activity.class}, new Object[]{activity});
24+
}
25+
26+
public static void dispatchActivityPaused(Application application, Activity activity) {
27+
RefInvoker.invokeMethod(application, Application.class, "dispatchActivityPaused", new Class[]{Activity.class}, new Object[]{activity});
28+
}
29+
30+
public static void dispatchActivityStopped(Application application, Activity activity) {
31+
RefInvoker.invokeMethod(application, Application.class, "dispatchActivityStopped", new Class[]{Activity.class}, new Object[]{activity});
32+
}
33+
34+
public static void dispatchActivitySaveInstanceState(Application application, Activity activity, Bundle outState) {
35+
RefInvoker.invokeMethod(application, Application.class, "dispatchActivitySaveInstanceState", new Class[]{Activity.class, Bundle.class}, new Object[]{activity, outState});
36+
}
37+
38+
public static void dispatchActivityDestroyed(Application application, Activity activity) {
39+
RefInvoker.invokeMethod(application, Application.class, "dispatchActivityDestroyed", new Class[]{Activity.class}, new Object[]{activity});
40+
41+
}
42+
}

0 commit comments

Comments
 (0)