ARouter是阿里巴巴開源的Android平臺中對頁面、服務提供路由功能的中間件,沒用過的務必點擊傳送門
android { defaultConfig { ... javaCompileOptions { annotationProcessorOptions { arguments = [ moduleName : project.getName() ] } } } } dependencies { //ARouter compile 'com.alibaba:arouter-api:x.x.x' annotationProcessor 'com.alibaba:arouter-compiler:x.x.x' //XRouter compile 'com.mondyxue:xrouter:1.0-SNAPSHOT@aar' } repositories { maven { //XRouter url "https://raw.githubusercontent.com/MondyXue/Maven/master" } }
import com.alibaba.android.arouter.facade.annotation.Route; @Route(path = "/page/browser") public class WebViewActivity extends BaseActivity{ ... }
//初始化uri信息 XRouter.setScheme("xrouter"); XRouter.setAuthority("mondyxue.github.io"); //XRouter初始化 XRouter.init(DemoApplication.this);
import com.mondyxue.xrouter.annotation.Extra; import com.mondyxue.xrouter.annotation.Route; public interface WebNavigator{ @Route(path = "/page/browser") void openUrl(@Extra("url") String url); }
XRouter.getRouter() .create(WebNavigator.class) .openUrl("https://github.com/Alibaba/ARouter");
XRouter基於ARouter提供了針對幾個經常使用場景的解決方案java
//聲明返回類型爲ActivityNavigator<T>,T爲須要解析的回傳數據類型 @Route(path = "/page/login") ActivityNavigator<UserInfo> toLoginFragment(); //複寫Activity和Fragment基類中的onActivityResult方法 public abstract class BaseActivity extends FragmentActivity{ ... @Override protected void onActivityResult(int requestCode, int resultCode, Intent data){ super.onActivityResult(requestCode, resultCode, data); //XRouter處理回調邏輯 XRouter.getRouter() .getActivityManager() .onActivityResult(BaseActivity.this, requestCode, resultCode, data); } } //實現Callback public abstract class UserInfoCallback extends RouteCallback<UserInfo>{ @Override public UserInfo parseData(int requestCode, int resultCode, Intent data){ return (UserInfo) data.getSerializableExtra(Extras.UserInfo); } } //路由發起 XRouter.getRouter() create(DemoNavigator.class) toLoginFragment() startActivityForResult(new UserInfoCallback(){ @Override public void onResponse(@NonNull UserInfo data){ Toast.makeText(MainActivity.this, "login success: " + data.toString(), Toast.LENGTH_SHORT).show(); } });
//聲明 @Route(path = "/service/userService") UserService getUserService(); //建立navigator DemoNavigator navigator = XRouter.getRouter().create(DemoNavigator.class); //獲取UserService UserService userService = navigator.getUserService(); boolean isLogin = userService.isLogin(); UserInfo userInfo = userService.getUserInfo(); //獲取Logger Logger logger = navigator.getLogger(); logger.e("tag", "msg...");
import com.mondyxue.xrouter.navigator.Navigator; //聲明返回類型爲Navigator @Route(path = "/page/login") Navigator toLoginFragment(); //建立Navigator Navigator navigator = XRouter.getRouter() .create(DemoNavigator.class) .toLoginFragment(); //經過Navigator調用支持方法 Uri uri = navigator.uri(); Intent intent = navigator.intent(); Fragment fragment = navigator.fragment(); IProvider provider = navigator.service(); navigator.startActivity();
import com.mondyxue.xrouter.constant.RouteType; import com.alibaba.android.arouter.facade.annotation.Route; //在ARouter的Route註解中 //RouteType中有幾個輔助flag值,可用於ARouter的Route註解中的extras值Route(extras=...) RouteType.GreenChannel//綠色通道,不通過攔截器 RouteType.Fragment//Fragment標記 RouteType.Activity//Activity標記 RouteType.Service//標記是否爲實現了IProvider的服務類 RouteType.WithinTitlebar//標記此頁面是否已有標題欄(Toolbar等) RouteType.Login//標記訪問此頁面是否須要登陸權限 RouteType.Main//標記此頁面是否爲App首頁 //組合打法 RouteType.TitlebarFragment = Fragment | WithinTitlebar; RouteType.LoginActivity = Activity | Login;
@Route(path = "/page/userInfo", extras = RouteType.LoginFragment) public class UserInfoFragment extends BaseFragment{ ... }
@Interceptor(priority = 4, name = "LoginInterceptor") public class LoginInterceptor extends com.mondyxue.xrouter.interceptor.LoginInterceptor implements IInterceptor{ //返回當前用戶是否已登陸 @Override public boolean isLogin(){ return XRouter.getRouter() .create(DemoNavigator.class) .getUserService() .isLogin(); } //調用登陸服務,在登陸回調中執行原攔截器回調 @Override protected void onInterrupt(final Postcard postcard, final InterceptorCallback callback){ XRouter.getRouter() .create(DemoNavigator.class) .toLoginFragment() .startActivityForResult(new UserInfoCallback(){ @Override public void onResponse(@NonNull UserInfo data){ postcard.withSerializable(Extras.UserInfo, data); callback.onContinue(postcard); } @Override public void onError(Throwable throwable){ callback.onInterrupt(throwable); } @Override public void onCancel(){ callback.onInterrupt(new RuntimeException("login cancel!")); } }); } }
@Route(path = "/page/text", extras = RouteType.Fragment) public class TextFragment extends BaseFragment{ ... }
@Route(path = "/page/contanier", extras = RouteType.Activity | RouteType.GreenChannel) public class ContanierActivity extends BaseActivity{ @Override protected int getRootLayout(){ //RouteType.Titlebar標記值可經過此方式獲取 boolean withinTitlebar = getIntent().getBooleanExtra(RouteExtras.WithinTitlebar, false); //根據標記值決定容器的佈局是否有標題欄 return withinTitlebar ? R.layout.activity_contanier : R.layout.activity_contanier_within_titlebar; } @Override protected void init(){ Intent intent = getIntent(); boolean withinTitlebar = intent.getBooleanExtra(RouteExtras.WithinTitlebar, false); if(!withinTitlebar){ //判斷並設置Title String title = intent.getStringExtra(RouteExtras.Title); ((TextView) findViewById(R.id.tv_title)).setText(title); } //獲取攔截器中傳過來的Fragment路由path String path = intent.getStringExtra(RouteExtras.PathTo); if(!TextUtils.isEmpty(path)){ //使用XRouter根據path獲取fragment實例 final Fragment fragment = XRouter.getRouter().build(path).navigator().fragment(); if(fragment != null){ fragment.setArguments(intent.getExtras()); runOnUiThread(new Runnable(){ @Override public void run(){ getSupportFragmentManager() .beginTransaction() .add(R.id.fl_contanier, fragment) .hide(fragment) .show(fragment) .commitAllowingStateLoss(); } }); return; } } finish(); } }
@Interceptor(priority = 8, name = "FragmentInterceptor") public class FragmentInterceptor extends com.mondyxue.xrouter.interceptor.FragmentInterceptor implements IInterceptor{ @Override protected String getFragmentContainerPath(){ //返回Fragment容器Activity路徑 return "/page/contanier"; } }
若是你使用混淆而且用到Fragment攔截器的話,須要在混淆配置中添加如下規則:android
#XRouter:使用Fragment攔截器 -keep class com.alibaba.android.arouter.facade.Postcard{*;}
小弟不才,第一次分享代碼到Github,碼代碼這茬,一我的容易出事,並且項目來不及寫註釋,因此特此貼上Q羣二維碼,若是你們有什麼建議和槽點,歡迎可以多多交流。git