PageRouter 一款輕量級Android路由框架(支援Activity與Fragment跳轉)
概述
原專案是由後臺分發url,客戶端各Activity在Manifest中配置IntentFilter,通過匹配URL實現跳轉和傳參(隱式跳轉);同時這些頁面也支援Intent跳轉,通過Bundle傳參(顯示跳轉)。
Fragment的統一跳轉則需要將相關邏輯放入容器Activity中,導致公共的fragment容器註冊一大堆IntentFilter,還要為每個Fragment去單獨解析引數。
隨著專案迭代,支援跳轉的頁面越來越多,傳參也越來越複雜,Manifest日漸臃腫,Activity中也需要通過判斷intent來分別去解析url和bundle獲取引數,給專案的迭代與維護增加很多維護成本。
基於以上種種問題,我考察了主流的幾個開源路由框架,發現都沒法完全滿足我的需求,有的不支援配置多路徑(歷史原因部分頁面必須支援多路徑);有的不支援引數自動解析(便利性大打折扣);普遍功能多,跳轉邏輯複雜;基本都不支援Fragment的直接跳轉,kolin支援度也參差不齊。
經過參考了多款路由框架,我實現了一個輕量級Android路由框架:PageRouter,完美解決以上痛點問題,以下是PageRouter的相關特點及使用文件。
Github
ofollow,noindex">https://github.com/liujingg/PageRouter
效果

pagerouter-demo.gif
特點
- 支援Activity的標準URL解析與跳轉
- 支援Fragment直接跳轉到指定的關聯Activity
- 支援多路徑
- 支援多模組工程
- 支援kotlin
- 支援引數自動注入,kotlin下支援屬性委託獲取引數
- 支援新增攔截器
- 支援全域性降級與區域性降級策略
新增依賴
android { defaultConfig { ... //multi module configuration javaCompileOptions { annotationProcessorOptions { arguments = [targetModuleName: 'Other']// replace with the other module project name } } } } dependencies { // Replace the last version implementation "com.liujing.pagerouter:router:last-version" annotationProcessor "com.liujing.pagerouter:router-compiler:last-version" ... }
kotlin 專案請使用kapt替換annotationProcessor
apply plugin: 'kotlin-kapt // Replace the last version implementation "com.liujing.pagerouter:router:last-version" kapt "com.liujing.pagerouter:router-compiler:last-version"
功能與使用
1. 初始化
強烈建議在Application中初始化。
Router.init("pagerouter"); //your application's specific scheme
註冊其他模組路由(如有)。
Router.register(new OtherRouterInitializer());
手動新增路由條目。
Router.register(new RouterInitializer() { @Override public void initActivityTable(Map<String, Class<? extends Activity>> router) { router.put("second2", SecondActivity.class); } @Override public void initFragmentTable(Map<String, Pair<Class<? extends Activity>, Class<? extends Fragment>>> router) { } });
2. 添加註解
Activity註解
@RouterActivity({"second", "third"}) public class SecondActivity extends AppCompatActivity { ... }
Fragment註解
// The activityClazz here means the fragment currently associated with Activity @RouterFragment(value = "myfragment", activityClazz = FragmentContainerActivity.class) public class MyFragment extends Fragment { ... }
3. 引數解析
@RouterActivity({"second"}) public class SecondActivity extends AppCompatActivity { @RouterField("id") // map parameters in the url by name private int id; ... @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_common); Router.inject(this);// PageRouter will automatically set value of fields ... } }
4. 發起跳轉
Router.startActivity(context,"scheme://second?id=17")
5. 混淆
-keep class * extends com.liujing.pagerouter.RouterInitializer { *; }
6. 跳轉結果回撥
Router.startActivity( this, "pagerouter://other?id=17", object : RouteCallback { override fun onSuccess(context: Context, uri: Uri) { Toast.makeText(context, "success", Toast.LENGTH_SHORT).show() } override fun onFailed(context: Context?, message: String?) { Toast.makeText(context, "failed : $message", Toast.LENGTH_SHORT).show() } })
7. 外部URL跳轉
AndroidManifest.xml中
<activity android:name=".RouterCenterActivity"> <intent-filter> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="myscheme"/> </intent-filter> </activity>
建立一個新的Activity用於監聽scheme事件
public class RouterCenterActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Uri data = getIntent().getData(); if (data != null) { Router.startActivity(this, data.toString()); } this.finish(); } }
8. 新增攔截器
Router.setIntercept(new IIntercept() { @Override public void process(@NonNull Context context, @NonNull Uri uri, InterceptorCallback callback) { if (...) { //TODO do something callback.onInterrupt(result, message);//interrupt routing process } else { callback.onContinue(uri); } } });
9. 全域性策略
Router.setDefaultCallBack(new RouteCallback() { @Override public void onSuccess(Context context, Uri uri) { } @Override public void onFailed(Context context, String message) { //TODO do something } });