使いやすいアンドロイドモジュール化間通信-インタフェース方式呼び出し

10597 ワード

github : https://github.com/gybin02/Protocol
Jet Protocol Androidモジュール間通信ライブラリ
ビジネスモジュール間ではjavaのinterfaceを定義/実現することによってビジネスロジックが完了し、必然的にモジュール間にコードレベルの依存が存在する.コンパイル期間のエンジニアリング依存性も招きます.実際、ビジネスモジュール間では論理的に依存しているだけで、実際のエンジニアリング依存を生む必要はありません.
このコンポーネントは、レンコンモジュール間の明示的な依存性を解消する能力を提供する.
シナリオの比較
  • は、要求サーバの動作と同様に、要求インタフェースを定義する.サービス側はフロントエンドでデータフォーマットを約束し、双方は通信を行う-ARouter
  • .
  • Jetエンジニアリングの@JImplementと@JProviderメソッドを使用します.欠点は、指定したインプリメンテーションが必要なクラスのフルパスです.
  • はinterfaceを定義し、モジュール間でインタフェースを呼び出す.(本コンポーネントの使用方法)
  • 次の操作を行います.
  • モジュールModuleのbuild.gradleでの依存関係の構成:
  •   //    :0.0.1-SNAPSHOT
     compile 'com.jet.framework:protocol:0.0.1'
    
  • 初期:アプリケーション内:初期化:
  •   ProtocolProxy.getInstance().init(this);
    
  • モジュールAにインタフェースを作成し、モジュールA呼び出し
  • に提供する.
    //  : @Interface     Value     ;
    @Interface("moduleB_key")
    public interface TestInterface {
         //     
         public void test(String msg);
    }
    
  • モジュールBには、インタフェースの実装が提供される.対外能力提供
  •    @Implement("moduleB_key")
       public class TestImplement {
       
           public void test(String msg) {
              //       
               Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
       
           }
       }
       //        TestInterface     ,          。      implements   。
    
  • モジュールAで呼び出す:
  •   ProtocolProxy.getInstance().
                            create(TestInterface.class)
                            .test("Implement By Module B");
      
       //       TestInterface,ProtocolProxy         。
                                    
    

    一般的な依存性の実装
  • 例えばモジュールA定義インタフェースは、対外能力を提供する:
  • public interface TestInterface {
    
         public void test(String msg);
    }
    
  • モジュールB実装インタフェース:
  • public class TestImplement implements TestInterface {
    
        @Override
        public void test(String msg) {
            Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
        }
    }
    
  • このようにモジュールAとモジュールBとの間には直接依存関係がある
  • .
    実装の原理
  • コンパイル期間注記APTにより、すべてのInterface->Implement対応関係ファイルの収集を実現:relate.json
  • ルーティング収集、appのgradleファイルにメソッドを追加し、jsonファイルをAssets/protocolディレクトリにコピーすることを実現します.
  • 初期化が適用されるとinit()メソッドが呼び出され、asset/protocol/ディレクトリのjsonをメモリにロードすることが実現される.
  • Java動的エージェントProxyInvoker呼び出し生成クラスを使用してルーティング配布を実現する.

  • 具体的な収集ルーティングgradleスクリプトは以下の通りです(2020-0404は使用できません).
    //      assets/       
    android.applicationVariants.all { variant ->
        def variantName = variant.name
        def variantNameCapitalized = variantName.capitalize()
        def copyMetaInf = tasks.create "copyMetaInf$variantNameCapitalized", Copy
        copyMetaInf.from project.fileTree(javaCompile.destinationDir)
        copyMetaInf.include "assets/**"
        copyMetaInf.into "build/intermediates/sourceFolderJavaResources/$variantName"
        tasks.findByName("transformResourcesWithMergeJavaResFor$variantNameCapitalized").dependsOn copyMetaInf
    }
    

    全体の原理はGoogle auto-serverと似ています.
    重要ヒント2020.0404
  • Gradle 5.0では、スクリプトは
  • を使用できません.
  • の考え方は参考になり、APIを再検索する必要があります.

  • 2つの他の考え方:
  • JavaPoetを使用してデータを中間のクラスの変数に入れる
  • 直接生成jsonファイル絶対アドレスに格納Asset/jsonキークラス
  • /**
         *      Asset   
         *
         * @param content
         */
        private void createAssetFile(String content) {
            // app/src/assets
            FileOutputStream fos = null;
            OutputStreamWriter writer = null;
    
            try {
                //filer.createResource()        
                //       class       ,
                //StandardLocation.CLASS_OUTPUT:java    class     ,/app/build/intermediates/javac/debug/classes/   
                //StandardLocation.SOURCE_OUTPUT:java     ,   /ppjoke/app/build/generated/source/apt/   
                //StandardLocation.CLASS_PATH   StandardLocation.SOURCE_PATH    ,       ,         pkg   
    
                FileObject resource = filer.createResource(StandardLocation.CLASS_OUTPUT, "", FLASH_PATH);
                String resourcePath = resource.toUri().getPath();
                //       json     app/src/main/assets/   ,               ,
                //                  /app/src/main/assets/   
                System.out.println(resourcePath);
                String appPath = resourcePath.substring(0, resourcePath.indexOf("/build/generated"));
                String module = appPath.substring(appPath.lastIndexOf("/") + 1);
                String assetsPath = appPath + "/src/main/assets/flash";
                System.out.println(assetsPath);
                System.out.println(module);
    
    
                File file = new File(assetsPath);
                if (!file.exists()) {
                    file.mkdir();
                }
    
                //    
                File outputFile = new File(file, "flash_" + module);
                if (outputFile.exists()) {
                    outputFile.delete();
                }
                outputFile.createNewFile();
    
                //  fastjson                JSON   。       
                fos = new FileOutputStream(outputFile);
                writer = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
                writer.write(content);
                writer.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (writer != null) {
                    try {
                        writer.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    

    紛らわす
  • 中間クラスは
  • を混同することはできない.
  • 実装クラスとインタフェースクラスは
  • を混同することはできない.
    リファレンス
  • 微信Androidモジュール化アーキテクチャ再構築実践
  • Androidプログラム設計探索:MVPとモジュール化
  • Androidモジュール化実践
  • コンポーネント化、モジュール化、集中式、分散式、サービス化、サービス向けアーキテクチャ、マイクロサービスアーキテクチャ
  • Androidコンポーネント化とプラグイン化開発
  • 代替:使用可能:https://github.com/gybin02/fllash

  • TODO
  • 以前はimplements interfaceで比較的容易にサブクラスメソッドの署名を得ることができたが,現在はIDEインテリジェントヒントがなく,実際の実装クラスメソッドを書く場合,少し不便である.(fixed)
  • インプリメンテーションが見つからない場合は空のポインタを報告し、処理して空の実装を使用することが望ましいが、Logヒント
  • エラーのヒントはもっと明らかにする必要があります:クラスが見つからない、方法の署名が間違っているなど;
  • AARはJcCenter
  • に発表された.