11package com .wyjson .router .core ;
22
3+ import static com .wyjson .router .core .Constants .ROUTER_CURRENT_PATH ;
4+ import static com .wyjson .router .core .Constants .ROUTER_RAW_URI ;
5+
36import android .app .Activity ;
47import android .content .Intent ;
58import android .net .Uri ;
69import android .os .Bundle ;
10+ import android .os .Handler ;
11+ import android .os .Looper ;
712
813import androidx .annotation .NonNull ;
914import androidx .annotation .Nullable ;
1015import androidx .fragment .app .Fragment ;
16+ import androidx .lifecycle .Lifecycle ;
17+ import androidx .lifecycle .LifecycleEventObserver ;
18+ import androidx .lifecycle .LifecycleObserver ;
19+ import androidx .lifecycle .LifecycleOwner ;
20+ import androidx .lifecycle .MutableLiveData ;
21+ import androidx .lifecycle .Observer ;
1122
1223import com .wyjson .router .GoRouter ;
1324import com .wyjson .router .enums .ParamType ;
@@ -184,7 +195,7 @@ public static <T> String getRawURI(T target) {
184195 } catch (Exception e ) {
185196 throw new RuntimeException ("getRawURI() " + e .getMessage ());
186197 }
187- return bundle .getString (GoRouter . ROUTER_RAW_URI );
198+ return bundle .getString (ROUTER_RAW_URI );
188199 }
189200
190201 /**
@@ -195,12 +206,16 @@ public static <T> String getRawURI(T target) {
195206 */
196207 public static <T > String getCurrentPath (T target ) {
197208 Bundle bundle ;
198- try {
199- bundle = getBundle (target , null , null );
200- } catch (Exception e ) {
201- throw new RuntimeException ("getCurrentPath() " + e .getMessage ());
209+ if (target instanceof Bundle ) {
210+ bundle = (Bundle ) target ;
211+ } else {
212+ try {
213+ bundle = getBundle (target , null , null );
214+ } catch (Exception e ) {
215+ throw new RuntimeException ("getCurrentPath() " + e .getMessage ());
216+ }
202217 }
203- return bundle .getString (GoRouter . ROUTER_CURRENT_PATH );
218+ return bundle .getString (ROUTER_CURRENT_PATH );
204219 }
205220
206221 /**
@@ -220,9 +235,9 @@ public static <T> void inject(T target, Intent intent, Bundle bundle) {
220235 throw new RuntimeException ("inject() " + e .getMessage ());
221236 }
222237
223- String path = bundle . getString ( GoRouter . ROUTER_CURRENT_PATH );
238+ String path = getCurrentPath ( bundle );
224239 if (TextUtils .isEmpty (path )) {
225- GoRouter .logger .error (null , "[inject] path Parameter is invalid! " );
240+ GoRouter .logger .error (null , "[inject] The " + ROUTER_CURRENT_PATH + " parameter was not found in the intent " );
226241 return ;
227242 }
228243
@@ -298,6 +313,7 @@ public static synchronized void assembleRouteCard(@NonNull Card card) throws NoF
298313 CardMeta cardMeta = getCardMeta (card );
299314 if (cardMeta != null ) {
300315 card .setCardMeta (cardMeta .getType (), cardMeta .getPathClass (), cardMeta .getTag ());
316+ card .withString (ROUTER_CURRENT_PATH , card .getPath ());
301317
302318 Map <String , ParamMeta > paramsType = cardMeta .getParamsType ();
303319 Uri rawUri = card .getUri ();
@@ -313,7 +329,7 @@ public static synchronized void assembleRouteCard(@NonNull Card card) throws NoF
313329 }
314330 }
315331 // 保存原始uri
316- card .withString (GoRouter . ROUTER_RAW_URI , rawUri .toString ());
332+ card .withString (ROUTER_RAW_URI , rawUri .toString ());
317333 }
318334 }
319335 }
@@ -362,4 +378,133 @@ private static void setValue(Card card, ParamType type, String key, String value
362378 }
363379 }
364380
381+ public static <T > void registerEvent (LifecycleOwner owner , @ NonNull Class <T > type , boolean isForever , @ NonNull Observer <T > observer ) {
382+ if (!(owner instanceof Activity ) && !(owner instanceof Fragment )) {
383+ /**
384+ * 正常通过api调用是不会走到这里,除非直接调用了此方法才有可能出现这种情况
385+ * 可能是FragmentViewLifecycleOwner类型,需要导包才能直接判断,为了少导入包,就这么写判断吧.
386+ */
387+ throw new RouterException ("The owner can only be an Activity or Fragment" );
388+ }
389+ if (type == null ) {
390+ throw new RouterException ("type cannot be empty!" );
391+ }
392+
393+ String path = getCurrentPath (owner );
394+ if (TextUtils .isEmpty (path )) {
395+ GoRouter .logger .error (null , "[registerEvent] The " + ROUTER_CURRENT_PATH + " parameter was not found in the intent" );
396+ return ;
397+ }
398+
399+ String key = path + "$" + type .getCanonicalName ();
400+ MutableLiveData <T > liveData ;
401+ if (Warehouse .events .containsKey (key )) {
402+ liveData = Warehouse .events .get (key );
403+ } else {
404+ liveData = new MutableLiveData <>();
405+ Warehouse .events .put (key , liveData );
406+ addLifecycleObserver (owner , getLifecycleObserver (key ));
407+ }
408+ if (liveData != null ) {
409+ if (isForever ) {
410+ liveData .observeForever (observer );
411+ } else {
412+ liveData .observe (owner , observer );
413+ }
414+ } else {
415+ GoRouter .logger .error (null , "[registerEvent] LiveData is empty??" );
416+ }
417+ }
418+
419+ public static <T > void unRegisterEvent (LifecycleOwner owner , @ NonNull Class <T > type , Observer <T > observer ) {
420+ if (type == null ) {
421+ throw new RouterException ("type cannot be empty!" );
422+ }
423+
424+ String path = getCurrentPath (owner );
425+ if (TextUtils .isEmpty (path )) {
426+ GoRouter .logger .error (null , "[registerEvent] The " + ROUTER_CURRENT_PATH + " parameter was not found in the intent" );
427+ return ;
428+ }
429+
430+ String key = path + "$" + type .getCanonicalName ();
431+ if (Warehouse .events .containsKey (key )) {
432+ MutableLiveData <T > liveData = Warehouse .events .get (key );
433+ if (liveData != null ) {
434+ if (observer != null ) {
435+ liveData .removeObserver (observer );
436+ } else {
437+ liveData .removeObservers (owner );
438+ }
439+ if (!liveData .hasObservers ()) {
440+ Warehouse .events .remove (key );
441+ }
442+ }
443+ } else {
444+ GoRouter .logger .warning (null , "[unRegisterEvent] No observer was found for this event" );
445+ }
446+ }
447+
448+ /**
449+ * 页面销毁时删除当前页面注册的事件
450+ *
451+ * @param key
452+ * @param <T>
453+ * @return
454+ */
455+ @ NonNull
456+ private static <T > LifecycleEventObserver getLifecycleObserver (String key ) {
457+ return new LifecycleEventObserver () {
458+ @ Override
459+ public void onStateChanged (@ NonNull LifecycleOwner owner , @ NonNull Lifecycle .Event event ) {
460+ if (event == Lifecycle .Event .ON_DESTROY ) {
461+ owner .getLifecycle ().removeObserver (this );
462+ if (Warehouse .events .containsKey (key )) {
463+ MutableLiveData <T > liveData = Warehouse .events .get (key );
464+ if (liveData != null && liveData .hasObservers ()) {
465+ liveData .removeObservers (owner );
466+ }
467+ Warehouse .events .remove (key );
468+ }
469+ }
470+ }
471+ };
472+ }
473+
474+ private static void addLifecycleObserver (final LifecycleOwner lifecycleOwner , @ NonNull LifecycleObserver lifecycleObserver ) {
475+ if (lifecycleOwner == null )
476+ return ;
477+ Runnable runnable = () -> lifecycleOwner .getLifecycle ().addObserver (lifecycleObserver );
478+ if (Looper .myLooper () == Looper .getMainLooper ()) {
479+ runnable .run ();
480+ } else {
481+ new Handler (Looper .getMainLooper ()).post (runnable );
482+ }
483+ }
484+
485+ public static <T > void postEvent (@ NonNull String path , @ NonNull T value ) {
486+ if (TextUtils .isEmpty (path )) {
487+ throw new RouterException ("path Parameter is invalid!" );
488+ }
489+ if (value == null ) {
490+ throw new RouterException ("value cannot be empty!" );
491+ }
492+ String key = path + "$" + value .getClass ().getCanonicalName ();
493+ if (Warehouse .events .containsKey (key )) {
494+ MutableLiveData <T > liveData = Warehouse .events .get (key );
495+ if (liveData != null ) {
496+ if (Looper .myLooper () == Looper .getMainLooper ()) {
497+ liveData .setValue (value );
498+ } else {
499+ liveData .postValue (value );
500+ }
501+ } else {
502+ GoRouter .logger .error (null , "[postEvent] LiveData is empty??" );
503+ }
504+ } else {
505+ GoRouter .logger .warning (null , "[postEvent] No observer was found for this event" );
506+ }
507+ }
508+
509+
365510}
0 commit comments