package Ġio . github . chen fe i 0 9 2 8 . reflect Ċ Ċ import Ġjava . lang . invoke . Method Handles Ċ import Ġjava . lang . reflect . Proxy Ċ Ċ /** Ċ Ġ* ĠåĪĽå»º åĨħéĥ¨ ä½¿çĶ¨ éĽĨåĲĪ æĿ¥ ä¿ĿåŃĺ çĽĳåĲ¬ åĻ¨ çļĦ çĽĳåĲ¬ åĻ¨ ä»£çĲĨ Ċ Ġ* Ġ ä¼łåħ¥ ä¸Ģä¸ª éĽĨåĲĪ æĿ¥ ä¿ĿåŃĺ çĽĳåĲ¬ åĻ¨ å®ŀçİ° ï¼Į å°Ĩ è¿ĶåĽŀ è¯¥ çĽĳåĲ¬ åĻ¨ çļĦä¸Ģä¸ª ä»£çĲĨ å®ŀä¾ĭ Ċ Ġ* Ċ Ġ* Ġ@ author ĠChen Fe i ( chen fe i 0 9 2 8 @ gmail . com ) Ċ Ġ* Ġ@ date Ġ 2 0 2 0 - 0 9 - 2 1 Ġ 1 4 : 1 1 Ċ Ġ*/ Ċ object ĠList eners Proxy Ġ{ ĊĊĠĠĠ Ġinline Ġfun Ġ< re ified ĠT Ġ: ĠAny > Ġnew Listeners Proxy ( listener Imp ls : ĠMutable Collection < T > Ġ= Ġarray ListOf ()) Ġ= ĊĠĠĠĠĠĠĠ Ġnew Listeners Proxy ( T :: class . java , Ġlistener Imp ls ) ĊĊĠĠĠ Ġfun Ġ< T Ġ: ĠAny > Ġnew Listeners Proxy ( ĊĠĠĠĠĠĠĠ Ġclazz : ĠClass < T >, Ġlistener Imp ls : ĠMutable Collection < T > Ġ= Ġarray ListOf () ĊĠĠĠ Ġ): ĠT Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠProxy . new Proxy Instance ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclazz . class Loader , ĠarrayOf ( clazz , ĠMutable Collection :: class . java ) ĊĠĠĠĠĠĠĠ Ġ) Ġ{ Ġproxy , Ġmethod , Ġargs Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIf Ġthe Ġmethod Ġis Ġa Ġmethod Ġfrom ĠObject Ġthen Ġdefer Ġto Ġnormal Ġinvocation . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( method . decl aring Class Ġ== ĠAny :: class . java ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ new Proxy Instance Ġmethod . safe Invoke ( this , Ġargs ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( android . os . Build . VERSION . SDK _ INT Ġ>= Ġandroid . os . Build . VERSION _ CODES . O Ġ&& Ġmethod . is Default ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠBecause Ġthe Ġservice Ġinterface Ġmight Ġnot Ġbe Ġpublic , Ġwe Ġneed Ġto Ġuse Ġa ĠMethod Handle Ġlookup ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthat Ġignores Ġthe Ġvisibility Ġof Ġthe Ġdeclaring Class . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġconstructor Ġ= ĠMethod Handles . Lookup :: class . java . getDeclared Constructor ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠClass :: class . java , ĠInt :: class . java Primitive Type ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconstructor . is Accessible Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ new Proxy Instance Ġconstructor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. newInstance ( method . decl aring Class , Ġ- 1 Ġ/* Ġtrusted Ġ*/) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. un reflect Special ( method , Ġmethod . decl aring Class ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. bind To ( proxy ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( args Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinvoke With Arguments () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinvoke With Arguments (* args ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġå¦Ĥæŀľ è¯¥ æĸ¹æ³ķ æĺ¯ éĽĨåĲĪ æİ¥åı£ å®ļä¹ī çļĦæĸ¹æ³ķ ï¼Į å¯¹ çĽĳåĲ¬ åĻ¨ éĽĨåĲĪ è¿Ľè¡Į æĵįä½ľ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( method . decl aring Class Ġ== ĠMutable Collection :: class . java ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ new Proxy Instance Ġmethod . safe Invoke ( listener Imp ls , Ġargs ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ åĲ¦åĪĻ æī§è¡Į çĽĳåĲ¬ åĻ¨ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġrst : ĠAny ? Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlistener Imp ls . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrst Ġ= Ġmethod . safe Invoke ( it , Ġargs ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ new Proxy Instance Ġrst ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġas ĠT ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġ< T Ġ: ĠAny > Ġnew Empty Listener ( clazz : ĠClass < T >): ĠT Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠProxy . new Proxy Instance ( clazz . class Loader , ĠarrayOf ( clazz )) Ġ{ Ġ_, Ġ_, Ġ_ Ġ-> ĊĠĠĠĠĠĠĠ Ġ} Ġas ĠT ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġå°Ĩ å¤ļä¸ª çĽĳåĲ¬ åĻ¨ çļĦ åĽŀè°ĥ å°ģè£ħ ä¸º ä¸Ģä¸ª çĽĳåĲ¬ åĻ¨ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġ< T Ġ: ĠAny > Ġnew Listeners Proxy ( clazz : ĠClass < T >, Ġvar arg Ġlisteners : ĠT ): ĠT Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfind Ġ= Ġlisteners . find Ġ{ Ġit Ġis ĠMutable Collection < *> Ġ} Ġ?: Ġnew Listeners Proxy ( clazz ) ĊĠĠĠĠĠĠĠ Ġval Ġmutable Collection Ġ= Ġfind Ġas ĠMutable Collection < T > ĊĠĠĠĠĠĠĠ Ġfor Ġ( listener Ġin Ġlisteners ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( find Ġ!== Ġlistener ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmutable Collection . add ( listener ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfind ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinline Ġfun Ġ< re ified ĠT Ġ: ĠAny > Ġnew Impl By Getter ( getter : ĠLazy < T >): ĠT Ġ= ĊĠĠĠĠĠĠĠ Ġnew Impl By Getter ( T :: class . java ) Ġ{ Ġgetter . value Ġ} ĊĊĠĠĠ Ġinline Ġfun Ġ< re ified ĠT Ġ: ĠAny > Ġnew Impl By Getter ( cross inline Ġgetter : Ġ() Ġ-> ĠT ): ĠT Ġ= ĊĠĠĠĠĠĠĠ Ġnew Impl By Getter ( T :: class . java , Ġgetter ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠåĪĽå»º ä¸Ģä¸ª æ ĩĴ èİ·åıĸ çļĦ ä»£çĲĨ å®ŀçİ° ï¼Į è¯¥ ä»£çĲĨ å¯¹è±¡ åı¯èĥ½ ä¸įä¼ļ å®ŀ æĹ¶ èİ·åıĸ åĪ° ( éĢļè¿ĩ ä¸Ģ æ®µ ä»£çłģ æĿ¥ find æĪĸ åĪĽå»º ) æĪĸ ä¸º æ ĩĴ åĬłè½½ ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinline Ġfun Ġ< T Ġ: ĠAny > Ġnew Impl By Getter ( clazz : ĠClass < T >, Ġcross inline Ġgetter : Ġ() Ġ-> ĠT ): ĠT Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠProxy . new Proxy Instance ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclazz . class Loader , ĠarrayOf ( clazz ) ĊĠĠĠĠĠĠĠ Ġ) Ġ{ Ġ_, Ġmethod , Ġargs Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ new Proxy Instance Ġmethod . safe Invoke ( getter (), Ġargs ) ĊĠĠĠĠĠĠĠ Ġ} Ġas ĠT ĊĠĠĠ Ġ} Ċ } Ċ