序文
GT ライブラリは、データ送信用の新しいフレームワークをついにリリースしました。現在、データ送信用の新しいフレームワークは GT と呼ばれています。EventBus のコア実装原理は、市場で人気のあるEventBus
の実装原理と同じです。
EventBus にも明らかな欠陥があります。EventBusでは、イベントの配布はアノテーション関数のパラメーターの種類によって決定されます。そのため、イベントの発行が多用される場合、特に複数のサブスクライバーと複数の同一パラメーターがある場合、イベントの配布を取得することが困難になります。パブリッシャはメッセージ フローの整理を開始しますが、どのサブスクライバが問題の原因となっているメッセージを受け入れて処理したかをすぐに見つけることができないため、参加者は通知プロセス全体を十分に理解する必要があります。これは、プログラム コードが中程度の場合には妥当な要件ですが、プログラムが大きすぎる場合には負担になります。EventBusには必要なコメント情報を必ず書き込んでください。そうしないと、その後の業務引き継ぎで無用なトラブルが発生します。
それでは、GT.EventBus を簡単に紹介しましょう。
目次
GT.EventBus には、最初に理解する必要がある 3 つの主要な要素があります。
イベント: イベント。任意のタイプのオブジェクトまたはキャラクターにすることができます。
もちろん、GT ライブラリにカプセル化されたアーキテクチャは、まず GT ライブラリに依存する必要があります。
依存関係の詳細なチュートリアルについては、以下を参照してください。
GT.EventBus と EventBus の違い:
(1). (最大の違い) イベント発行時にイベントクラスを定義する必要がないGT.EventBus は、EventBus がイベントクラスを介してイベントを発行しなければならないルールを取り消し、より柔軟な発行方法を採用し、ポイントする領域をカスタマイズし、イベントのパブリッシュ (詳しくは後ほど紹介します) 。オリジナルの EventBus では、サブスクライバーが複数あり、同じパラメーターがある場合、パブリッシャー時点からのメッセージ フローを整理することが難しく、迅速に実行できないという問題が解決されます。どのサブスクライバがメッセージを処理しているかを確認します
(2)。イベントの発行後にサブスクライバが戻り値を持っている場合は、イベントを発行することで戻り値を取得できます(ただし、スレッド制限があり、内部スレッド プールが使用されます)。 (3) .
同じイベントに異なるイベント ID を設定でき、サブスクライバーが受け取るイベントをより正確に発行できます。
(4).共通イベントの表示、スティッキー イベントの表示、単一のスティッキー イベントの削除、スティッキー イベントのクリアなどをサポートします。
(5). GT.EventBus はクロスプロセス送信をサポートしますが、元の EventBus はサポートしません。
(6). 親クラス継承サブスクライバーのトラバースは現時点ではサポートされていないため、後で改善される可能性があります。
GT.EventBus の簡単な紹介:
GT.EventBus は、Android 向けに最適化されたパブリッシュ/サブスクライブ イベント バスです。アプリケーション内のコンポーネント間、およびコンポーネントとバックグラウンド スレッド間の通信を簡素化します。利点は、低いオーバーヘッド、より洗練されたコード、送信側と受信側のカップリングのソリューションです。以前のActivityとActivityの間でよく使うIntentやBundleなどを利用してデータをやり取りすることができます
FragmentとFragmentが相互作用する場合は少し面倒になります 対応するActivityからタブなどでFragmentの参照を取得する必要がありますデータを取得する
か、それを処理するためにブロードキャストも使用します。たとえば、GT ライブラリは以前に GT.DataSend受信フレームワークをリリースしました。ここで使用される中心原理は、ブロードキャストを介してデータを転送することですが、ブロードキャストの使用はアクティビティと切り離すことができません。少し面倒ですが、2 つのデータ転送フレームワークにはそれぞれ長所と短所があります。
渡されるデータがシリアル化する必要があるエンティティクラスの場合、当然コストが少し高くなりますが、今日は GT.EventBus の使用方法を学習します。
GT.EventBus には、最初に理解する必要がある 3 つの主要な要素があります。
イベント: イベント。任意のタイプのオブジェクトまたはキャラクターにすることができます。
イベントサブスクライバー、サブスクライバー:
eventKey-(新機能-理解できなくても問題ありません。後ほどグラフィックで説明します)
* サブスクライバ キー ラベルを指定します。指定しない場合、メソッドはデフォルトでサブスクライバ キー ラベルと呼ばれます
* 注: EvenKey をカスタマイズする場合は記述しないでください。この文字はキーワードです。この文字はキーワードです。
※イースターエッグはイベント発行後にサブスクライバーの戻り値を受け取ることができますが、サブスクライバーとパブリッシャーが同じスレッドに存在しないか、または存在する場合は、発行されたイベントに 2 人のサブスクライバーがいる場合、イベントは発行できません。 スレッドはサブスクライバーの戻り値を受け取ります。
*
*イベントの発行メソッド 1: 純粋なeventData
* イベントをサブスクライバー マネージャー全体に発行します。
*
*イベントの発行メソッド 2: Pure String
* Single文字列表現、登録されているすべての領域で一致 このeventKey固有識別子に一致し、イベントを公開します
*複数の文字列表現、登録されているすべての領域でこれらの複数のeventKey固有識別子と一致し、イベントを公開します
*
*イベントの公開メソッド3: Pure Class
*単一クラス表現、現在の Class クラスで、Subscribe アノテーションによって識別されるすべてのメソッドを検索し、「パラメーター マッチング テスト」を実行してイベント
* 複数のクラス表現をパブリッシュします。これらの Class クラスの Subscribe アノテーションによって識別されるすべてのメソッドを検索し、「パラメーター マッチング テスト」を実行してイベントを発行します。
*
* イベントの発行方法 4: 文字列とクラスの混合型。混合の順序は便利です (ただし、スティッキー イベントを削除するときのキーは、アルファベット順も含め、発行されたイベントのキーとまったく同じである必要があります) *
単一混合タイプのグループは、このクラスでイベントを発行するためのeventKey名のメソッドを検索します。
* 複数の混合タイプのグループが表すため、これらのクラスでeventKey名のメソッドを見つけてイベントを発行します
5 つのスレッド モデルは次のとおりです。
(1) POSTING (デフォルト):現在のスレッドでイベントを処理します
(2) MAIN: イベントがメイン スレッドとしてポストされた場合はメイン スレッドで処理し、それ以外の場合はメイン スレッドに切り替えて処理します
(3) MAIN_ORDERED :どのスレッドであっても、メイン スレッドに直接切り替えてイベントを処理します
(4) 背景:イベントが子スレッドとして公開されている場合は、子スレッドで処理します。それ以外の場合は、新しい子スレッドが処理します
(5) ASYNC:どのスレッド上でも、新しい子スレッドが処理します。
スティッキー イベントをサポートするかどうか。デフォルトは falsesticky です。
イベントを最初に発行してから受信できるようにするメカニズム。
サブスクリプション方式の優先度はデフォルトで 0 です。優先度:
複数のイベント サブスクリプション メソッドが同じイベントを受信できます。
イベントが公開された後、スレッドを切り替えることなく、最も高い優先度を持つサブスクライバーが最初にイベントを受信します。イベントの公開時にサブスクライバーがスレッドを切り替えた場合、最初の優先度は保証されませんイベントを受け取るには
イベント配信をキャンセルするには、cancelEventdelivery:
イベントの配信がキャンセルされると、それ以降は下流にイベントが配信されなくなりますが、一般的にはサブスクリプションメソッドの優先度と連携し、優先度+イベント配信キャンセルでインターセプトチェーンを構築できます。
イベント発行者、発行者:
イベントは任意のスレッドのどこにでも送信でき、GT.EventBus の post(Object) メソッドを直接呼び出すことができます。GT.EventBus オブジェクトはそれ自体でインスタンス化できますが、通常は GT.EventBus.getDefault() を使用するだけです。ポスト関数
パラメータのタイプは、対応するタイプのイベントをサブスクライブする関数を自動的に呼び出します。
プロセス間でデータを渡す、postAcrossProcessess:
新バージョンv1.4.2.4以降では、マルチプロセス転送データに対応しました。
GTライブラリに依存
もちろん、GT ライブラリにカプセル化されたアーキテクチャは、まず GT ライブラリに依存する必要があります。
依存関係の詳細なチュートリアルについては、以下を参照してください。
次に GT.EventBus の基本的な使い方を見てみましょう 実は、使い方は市販されている一般的な EventBus とほぼ同じで、GT を追加するだけです。
public class MainActivity extends AppCompatActivity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = findViewById(R.id.tv);
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//发送事件
GT.EventBus.getDefault().post("GT库不止这一个好用的框架!");
}
});
//注册订阅者
GT.EventBus.getDefault().register(this);
}
//处理事件
@GT.EventBus.Subscribe
public void demo(String name){
tv.setText(name);
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消注册订阅
GT.EventBus.getDefault().unregister(this);
}
}
レンダリング:
GT.EventBus と EventBus の使用にほとんど違いがないことを確認してください。唯一の違いは、イベントの発行とイベントの処理のパラメーターにあります。これは、GT.EventBus と EventBus の最大の違いは、GT.EventBus が EventBus をキャンセルすることであるためです。イベントの公開: イベントを公開するためのルールは、より柔軟な公開方法を使用し、ポイントするエリアをカスタマイズして、イベントを公開するイベント クラスを通じて公開する必要があります。
次に、必要なイベント クラスのルールがキャンセルされたため、GT.EventBus がイベントを発行するために使用する方法を見てみましょう。
まずはポストパラメータのルールを見てみましょう
/**
* TODO 注意:在自定义 evenKey 时请不要写入 "_GT_" 字符,该字符为关键字
* TODO 彩蛋 发布事件后可接收到订阅者返回值,但如果订阅者与发布者不在同一线程中或
* 发布的事件中有两个订阅者,将无法在发布事件的线程接收到订阅者的返回值
*
* 发布事件 方式一:纯 eventData
* 将该事件发布到整个 订阅者管理器
* <p>
* 发布事件 方式二:纯 String
* 单个 String表示,在所有注册的区域里匹配到这 eventKey 唯一标识,并发布事件
* 多个 String表示,在所有注册的区域里匹配这 多个eventKey 唯一标识,并发布事件
* <p>
* 发布事件 方式三:纯 Class
* 单个 Class表示,在当前Class类中找到被 Subscribe注解标识
* 过的所有方法进行"参数匹配试"发布事件
* 多个 Class表示,在这些Class类中找到被 Subscribe注解标识
* 过的所有方法进行"参数匹配试"发布事件
* <p>
* 发布事件 方式四:String 与 Class 混合类型,混合的顺序可顺便
* (但在删除粘性事件时的key必须与发布事件的key一模一样,包括字母顺序)
* 单组 混合类型表示,在这 class 中 寻找到 该 eventKey 名称的方法进行发布事件
* 多组 混合类型表示,在这些 class 中 寻找到 这些 eventKey 名称的方法进行发布事件
* <p>
*/
これはevenKeyパラメータのルールです。理解していなくても問題ありません。パラメータを確認するために投稿を深く見てみましょう。
パラメータ 1: オブジェクト EventData
発行されたイベント (サポートされるパラメータは 1 つだけです。複数のパラメータを渡す必要がある場合は、バンドル、リスト、マップ、エンティティ クラス Bean などを渡すことができます)
パラメータ 2: オブジェクト...eventKeys
送信エリアを指定します (入力されていない場合、イベントはデフォルトですべてのサブスクライバーに公開されます)
以前にイベントを公開する方法では、 eventData パラメーターを入力するだけだったので、すべてのサブスクライバーに公開されるイベントは最初の公開方法に従って公開されます。
//发布事件 方式一:纯 eventData,将该事件发布到整个 订阅者管理器
GT.EventBus.getDefault().post("GT库不止这一个好用的框架!");
世界情勢を公開するとどんな影響があるのでしょうか?写真を見てみましょう
緑の線は受信できますが、赤の線はパラメータの種類が異なるため受信できません。
次に、イベントをいずれかのメソッドに個別に投稿したいのですが、すべてを投稿したくない場合はどうすればよいでしょうか?
次に、イベントを公開する 2 番目の方法を使用する必要があります。
//发布事件 方式二:纯 String
//单个 String表示,在所有注册的区域里匹配到这 eventKey 唯一标识,并发布事件
//多个 String表示,在所有注册的区域里匹配这 多个eventKey 唯一标识,并发布事件
GT.EventBus.getDefault().post("GT库不止这一个好用的框架!","demo");
メソッド名を追加するだけです。次に、これら 3 つのメソッドのうち 2 つのイベントを公開します。デモの後にイベントを公開するメソッドを追加するだけです。
//发布事件 方式二:纯 String
//单个 String表示,在所有注册的区域里匹配到这 eventKey 唯一标识,并发布事件
//多个 String表示,在所有注册的区域里匹配这 多个eventKey 唯一标识,并发布事件
GT.EventBus.getDefault().post("GT库不止这一个好用的框架!","demo","aaa");
非常に簡単です。コードにコメントされたリリース イベント ルールが理解できます。
グローバルにリリースされているため、他のアクティビティやページに同じメソッド名とパラメータがある場合、MainActivity2 のメソッドではなく、MainActivity のメソッドのみを投稿したいのですが、どうすればよいか考えたことはありませんか?
イベントを発行する 3 番目の方法を使用します: 0
//发布事件 方式三:纯 Class
//单个 Class表示,在当前Class类中找到被 Subscribe注解标识,过的所有方法进行"参数匹配试"发布事件
//多个 Class表示,在这些Class类中找到被 Subscribe注解标识,过的所有方法进行"参数匹配试"发布事件
GT.EventBus.getDefault().post("GT库不止这一个好用的框架!", MainActivity.class);
レンダリング:
ログ:
GT_i: com.example.myapplication.(MainActivity.java:32) demo(): 接收到:GT库不止这一个好用的框架!
GT_i: com.example.myapplication.(MainActivity.java:38) aaa(): 接收到:GT库不止这一个好用的框架!
MainActivity の demo() メソッドと aaa() メソッドの両方が呼び出され、イベントが受信されるのに、なぜ bbb() メソッドがイベントを受信しなかったのでしょうか? bbb() メソッドのパラメーターの型が異なるためです。 、イベントは bbb() メソッドに対して公開されません。
質問: MainActivity2 のデモ メソッドにイベントを正確に発行したいのですが、他のメソッドでイベントを受信したくない場合はどうすればよいですか?
次に、イベントを公開する 4 番目の方法を使用できます。
//发布事件 方式四:String 与 Class 混合类型,在发布事件时的混合类型顺序可顺便
//(但在删除粘性事件时的key必须与发布事件的key一模一样,包括字母顺序)
//单组 混合类型表示,在这 class 中 寻找到 该 eventKey 名称的方法进行发布事件
//多组 混合类型表示,在这些 class 中 寻找到 这些 eventKey 名称的方法进行发布事件
GT.EventBus.getDefault().post("GT库不止这一个好用的框架!", MainActivity.class, "demo");
レンダリング:
ログ:
com.example.myapplication.(MainActivity.java:32) demo(): 接收到:GT库不止这一个好用的框架!
このようにして、正確なリリース イベントを実現しました。ここまでで、GT.EvenBus のリリース イベントがすべて揃ったと思いますか? 特別なメソッドを特殊化できる、より便利なカスタム リリース イベント識別子もあります。
MainActivityのデモメソッドに「GT」というタグを追加します。
それでは、MainActivity2 でイベントを正確にリリースしてみましょう
レンダリング
はい、MainActivity2 によってリリースされたイベントが MainActivity のデモ メソッドを受け取っていないことが判明しました。
(eventKey = "GT")パラメーターをクリックして、 その理由を確認してみましょう。
当然のことですが、以前はこの値を設定していなかったので、GT.EventBus はクラスのメソッド名をデフォルトで識別子としてeventKeyに設定しました。今回はこの識別子を手動で設定します。つまり、イベントをこのメソッドに発行する必要もあります。新しく設定されたeventKey識別子に従って発行し、
イベントを発行するコードを変更してみましょう。
変更点:
//发布事件 方式四:String 与 Class 混合类型,在发布事件时的混合类型顺序可顺便
//(但在删除粘性事件时的key必须与发布事件的key一模一样,包括字母顺序)
//解释:向MainActivity.class类中的 GT 标识发布事件,传递的参数类型为String
GT.EventBus.getDefault().post("GT库不止这一个好用的框架!", MainActivity.class, "GT");
レンダリングを見てみましょう。
サブスクライバの戻り値を取得する
次に、実行後にサブスクライバーによって返されたデータを取得する、非常に便利で興味深い関数を学習しましょう。
オリジナルの EventBus はこれをサポートしていません。これは GT.EventBus の独自の機能です。
サブスクライバーからデータを返すコードを見てみましょう。
イベントのパブリッシャーがサブスクライバーから返されたデータをどのように受け取るかを見てみましょう。
レンダリング:
イベントのパブリッシャーのすぐ後ろで受信パラメータがサブスクライバの戻り値になるのはすごいと思いませんか? この受信パラメータは条件付きですが、10 人以上のサブスクライバが同時にパラメータを返した場合、どれを受信すればよいでしょうか?
したがって、サブスクライバから返されたパラメータを受信するための条件は次のとおりです。
イベントの発行後、サブスクライバーの戻り値を受け取ることができますが、サブスクライバーとパブリッシャーが同じスレッドにいない場合、または発行されたイベントで複数のサブスクライバーが同時に戻っている場合は、サブスクライバーの戻り値が返されます。イベントを公開したスレッドでは受信されません
GT.EventBus は、イベント クラスを使用しなければならないというルールをキャンセルしますが、イベント クラスの使用もサポートしており、イベントが正常に発行および受信されるようになりました。
イベントクラスを使ったデモ
サブスクライバーイベントクラス
イベントクラスを公開する
レンダリング:
ログ:
com.example.myapplication.(MainActivity.java:25) bbb(): 接收到:MessageBean{data='我是 Activity2'}
(MainActivity2.java:19): 订阅者返回的值:MessageBean{data='我收到了:我是 Activity2'}
非常に良いです。これを見れば、GT.EventBus と EventBus のすべての違いをほぼ学習したことになります。後で説明するのは、サブスクライバー スレッド、サブスクライバー メソッドの優先順位 、 サブスクライバーのサポート スティッキー イベント 、および スティッキー イベントのパブリッシュ 、 単一の削除です。スティッキー イベント、すべてのスティッキー イベントをクリア 、これらは次のことがわかっていれば無視してかまいません。
スキップする必要がある生徒は、後で説明する違いについては、下の図を参照してください。
これまで EventBus を使用したことがない生徒は、サブスクライバー スレッドの処理について学びましょう
5 つのスレッド イベント処理:
POSTING:現在のスレッドで投稿されたイベントを処理します。
MAIN:イベントが解放されたときにそれが (UI) メイン スレッドである場合、イベントを解放したメイン スレッドで処理されます。それ以外の場合は、新しいメイン スレッドが処理されます。
MAIN_ORDERED:直接新しいメインスレッド処理
バックグラウンド:イベントが解放されたときに子スレッドである場合は、イベントを解放した子スレッドで処理されます。それ以外の場合は、新しい新しい子スレッドが処理されます。
ASYNC:直接新しい子スレッドの処理を行う
写真を見てみましょう、それはわかります
ここでは、スレッドで使用される 3 つのメソッドの事後効果について簡単に紹介します。後の 2 つは、意味を確認することで理解できます。
子スレッドで UI が誤って更新された場合、実際にはエラーが報告されることに注意してください。ただし、GT.EventBus はエラーをキャプチャしてカプセル化するのに役立ちます。そのため、スレッド処理では、どのスレッドがどのような動作をするかに注意してください。
加入者メソッドの優先順位
実際に書かれたコード
最終的なレンダリング:
ログ:
com.example.myapplication.(MainActivity.java:29) demo(): 接收到:GT库不止这一个好用的框架!
com.example.myapplication.(MainActivity.java:39) bbb(): 接收到:GT库不止这一个好用的框架!
com.example.myapplication.(MainActivity.java:34) aaa(): 接收到:GT库不止这一个好用的框架!
画像と効果画像を見て、すぐに理解できますか。ただし、ここでメソッドの優先順位のルールの注釈に注意する必要があります。
優先順位は、スレッド実行イベントを切り替えずに同一スレッドでイベントを発行した場合に保証されますが、スレッド実行イベントを切り替えた場合は保証されません。
スティッキーイベントのサポート
いわゆるスティッキー イベントは、イベントが最初に送信され、サブスクライバーは後でそれを受信します。スティッキー イベントの発行と通常のイベントの発行の使用方法は、呼び出しのメソッド名が変更されるだけで、残りは同じです。同じ
//发送普通事件
GT.EventBus.getDefault().post(new LoginBean(user, pass), "getUserPass");
//发送粘性事件
GT.EventBus.getDefault().postSticky(new LoginBean(user, pass), "getUserPass");
ログインページを使用してデモを行います
ログインページのコード:
public class MainActivity extends AppCompatActivity {
private EditText et_user;
private EditText et_pass;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_user = findViewById(R.id.et_user);
et_pass = findViewById(R.id.et_pass);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String user = et_user.getText().toString();
String pass = et_pass.getText().toString();
//...省去登录成功判断条件
Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
//发送粘性事件
GT.EventBus.getDefault().postSticky(new LoginBean(user, pass), "getUserPass");
startActivity(new Intent(MainActivity.this, MainActivity2.class));
}
});
}
}
イベントを直接送信するページには、登録済みの購読者と購読解除者を記述する必要はありません。ログインページは、ユーザーが入力したアカウントのパスワードを取得します。判定が正しければ、ログインが正常に表示され、アカウントがスティッキーイベントに送信されます。
このとき、送信する領域として指定しているのはgetUserPass 、つまり 後から開いたページやクラスにgetUserPass の領域と一致するメソッドがあれば、そのメソッドが自動的に呼び出されて代入されます。ここでの 送信イベント ルールpostSticky は、 実際には post とまったく同じです 。ただし、 postSticky は スティッキー イベントをサポートし、送信ルールはpostと同じです 。
スティッキーイベントを受信する方法を見てみましょう
public class MainActivity2 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
//注册订阅者
GT.EventBus.getDefault().register(this);
}
//支持粘性事件
@GT.EventBus.Subscribe(sticky = true)
public void getUserPass(LoginBean loginBean) {
GT.logt("收到登录的账号:" + loginBean);
TextView textView = findViewById(R.id.tv_title);
textView.setText("收到登录的账号:\n" + loginBean.getUser() + "\n" + loginBean.getPass());
}
@Override
protected void onDestroy() {
super.onDestroy();
//注册订阅者
GT.EventBus.getDefault().unregister(this);
}
}
受信側のみがサブスクライバの登録とサブスクライバのキャンセルを 行う必要があります。このクラスのメソッド名は getUserPass であり、パラメータは同じである ことに注意してください。これにより、データが確実に受信されます。サブスクライバの登録時にgetUserPassメソッドが呼び出されます。、
イベント配信を中止する
以前にこの機能を実行した記録があり、仕事が忙しくて追加したかったのですが、結局忘れてしまい、現在V1.4.2.2 の上に 追加しています。最初に友達やファンに感謝するため、ブロガーにこの関数を書くのを忘れたことを思い出させるためです。次にイベント配信を中止する方法を見てみましょう。
GT ライブラリのキャンセル イベントの配布はオリジナル バージョンとは異なりますが、オリジナル バージョンよりもシンプルで複雑ではないので注意してください。
GT ライブラリはシンプルさを追求して誕生しました。
イベントの配信がキャンセルされると、それ以降は下流にイベントが配信されなくなりますが、一般的にはサブスクリプションメソッドの優先度と連携し、優先度+イベント配信キャンセルでインターセプトチェーンを構築できます。
MainActivity.class と MainActivity2.class という 2 つのクラスをそれぞれ構築します。
次に、2 つの同一のサブスクライバ aaa を異なるクラスに書き込みます
両方のクラスにサブスクライバ aaa が存在しますが、MainActivity から MainActivity2 にジャンプし、クリックして MainActivity2 でイベントを公開します。
この方法で公開されたイベントを見てみましょう。デフォルトの順序は次のとおりです。
MainActivity2 のサブスクライバ aaa が最初に実行され、MainActivity のサブスクライバ aaa が後で実行されます。
つまり、イベントの発行時に同じサブスクライバーが存在する場合、GT.EventBus のデフォルトの順序では、最初にこのクラスのサブスクライバーを送信し、次に他のクラスのサブスクライバーを送信します。
必要に応じて、MainActivity1、MainActivity2、MainActivity3、MainActivity4、MainActivity5 にサブスクライバー aaa が存在します。最初は 1/2/3/4/5 の順序でイベントを発行しましたが、特別な理由により、これを公開するには、イベントは 3 で消費されます。どうすればよいですか? このとき、イベント配信をキャンセルする仕組みを利用することで実現できます。
このキャンセルイベント配信を追加した後の実行ログは次のようになります。
MainActivity2 を実行した後、発行されたイベントがインターセプトされます。これは最も基本的なインターセプト方法ですが、冒頭でブロガーが GT.EventBus のインターセプトがオリジナルのバージョンと異なると述べたので、違いを見てみましょう。
オリジナルバージョン: インターセプト方法として仮パラメータを使用します
@Subscribe
public void onEvent(MessageEvent event){
EventBus.getDefault().cancelEventDelivery(event) ;
}
GT ライブラリ バージョン: 5 つのインターセプト メソッド、柔軟かつ変更可能、特定のインターセプト メソッドは独自の使用シナリオに応じて柔軟に呼び出すことができます。
使い方はとても簡単です、ここでキャンセルイベントを紹介します。
プロセス間でデータを渡す
これは GT.EventBus v1.4.2.4 以降のバージョンでのみサポートされている機能であり、プロセス間でのデータ転送が容易になります。
AndroidManifest.xml を見てみましょう
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication"
tools:targetApi="31">
<!-- 跨进程 Activity -->
<activity
android:name=".MainActivity2"
android:exported="false"
android:launchMode="singleTask"
android:process=":process.unity"/>
<!-- 非跨进程 Activity -->
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
回路図:
MainActivity コード:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GT.logt("创建 非跨进程");
//注册事件
GT.EventBus.getDefault().register(this);
findViewById(R.id.tv).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//跳转会非跨进程 Activity
startActivity(new Intent(MainActivity.this, MainActivity2.class));
}
});
findViewById(R.id.tv2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//向 MainActivity 发送数据
GT.EventBus.getDefault().postAcrossProcesses("跨进程,你好呀", "readData2");
}
});
}
@GT.EventBus.Subscribe
public void readData1(String msg) {
GT.logt("读取到:" + msg);
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消注册简洁版
GT.EventBus.getDefault().unregister(this);
}
}
MainActivity2 コード:
public class MainActivity2 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
GT.logt("创建 跨进程");
//注册 跨进程Activity
GT.EventBus.getDefault().registerAcrossProcesses(this);
findViewById(R.id.tv).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(MainActivity2.this, MainActivity.class));//跳转会非跨进程 Activity
}
});
findViewById(R.id.tv2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
GT.EventBus.getDefault().postAcrossProcesses("你好,我收到了你的消息", "readData1");//向 MainActivity 发送数据
}
});
}
@GT.EventBus.Subscribe
public void readData2(String msg) {
GT.logt("读取到:" + msg);
}
@Override
protected void onDestroy() {
super.onDestroy();
GT.EventBus.getDefault().unregisterAcrossProcesses(this);//取消跨进程注册
}
}
このデータのプロセス間転送は非常に簡単に実装できます。
ローカル イベントを購読して公開します。
public class MainActivity extends AppCompatActivity {
public final static String EVENT_BUS_AA = "EVENT_BUS_AA";//定义局部事件关键字
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//定义局部订阅事件
GT.EventBus.registerInteriors(this, MainActivity.EVENT_BUS_AA, new GT.OneListener<String>() {
@Override
public void onOneListener(String name) {
super.onOneListener(name);
GT.logt("接受到发送的消息:" + name);
}
});
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//发布局部事件
GT.EventBus.postInteriors("名字", MainActivity.EVENT_BUS_AA);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消当类的局部事件
GT.EventBus.unregisterInteriors(this);
}
}
ローカルイベント、非常にシンプルかつ柔軟
もちろん、次のようなより実用的な方法もあります。
API を使用するその他の機能:
//注册简介版
GT.EventBus.registers(this);
//取消注册简洁版
GT.EventBus.unregisters(this);
//注册 跨进程Activity 简洁版
GT.EventBus.registerAcrossProcessess(this);
//取消跨进程注册 简洁版
GT.EventBus.unregisterAcrossProcessess(this);
//发布事件 简洁版
GT.EventBus.posts("发送的内容","发送的目的地");
//发布粘性事件 简洁版
GT.EventBus.postStickys("发送的内容","发送的目的地");
//发布跨进程事件 简洁版
GT.EventBus.postAcrossProcessess("发送的内容","发送的目的地");
//发布本进程 与 跨进程事件 简洁版
GT.EventBus.postAlls("发送的内容","发送的目的地");
/**
* 删除单个 粘性事件
*
* @param eventKeys 填写的 key 必须要与发布事件的 key 一模一样,包括字母顺序
*/
public boolean removeStickyEvent(Object... eventKeys)
/**
* 清空粘性事件
*/
public void clearStickyEvent()
/**
* 查看普通事件
*/
public void showEventBusMap() {
/**
* 查看粘性事件
*/
public void showEventBusStickyMap()
上記は GT.EventBus のコア機能の現在の使用法です。特に良い提案がある場合は、コメント エリアにメッセージを残してください。
クリックしてフォローしていいね (〃'▽'〃) し てブロガーの最新リリース ライブラリをフォローしてください: GitHub - 1079374315/GT