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 ファイルを作成し、リンクをクリックして Uri の遷移を完了します。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 の機能は非常に包括的で、使用も非常に簡単です。上記の内容は最もよく使用されるものであり、他の機能(インターセプター、ダウングレード戦略、トランジションアニメーション、マッピング関係のグループ化など)については、公式ドキュメントを参考にして実践してください。