AndroidはEventイベント応答フレームワークを正確に送信(EventBusの乱用問題を解決)

5634 ワード

Androidプロジェクトでは、Eventbusはすでによく知られていると信じています.EventbusはModuleにまたがるイベント送信応答をサポートするフレームワークですが、プロジェクトの拡大や複数のチームの開発に伴い、一部の開発子供靴は特定のビジネスシーンのため、グループ内の他のメンバーのeventイベントを頻繁に多重化することがあります.長い間、複数のeventbusイベントが発生し、複数のシーンが同時に受信されます.ある日、奇妙なバグが発見されるかもしれませんが、どうしても原因が見つかりません.最後に、前の子供靴が乱用されたeventbusによるものであることがわかります.このようなバグは長い時間を浪費し、postソースとhandleの受信者が見つからないイベントもあります.このような状況に対応して、本人は点対点の開発フレームワークを開発して、大体EventBusの使い方を維持して、以下は使用方式です:受信:
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    PointBus.getDefault().register(this);
    setContentView(R.layout.activity_main);
}

public void onTestClick(View view){
    Intent intent = new Intent(this, TestActivity.class);
    startActivity(intent);
}

@PointSubscribe(threadMode = ThreadMode.MAIN)
public void handleEvent(TestEvent testEvent) {
    Toast.makeText(this,testEvent.msg,Toast.LENGTH_LONG).show();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    PointBus.getDefault().unRegister(this);
}

送信:
  public void testPost() {
    PointBus.getDefault().post(this, new TestEvent("from TestActivity"), "com.fly.ui.test.MainActivity");
}

ここのcom.fly.ui.test.MainActivityは、上記のイベントを受信したActivityです.他のActivityやFragmentで処理されている同じイベントが受信されなくても、イベントがどのように緩んでいるかを指定できます.
以下は原理を実现するので、大体原理はやはり使うAPTここのAPTに対して熟知していない子供靴はいくつか基础の文章を探して少し学ぶことができて简単に手の下でprocess部分の肝心なコードを贴り付けます
     TypeElement classElement = (TypeElement) method.getEnclosingElement();
                VariableElement param = method.getParameters().get(0);
                TypeMirror typeMirror = getParamTypeMirror(param, messager);
                String className = classElement.getSimpleName().toString();

                if (element instanceof ExecutableElement) {
                  PointSubscribe bindView = element.getAnnotation(PointSubscribe.class);
                  String threadMode = bindView.threadMode().name();             
                  ExecutableElement method = (ExecutableElement) element;

注記寸法のメソッドに対応するクラスのフルネームとeventクラスのフルネームのすべての情報がキャッシュリストに格納され、最後にJavaファイルが作成されることがわかりました.
 Writer writer = jfo.openWriter();
        writer.write("package " + packName + ";");
        writer.write("

"); writer.write("import com.fly.bus.SubscribeImpl;"); writer.write("
"); writer.write("import com.fly.bus.SubscribeInfo;"); writer.write("
"); writer.write("import java.util.ArrayList;"); writer.write("
"); writer.write("import java.util.HashMap;"); writer.write("
"); writer.write("import java.util.List;"); writer.write("
"); writer.write("public class " + newClassName + " implements SubscribeImpl{

"); writer.write(" public static HashMap> subscribeInfoMap;
"); writer.write(" public static List subscribeInfoList;
"); writer.write(" static {
"); writer.write(" subscribeInfoMap = new HashMap<>();
"); initSubscribeInfo(writer, hashMap); writer.write(" }
"); writer.write(" public static void initSubscribeInfo(String methodName,String eventName,String threadMode){
"); writer.write(" subscribeInfoList.add(new SubscribeInfo(methodName,eventName,threadMode));
"); writer.write(" }
"); writer.write(" @Override
"); writer.write(" public HashMap> getSubscribeInfo(){
"); writer.write(" return subscribeInfoMap;
"); writer.write(" }
"); writer.write("

"); writer.write("}
"); writer.flush(); writer.close(); private void initSubscribeInfo(Writer writer, HashMap> hashMap) { try { for (String className : hashMap.keySet()) { writer.write(" subscribeInfoList = new ArrayList<>();
"); List infoList = hashMap.get(className); if (infoList == null || infoList.size() == 0) { continue; } for (SimpleSubscribeInfo info : infoList) { String methodName = info.getMethodName(); String eventName = info.getEventName(); String threadMode = info.getThreadMode(); writer.write(" initSubscribeInfo(" + "\"" + methodName + "\"" + "," + "\"" + eventName + "\"" + "," + "\"" + threadMode + "\"" + ");
"); } writer.write(" subscribeInfoMap.put(" + "\"" + className + "\"" + ",subscribeInfoList);
"); } } catch (Exception e) { e.printStackTrace(); } }

まとめ:すべての注釈のメソッドに対応するクラスとパラメータ名をコンパイラがAbstractProcessorを利用してコンパイラで生成したHashmapに保存し、postのときにターゲットクラスのフルネーム(com.fly.ui.test.MainActivity)をkeyとして対応するvalueを探し、valueにeventクラスのフルネームとメソッド名、イベントを処理するスレッドを保存し、invoke methodでよい
最後にgithubリンクを添付します.https://github.com/tmacfly/PointBusMaster転送は出典を明記していただきありがとうございます