2525import android .content .pm .ApplicationInfo ;
2626import android .content .res .AssetManager ;
2727import android .content .res .Resources ;
28- import android .os .Handler ;
2928import android .os .Looper ;
30- import android .util .Log ;
3129
3230import java .io .File ;
3331import java .io .FileFilter ;
4543import androidx .pluginmgr .environment .PluginClassLoader ;
4644import androidx .pluginmgr .environment .PluginContext ;
4745import androidx .pluginmgr .environment .PluginInstrumentation ;
46+ import androidx .pluginmgr .selector .DefaultActivitySelector ;
47+ import androidx .pluginmgr .selector .DynamicActivitySelector ;
4848import androidx .pluginmgr .utils .FileUtil ;
4949import androidx .pluginmgr .utils .PluginManifestUtil ;
50+ import androidx .pluginmgr .utils .Trace ;
5051import androidx .pluginmgr .verify .PluginNotFoundException ;
5152import androidx .pluginmgr .verify .PluginOverdueVerifier ;
5253import androidx .pluginmgr .verify .SimpleLengthVerifier ;
5960 */
6061public class PluginManager implements FileFilter {
6162
62- private static final String TAG = PluginManager .class .getSimpleName ();
63-
6463 /**
6564 * 插件管理器单例
6665 */
@@ -94,9 +93,7 @@ public class PluginManager implements FileFilter {
9493 */
9594 private PluginOverdueVerifier pluginOverdueVerifier = new SimpleLengthVerifier ();
9695
97- private PluginInstrumentation pluginInstrumentation ;
98-
99- private Handler uiHandler ;
96+ private DynamicActivitySelector activitySelector = DefaultActivitySelector .getDefault ();
10097
10198
10299 /**
@@ -113,13 +110,10 @@ private PluginManager(Context context) {
113110 dexOutputPath = optimizedDexPath .getAbsolutePath ();
114111 dexInternalStoragePath = context
115112 .getDir (Globals .PRIVATE_PLUGIN_ODEX_OUTPUT_DIR_NAME , Context .MODE_PRIVATE );
116- uiHandler = new Handler (Looper .getMainLooper ());
117113 DelegateActivityThread delegateActivityThread = DelegateActivityThread .getSingleton ();
118114 Instrumentation originInstrumentation = delegateActivityThread .getInstrumentation ();
119- if (originInstrumentation instanceof PluginInstrumentation ) {
120- pluginInstrumentation = (PluginInstrumentation ) originInstrumentation ;
121- } else {
122- pluginInstrumentation = new PluginInstrumentation (originInstrumentation );
115+ if (!(originInstrumentation instanceof PluginInstrumentation )) {
116+ PluginInstrumentation pluginInstrumentation = new PluginInstrumentation (originInstrumentation );
123117 delegateActivityThread .setInstrumentation (pluginInstrumentation );
124118 }
125119 }
@@ -150,10 +144,10 @@ private static void checkInit() {
150144 */
151145 public static void init (Context context ) {
152146 if (SINGLETON != null ) {
153- Log . w ( TAG , "PluginManager have been initialized, YOU needn't initialize it again!" );
147+ Trace . store ( "PluginManager have been initialized, YOU needn't initialize it again!" );
154148 return ;
155149 }
156- Log . i ( TAG , "init PluginManager..." );
150+ Trace . store ( "init PluginManager..." );
157151 SINGLETON = new PluginManager (context );
158152 }
159153
@@ -233,7 +227,7 @@ private PlugInfo removePlugByPkg(String pkg) {
233227 public Collection <PlugInfo > loadPlugin (final File pluginSrcDirFile )
234228 throws Exception {
235229 if (pluginSrcDirFile == null || !pluginSrcDirFile .exists ()) {
236- Log . e ( TAG , "invalidate plugin file or Directory :"
230+ Trace . store ( "invalidate plugin file or Directory :"
237231 + pluginSrcDirFile );
238232 return null ;
239233 }
@@ -311,7 +305,7 @@ private PlugInfo buildPlugInfo(File pluginApk, String pluginId,
311305 Application app = makeApplication (pluginClassLoader , appClassName );
312306 attachBaseContext (info , app );
313307 info .setApplication (app );
314- Log . i ( TAG , "buildPlugInfo: " + info );
308+ Trace . store ( "Build pluginInfo => " + info );
315309 return info ;
316310 }
317311
@@ -331,7 +325,7 @@ private void attachBaseContext(PlugInfo info, Application app) {
331325 *
332326 * @param pluginClassLoader 类加载器
333327 * @param appClassName 类名
334- * @return
328+ * @return 插件App
335329 */
336330 private Application makeApplication (PluginClassLoader pluginClassLoader , String appClassName ) {
337331 if (appClassName != null ) {
@@ -340,20 +334,25 @@ private Application makeApplication(PluginClassLoader pluginClassLoader, String
340334 } catch (Throwable ignored ) {
341335 }
342336 }
343-
337+ //default application
344338 return new Application ();
345339 }
346340
347341
348342 /**
349343 * 将Apk复制到私有目录
344+ * @see PluginOverdueVerifier
345+ * 可设置插件覆盖校检器来验证插件是否需要覆盖
350346 *
351347 * @param pluginApk 插件apk原始路径
352348 * @param targetPutApk 要拷贝到的目标位置
353349 */
354350 private void copyApkToPrivatePath (File pluginApk , File targetPutApk ) {
355- if (targetPutApk .exists () && pluginOverdueVerifier != null && pluginOverdueVerifier .isOverdue (pluginApk , targetPutApk )) {
356- return ;
351+ if (pluginOverdueVerifier != null ) {
352+ //仅当私有目录中插件已存在时需要检验
353+ if (targetPutApk .exists () && pluginOverdueVerifier .isOverdue (pluginApk , targetPutApk )) {
354+ return ;
355+ }
357356 }
358357 FileUtil .copyFile (pluginApk , targetPutApk );
359358 }
@@ -412,44 +411,134 @@ public boolean accept(File pathname) {
412411 //=================启动插件相关方法=======================
413412 //======================================================
414413
415- public void startMainActivity (Context from , PlugInfo plugInfo ) {
414+
415+ /**
416+ * 启动插件的主Activity
417+ *
418+ * @param from fromContext
419+ * @param plugInfo 插件Info
420+ * @param intent 通过此Intent可以向插件传参, 可以为null
421+ */
422+ public void startMainActivity (Context from , PlugInfo plugInfo , Intent intent ) {
416423 if (!pluginPkgToInfoMap .containsKey (plugInfo .getPackageName ())) {
417424 return ;
418425 }
419426 ActivityInfo activityInfo = plugInfo .getMainActivity ().activityInfo ;
420427 if (activityInfo == null ) {
421428 throw new ActivityNotFoundException ("Cannot find Main Activity from plugin." );
422429 }
423- String mainActivityName = plugInfo .getMainActivity ().activityInfo .name ;
424- CreateActivityData createActivityData = new CreateActivityData (mainActivityName , plugInfo .getPackageName ());
425- Intent intent = new Intent (from , Globals .selectDynamicActivity (activityInfo ));
426- intent .putExtra (Globals .FLAG_ACTIVITY_FROM_PLUGIN , createActivityData );
427- from .startActivity (intent );
430+ startActivity (from , plugInfo , activityInfo , intent );
431+
432+ }
433+
434+ /**
435+ * 启动插件的主Activity
436+ *
437+ * @param from fromContext
438+ * @param plugInfo 插件Info
439+ */
440+ public void startMainActivity (Context from , PlugInfo plugInfo ) {
441+ startMainActivity (from , plugInfo , null );
428442 }
429443
444+ /**
445+ * 启动插件的主Activity
446+ * @param from fromContext
447+ * @param pluginPkgName 插件包名
448+ * @throws PluginNotFoundException 该插件未加载时抛出
449+ * @throws ActivityNotFoundException 插件Activity信息找不到时抛出
450+ */
430451 public void startMainActivity (Context from , String pluginPkgName ) throws PluginNotFoundException , ActivityNotFoundException {
431452 PlugInfo plugInfo = tryGetPluginInfo (pluginPkgName );
432453 startMainActivity (from , plugInfo );
433454 }
434455
435- public void startActivity (Context from , PlugInfo plugInfo , String targetActivity ) {
436- ActivityInfo activityInfo = plugInfo .findActivityByClassName (targetActivity );
456+
457+ /**
458+ * 启动插件的指定Activity
459+ *
460+ * @param from fromContext
461+ * @param plugInfo 插件信息
462+ * @param activityInfo 要启动的插件activity信息
463+ * @param intent 通过此Intent可以向插件传参, 可以为null
464+ */
465+ public void startActivity (Context from , PlugInfo plugInfo , ActivityInfo activityInfo , Intent intent ) {
437466 if (activityInfo == null ) {
438- throw new ActivityNotFoundException ("Cannot find " + targetActivity + " from plugin, could you declare this Activity in plugin?" );
467+ throw new ActivityNotFoundException ("Cannot find ActivityInfo from plugin, could you declare this Activity in plugin?" );
468+ }
469+ if (intent == null ) {
470+ intent = new Intent ();
439471 }
440- CreateActivityData createActivityData = new CreateActivityData (targetActivity , plugInfo .getPackageName ());
441- Intent intent = new Intent (from , Globals .selectDynamicActivity (activityInfo ));
472+ CreateActivityData createActivityData = new CreateActivityData (activityInfo . name , plugInfo .getPackageName ());
473+ intent . setClass (from , activitySelector .selectDynamicActivity (activityInfo ));
442474 intent .putExtra (Globals .FLAG_ACTIVITY_FROM_PLUGIN , createActivityData );
443475 from .startActivity (intent );
444476 }
445477
478+
479+ public DynamicActivitySelector getActivitySelector () {
480+ return activitySelector ;
481+ }
482+
483+ public void setActivitySelector (DynamicActivitySelector activitySelector ) {
484+ if (activitySelector == null ) {
485+ activitySelector = DefaultActivitySelector .getDefault ();
486+ }
487+ this .activitySelector = activitySelector ;
488+ }
489+
490+ /**
491+ * 启动插件的指定Activity
492+ *
493+ * @param from fromContext
494+ * @param plugInfo 插件信息
495+ * @param targetActivity 要启动的插件activity类名
496+ * @param intent 通过此Intent可以向插件传参, 可以为null
497+ */
498+ public void startActivity (Context from , PlugInfo plugInfo , String targetActivity , Intent intent ) {
499+ ActivityInfo activityInfo = plugInfo .findActivityByClassName (targetActivity );
500+ startActivity (from , plugInfo , activityInfo , intent );
501+ }
502+
503+ /**
504+ * 启动插件的指定Activity
505+ *
506+ * @param from fromContext
507+ * @param plugInfo 插件信息
508+ * @param targetActivity 要启动的插件activity类名
509+ */
510+ public void startActivity (Context from , PlugInfo plugInfo , String targetActivity ) {
511+ startActivity (from , plugInfo , targetActivity , null );
512+ }
513+
514+
515+ /**
516+ * 启动插件的指定Activity
517+ *
518+ * @param from fromContext
519+ * @param pluginPkgName 插件包名
520+ * @param targetActivity 要启动的插件activity类名
521+ */
446522 public void startActivity (Context from , String pluginPkgName , String targetActivity ) throws PluginNotFoundException , ActivityNotFoundException {
523+ startActivity (from , pluginPkgName , targetActivity , null );
524+ }
525+
526+ /**
527+ * 启动插件的指定Activity
528+ *
529+ * @param from fromContext
530+ * @param pluginPkgName 插件包名
531+ * @param targetActivity 要启动的插件activity类名
532+ * @param intent 通过此Intent可以向插件传参, 可以为null
533+ */
534+ public void startActivity (Context from , String pluginPkgName , String targetActivity , Intent intent ) throws PluginNotFoundException , ActivityNotFoundException {
447535 PlugInfo plugInfo = tryGetPluginInfo (pluginPkgName );
448- startActivity (from , plugInfo , targetActivity );
536+ startActivity (from , plugInfo , targetActivity , intent );
449537 }
450538
539+
451540 public void dump () {
452- Log . d ( TAG , pluginPkgToInfoMap .size () + " Plugins is loaded, " + Arrays .toString (pluginPkgToInfoMap .values ().toArray ()));
541+ Trace . store ( pluginPkgToInfoMap .size () + " Plugins is loaded, " + Arrays .toString (pluginPkgToInfoMap .values ().toArray ()));
453542 }
454543
455544 /**
0 commit comments