-
Notifications
You must be signed in to change notification settings - Fork 93
1. Router
gaowei edited this page Apr 8, 2024
·
21 revisions
- 不方便直接拿到Activity.class
- 端外、push、h5通过URI跳转Activity页面
- 回调式onActivityResult,无需在Activity中覆写方法接收结果
- scheme和host都是可省的,如果仅限于app内跳转,建议只用path
- scheme、host、path都支持正则表达式,需要匹配任意字符串,可以使用".*"
- path如果不是正则表达式,必须以/开头
- scheme、host、path都支持占位符,以<>作为标记如,会把url中该位置的值赋给<>内的这个变量
@Router(scheme = "didi", host = "router", path = "/login")
public class ActivityLogin extends Activity {
}
- url中会把?后面的部分作为参数传入到putExtra中
- putExtra的参数会存放到Activity的Intent中
- putAddition的参数无法传递到Intent
- DRouter支持一些系统扩展能力,比如动画。参考Extend类,使用putExtra(key, value)添加
DRouter.build("didi://router/login?a=1&b=2")
.putExtra(Extend.START_ACTIVITY_FLAGS, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK) // flag
.putExtra(key, value) // 自定义参数
.start(context, new RouterCallback() {
@Override
public void onResult(@NonNull Result result) {
boolean r = result.isActivityStarted();
}
});
- 方法1:最新的android建议使用ActivityResultLauncher来接受回调(推荐)
DRouter.build("/activity/result")
.setActivityResultLauncher(launcher) // 自定义ActivityResultLauncher
.start(this)
- 方法2:省略覆写Activity的onActivityResult方法和requestCode定义(已废弃)
DRouter.build("didi://router/login")
.putExtra(key, value)
.start(this, new RouterCallback.ActivityCallback() {
@Override
public void onActivityResult(int resultCode, Intent data) {
}
});
获取参数需要在Activity的getIntent中获取
- 方法3:如果不方便添加注解,可以使用原生intent方式打开Activity,同样支持回调式onActivityResult
DRouter.build(null)
.putExtra(Extend.START_ACTIVITY_VIA_INTENT, intent)
.putExtra(key, value)
.start(this, new RouterCallback.ActivityCallback() {
@Override
public void onActivityResult(int resultCode, Intent data) {
}
});
- 提供一个端外跳转的入口Activity,通过DRouter分发出去,然后关闭页面
<activity android:name=".SchemeActivity">
<intent-filter>
<data android:scheme="didi" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
// 自定义入口Activity
public class SchemeActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DRouter.build(getIntent().getData()).start(this);
finish();
}
}
- 获取Fragment实例或者Class
- 无反射
- scheme、host、path命名策略同Activity
@Router(scheme = "didi", host = "router", path = "/message")
public class MessageFragment extends Fragment {
}
- putExtra的参数会存放到Fragment的setArguments中
- putAddition的参数无法传递到Fragment
- putExtra(Extend.START_FRAGMENT_NEW_INSTANCE,false),可以关闭自动实例化
DRouter.build("didi://router/message")
.putExtra(Extend.START_ACTIVITY_FLAGS, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK) // flag
.putExtra(key, value) // 自定义参数
.start(context, new RouterCallback() {
@Override
public void onResult(@NonNull Result result) {
Fragment f = result.getFragment();
Class<?> fCls = result.getRouterClass();
}
});
- 获取View实例或者Class
- 无反射
- scheme、host、path命名策略同Activity
@Router(scheme = "didi", host = "router", path = "/view/circle")
public class CircleView extends View {
}
- putExtra的参数会存放到View的setTag中
- putAddition的参数无法传递到View
- putExtra(Extend.START_VIEW_NEW_INSTANCE,false),可以关闭自动实例化
DRouter.build("didi://router/view/circle")
.putExtra(key, value)
.start(context, new RouterCallback() {
@Override
public void onResult(@NonNull Result result) {
View v = result.getView();
Class<?> vCls = result.getRouterClass();
}
});
- 端外、push、h5跳转到native代码
- 无需下沉接口的组件间通信,有数据返回能力
- 增强版EventBus
- 每次调用都会实例化
- scheme、host、path命名策略同Activity
@Router(scheme = "didi", host = "router", path = "/sendOrder",
thread = Thread.WORKER) //指定执行线程
public class SendOrderHandler implements IRouterHandler {
@Override
void handle(@NonNull Request request, @NonNull Result result);
// result可以添加数据,会返回给调用方
// 如果需要拦截后面的所有结点可以执行,默认不拦截
request.getInterceptor().onInterrupt();
}
}
- 在内部注册一个监听者,不会重新实例化,类似EventBus,比EventBus增加了数据返回的能力
- 如果注册时使用了lifecycleOwner,会自动解注册
// 动态注册
IRegister register =
DRouter.register(
RouterKey.build("/dynamic/handler").setLifecycleOwner(lifecycleOwner),
new IRouterHandler() {
@Override
public void handle(@NonNull Request request, @NonNull Result result) {
}
});
// 解注册,如果注册时使用了生命周期,则可省
register.unregister();
DRouter.build("didi://router/sendOrder")
.putExtra(key, value)
.start(context, new RouterCallback() {
@Override
public void onResult(@NonNull Result result) {
}
});
正常情况下Activity被start后以及RouterHandler的handle方法执行完成后,RouterCallback中的Result会立刻返回,如果希望RouterCallback中的Result可以等待目标某个触发时机然后才返回Result,同时不阻塞当前线程,可以考虑暂存Result
- 启动登录页,等待用户真正登陆成功后回调
- 用户端外冷启动App,需要等待MainActivity的onResume回调或某些事情准备好后再回调
- RouterHandler有耗时任务,希望等待执行完后再返回给调用方,又不阻塞调用方
- Activity和RouterHandler增加hold参数,就启用了HoldResult
@Router(scheme = "didi", host = "router", path = "/login"
hold = "true")
public class ActivityLogin extends Activity {
@Override
protected void onCreate() {
super.onCreate();
Request request = RouterHelper.getRequest(this);
Result result = RouterHelper.getResult(this);
// 根据业务,在某个时间点触发这个释放(必须有)
RouterHelper.release(this);
}
}
@Router(scheme = "didi", host = "router", path = "/sendOrder",
hold = "true")
public class SendOrderHandler implements IRouterHandler {
@Override
void handle(@NonNull Request request, @NonNull Result result);
// 根据业务,在某个时间点触发这个释放(必须有)
RouterHelper.release(request);
}
}
- 同普通的导航方式一样
DRouter.build("didi://router/sendOrder")
.setHoldTimeout(3000) // 设置超时时间内未返回则自动回调callback
.start(context, new RouterCallback() {
@Override
public void onResult(@NonNull Result result) {
// 只有目标被释放后才会回调,且不会阻塞该线程
}
});
- 监听请求结果,请求处理完后,会回调这个地方
- 可以在这里做降级
@Service(function = IRouterResult.class)
public class RouterResult implements IRouterResult {
@Override
public void onResult(@NonNull Request request, @RouterState int state) {
}
}
- 目标页面需要某种权限,比如登陆
- 目标页面需要先进行某项操作,比如打开定位功能
- 需要重定向
- 全局拦截器会在任意请求发起时执行
- 非全局拦截器,只有当目标存在时,拦截器才会执行
- 非全局@Interceptor注解可省略,但当使用注解时会避免使用反射,推荐使用
- 全局拦截器会在任意请求发起时都会执行
可以做一些预处理,比如重定向
@Interceptor(name = "interceptor1", //可选,可以使用名字替代类耦合的方式来引用到
priority = 1, //可选,优先级,值越大优先级越高
global = true) //可选,是否是全局拦截器
public class LoginInterceptor implements IRouterInterceptor {
@Override
public void handle(@NonNull Request request) {
if (isGo?) {
request.getInterceptor().onContinue();
} else {
request.getInterceptor().onInterrupt();
}
}
}
@Router(path = "/main",
interceptor = LoginInterceptor.class)
public class MainActvity extends Activity {
}