PS:どんな時でも幻想を抱いてはいけません。自分の計画を持ち、美しい気持ちを持ち、自分自身と自分を愛してくれる人に責任を持つべきです。
前の 2 つの記事では、Android のコンポーネント化の基本知識と Android のコンポーネント化プロセスにおける Application に関する知識を紹介しました。この記事を読む前に、以下の 2 つの記事を先に読むことをお勧めします:
Android のコンポーネント化プロセスでは、異なるモジュール間のインターフェースの遷移も非常に重要です。自分が手掛けたプロジェクトをコンポーネント化する場合、ARouter は非常に使いやすいルーティングフレームワークであり、大手企業の開発チームによってメンテナンスされていますので、品質に問題はないと信じています。
ARouter は Alibaba チームがオープンソースで提供している Android アプリのコンポーネント化のためのフレームワークで、モジュール間のルーティング、通信、インターセプト機能をサポートしています。ネイティブの遷移に比べて、コンポーネント化開発により適応しています。この記事では、ARouter の一般的な機能を事例を通じてまとめます。具体的には以下の通りです:
- ARouter の設定
- アプリ内遷移
- アプリ内でのパラメータ付き遷移
- Activity の戻り結果処理
- Uri を使った遷移とパラメータ解析
- モジュール間の遷移
- サービス呼び出し
- 表示効果
ARouter の設定#
対応する build.gradle ファイルに ARouter の関連依存関係を以下のように設定します:
android {
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
}
dependencies {
//apiとcompilerは互換性を持たせて使用し、最新バージョンを使用することで互換性を保証
compile 'com.alibaba:arouter-api:1.4.0'
annotationProcessor 'com.alibaba:arouter-compiler:1.2.1'
...
}
ルーティングテーブルの自動読み込みを設定することもできます。プロジェクトの build.gradle ファイルで設定し、設定方法は以下の通りです:
// ルーティングテーブル自動読み込みプラグイン
apply plugin: 'com.alibaba.arouter'
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
//ARouter
classpath "com.alibaba:arouter-register:1.0.2"
}
}
さらに、Application 内で ARouter を初期化する必要があります。以下のようにします:
@Override
public void onCreate() {
super.onCreate();
// ARouterの初期化前に設定する必要があります
if (BuildConfig.DEBUG){
// ログを有効にする
ARouter.openLog();
// デバッグモードを有効にする。install runモードで実行する場合は、デバッグモードを有効にする必要があります
ARouter.openDebug();
}
ARouter.init(this);
}
アプリ内遷移#
ARouter を使用してアプリ内遷移を行うのは非常に簡単です。遷移したい Activity に@Routeアノテーションを追加するだけです。具体的には以下の通りです:
// 設定されたpathは少なくとも2階層必要です。例:/xx/xxx
@Route(path = FirstActivity.PATH)
public class FirstActivity extends AppCompatActivity {
public static final String PATH = "/test/firstActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
}
}
次に、ARouter が提供する遷移方法を使用してアプリ内部での遷移を行います。具体的には以下の通りです:
// アプリ内遷移
ARouter.getInstance()
.build(FirstActivity.PATH)
.navigation();
アプリ内でのパラメータ付き遷移#
ARouter は withString などの一連の with で始まるメソッドを使用して、対応するパラメータを設定してパラメータを渡します。具体的には以下の通りです:
// アプリ内でのパラメータ付き遷移
ARouter.getInstance()
.build(SecondActivity.PATH)
.withString(SecondActivity.PARAM, "これは遷移に持ち込まれるパラメータです")
.navigation();
次に、遷移先の Activity で Intent を使用して渡されたパラメータを取得します。具体的には以下の通りです:
@Route(path = SecondActivity.PATH)
public class SecondActivity extends AppCompatActivity {
public static final String PATH = "/test/secondActivity";
public static final String PARAM = "param";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Intent intent = getIntent();
if (intent!=null){
String param = intent.getStringExtra(PARAM);
Toast.makeText(this, param, Toast.LENGTH_SHORT).show();
}
}
}
Activity の戻り結果処理#
Activity の戻り結果処理はネイティブとほぼ同じで、遷移時に requestCode を持ち運びます。具体的には以下の通りです:
// Activityの戻り結果処理
ARouter.getInstance()
.build(ThreeActivity.PATH)
.navigation(this, 100);
次に、Activity が戻る際に Intent を使用して setResult でパラメータを持ち運びます。具体的には以下の通りです:
@Route(path = ThreeActivity.PATH)
public class ThreeActivity extends AppCompatActivity {
public static final String PATH = "/test/threeActivity";
public static final String PARAM_RESULT = "param_result";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_three);
Intent intent = getIntent();
//setResult
intent.putExtra(PARAM_RESULT,"これは戻りに持ち込まれるパラメータです");
setResult(RESULT_OK,intent);
}
}
Uri を使った遷移とパラメータ解析#
ARouter は Uri を使った遷移もサポートしています。まず、Scheme イベントをリスンするための無界面 Activity を作成し、その Activity が Uri を統一的に転送します。すべての Uri はここを通過して分配遷移され、Uri の制御が非常に良くなり、Uri を使った遷移の安全性がある程度向上します。無界面 Activity は以下のように実装します:
public class SchemeFilterActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Uri uri = getIntent().getData();
// 外部遷移のUriを統一し、ルーターによる統一分配を実現し、Intent属性のマッチングによる安全リスクを減少させます
ARouter.getInstance().build(uri).navigation(this, new NavCallback() {
@Override
public void onArrival(Postcard postcard) {
finish();
}
});
}
}
AndroidManifest ファイルに host、scheme、Action を設定します。具体的には以下の通りです:
<activity android:name=".SchemeFilterActivity">
<intent-filter>
<data
android:host="test.manu.com"
android:scheme="arouter" />
<action android:name="com.manu.route" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
次に、assets フォルダ内に html ファイルを作成し、クリックして遷移リンクを完成させます。html の内容は以下の通りです:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<h2>遷移テスト</h2>
<h2>カスタムScheme</h2>
<p>
<!--パラメータなし-->
<a href="arouter://test.manu.com/test/fiveActivity">arouter://test111.manu.com/test/fiveActivity</a>
</p>
<p>
<!--パラメータ付き-->
<a href="arouter://test.manu.com/test/sixActivity?name=alex&age=18&score=%7B%22score%22:%2290%22,%22rank%22:%222%22%7D">arouter://test111.manu.com/test/sixActivity?name=alex&age=18&score={"score":"90","rank":"2"}</a>
</p>
</body>
</html>
具体的な効果は実行効果図を参照してください。
次に、WebView を使用してこの Html を読み込むことで、対応する Activity に遷移できます。つまり、リンク内の fiveActivity と SixActivity です。2 つの Activity はそれぞれ以下の通りです:
// FiveActivity
@Route(path = FiveActivity.PATH)
public class FiveActivity extends AppCompatActivity {
public static final String PATH = "/test/fiveActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_five);
}
}
// SixActivity
@Route(path = SixActivity.PATH)
public class SixActivity extends AppCompatActivity {
public static final String PATH = "/test/sixActivity";
@Autowired
public String name;
@Autowired
public int age;
@Autowired
// Uriでカスタムオブジェクトを渡す場合、パラメータにjson文字列(encodeURIエンコード)を使用して渡し、SerializationServiceインターフェースを実装したクラスを作成してjsonの解析を行います
public ScoreBean score;
@BindView(R.id.tvData)
TextView tvData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_six);
ButterKnife.bind(this);
// パラメータの自動依存注入
ARouter.getInstance().inject(this);
String info = "name=" + name + ",age=" + age + ",score=" + score;
tvData.setText(info);
Log.i("SixActivity", info);
}
}
モジュール間の遷移#
主モジュールと子モジュール間の遷移も非常に簡単です。主モジュールから子モジュールに遷移する場合、主モジュールと子モジュールの両方で ARouter を設定する必要があります。主モジュール内に遷移する子モジュールのパスを管理するインターフェースを作成します。具体的には以下の通りです:
// 遷移パスを管理
public interface Module {
String MODULE_ONE = "/module1/module-one";
String MODULE_TWO = "/module2/module-two";
}
次に、直接遷移を行います。具体的には以下の通りです:
// Module-oneに遷移
ARouter.getInstance()
.build(Module.MODULE_ONE)
.navigation();
サービス呼び出し#
ARouter 内のサービス呼び出しは Android 内の Service と混同しないでください。ARouter 内のサービス呼び出しは実際には特定のビジネスのラッピングであり、ARouter のこの層の統一的なラッピングにより、呼び出しがより便利になります。パスと名前を知っているだけで自由に呼び出すことができます。IProvider を実装してサービスを作成します。以下のようにします:
@Route(path = "/service/singleService")
public class SingleService implements IProvider {
public static final String PATH = "/service/singleService";
private Context mContext;
//具体的なサービス
public void showMessage() {
Toast.makeText(mContext, "これは外部に提供されるサービスです", Toast.LENGTH_SHORT).show();
}
@Override
public void init(Context context) {
this.mContext = context;
Log.i("SingleService", "SingleServiceが初期化されました");
}
}
次に、呼び出しを行います。呼び出し方法は以下の通りです:
// サービスクラスを通じて呼び出す
ARouter.getInstance().navigation(SingleService.class).showMessage();
// サービスクラスのPathを通じて呼び出す
((SingleService) ARouter.getInstance()
.build(SingleService.PATH)
.navigation())
.showMessage();
さらに、依存注入の方法を使用してサービスの呼び出しを完了することもできます。この方法は複数のサービスを管理するのに便利です。サービス管理クラスを以下のように作成します:
// サービス管理クラス
public class ServiceManage {
@Autowired
SingleService singleService;
public ServiceManage(){
// 依存注入の方法でサービスを取得
ARouter.getInstance().inject(this);
}
public void getService(){
singleService.showMessage();
}
}
次に、サービス管理クラスを通じて具体的なサービスを呼び出します。以下のようにします:
//サービス管理、依存注入の方法でサービスを取得
ServiceManage manage = new ServiceManage();
manage.getService();
表示効果#
上記の実装のテスト効果は以下の図の通りです:
ARouter の機能は非常に包括的で、使用も非常に簡単です。上記の内容は最もよく使用されるものです。他の機能、例えばインターセプター、ダウングレード戦略、トランジションアニメーション、マッピング関係のグループ化などについては、公式ドキュメントを参考にして実践してください。