}
@Override
public void onInterrupt(Postcard postcard) {
LogUtils.e(“被拦截了”);
}
});
});
}
}
1.2、Test1Activity
@Route(path = MainActivity.AROUTER_PATH_TEST1)
public class Test1Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test1);
}
}
1.3、Test2Activity
@Route(path = MainActivity.AROUTER_PATH_TEST2)
public class Test2Activity extends AppCompatActivity {
@Autowired(name = “name”)
String name;
@Autowired(name = “age”)
int age;
@Autowired(name = “test”)
Person person;
@Override
protected void onCreate(Bundle savedInstanceState) {
ARouter.getInstance().inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test2);
TextView tvShow = findViewById(R.id.tvShow);
if (person != null){
tvShow.setText(name + ", " + age + “,” + person.toString());
}
}
}
1.4、TestInterceptorActivity
@Route(path = MainActivity.AROUTER_PATH_TEST3)
public class TestInterceptorActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_interceptor);
}
}
1.5、Test1Interceptor
@Interceptor(priority = 7)
public class Test1Interceptor implements IInterceptor {
Context mContext;
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
if (MainActivity.AROUTER_PATH_TEST3.equals(postcard.getPath())){
// 这里的弹窗仅做举例,代码写法不具有可参考价值
final AlertDialog.Builder ab = new AlertDialog.Builder(MainActivity.getActivity());
ab.setCancelable(false);
ab.setTitle(“温馨提醒”);
ab.setMessage(“想要跳转到TestInterceptorActivity么?(触发了”/inter/test1"拦截器,拦截了本次跳转)");
ab.setNegativeButton(“继续”, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
callback.onContinue(postcard);
}
});
ab.setNeutralButton(“算了”, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
callback.onInterrupt(null);
}
});
ab.setPositiveButton(“加点料”, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
postcard.withString(“extra”, “我是在拦截器中附加的参数”);
callback.onContinue(postcard);
}
});
MainLooper.runOnUiThread(new Runnable() {
@Override
public void run() {
ab.create().show();
}
});
}else {
callback.onContinue(postcard);
}
}
@Override
public void init(Context context) {
mContext = context;
LogUtils.e(Test1Interceptor.class.getName()+" has init.");
}
}
1.6、其他
public class Person implements Parcelable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
protected Person(Parcel in) {
name = in.readString();
age = in.readInt();
}
@Override
public String toString() {
return “Person{” +
“name='” + name + ‘’’ +
“, age=” + age +
‘}’;
}
public static final Creator CREATOR = new Creator() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
}
public class MainLooper extends Handler {
private static MainLooper instance = new MainLooper(Looper.getMainLooper());
protected MainLooper(Looper looper) {
super(looper);
}
public static MainLooper getInstance() {
return instance;
}
public static void runOnUiThread(Runnable runnable) {
if(Looper.getMainLooper().equals(Looper.myLooper())) {
runnable.run();
} else {
instance.post(runnable);
}
}
}
2、源码分析
======
ARouter是通过APT生成代码在框架内部进行操作,那么,项目编译生成的文件位置在那里?
既然生成了这些源码,我们就先随便点点看看这些都是啥?
/**
- DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY AROUTER. */
public class ARouter G r o u p Group Groupapp implements IRouteGroup {
@Override
public void loadInto(Map<String, RouteMeta> atlas) {
atlas.put(“/app/Test1Activity”, RouteMeta.build(RouteType.ACTIVITY, Test1Activity.class, “/app/test1activity”, “app”, null, -1, -2147483648));
atlas.put(“/app/Test2Activity”, RouteMeta.build(RouteType.ACTIVITY, Test2Activity.class, “/app/test2activity”, “app”, new java.util.HashMap<String, Integer>(){{put(“test”, 10); put(“name”, 8); put(“age”, 3); }}, -1, -2147483648));
atlas.put(“/app/Test3Activity”, RouteMeta.build(RouteType.ACTIVITY, TestInterceptorActivity.class, “/app/test3activity”, “app”, null, -1, -2147483648));
}
}
/**
- DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY AROUTER. */
public class ARouter R o o t Root Rootapp implements IRouteRoot {
@Override
public void loadInto(Map<String, Class<? extends IRouteGroup>> routes) {
routes.put(“app”, ARouter G r o u p Group Groupapp.class);
}
}
具体源码大家可以自行查看,不过多粘贴了。
这里简简单单随便截图了APT生成的部分源码,是不是感觉跟上一篇文章使用到的代码很多相似性呐~比如拦截器的优先级是1、跳转匹配的路径也是一样的、跳转传递的参数、定义的组名等等。既然这么多一样的那肯定是在内部某部分进行封装使用,带着这个问题我们开始逐步分析。
首先,我们从该框架使用到的注解开始分析(因为注解是使用这个框架的起点)
2.1、注解分析
首先,我们知道要使用ARouter的首先需要在类的注释上面写上 @Route 这个注解,点进源码看看
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Route {
String path();
String group() default “”;
String name() default “”;
int extras() default Integer.MIN_VALUE;
int priority() default -1;
}
使用该注解标注的类将被自动添加至路由表中。而且,ARouter 并非仅提供页面(Activity)的路由功能,还可以用来路由模块想要暴露给其他模块调用的接口。也就是说 @Route 不仅可用于 Activity 类,还可用于模块对外接口的实现类。那么具体它可以实现那些类型?
从上面的源码可以看到,除了拦截器,里面通过实现接口重写方法,方法里面都有一个RouteMeta,那么我们点进去RouteMeta这个类看看:
/**
-
It contains basic route information.
*/
public class RouteMeta {
private RouteType type; // Type of route
private Element rawType; // Raw type of route
private Class<?> destination; // Destination
private String path; // Path of route
private String group; // Group of route
private int priority = -1; // The smaller the number, the higher the priority
private int extra; // Extra data
private Map<String, Integer> paramsType; // Param type
private String name;
private Map<String, Autowired> injectConfig; // Cache inject config.
public RouteMeta() {
}
}
注释的意思是:它包含基本路由信息。
RouteType,就是路由的类型。那么,这款路由框架的具体路由类型又有那些?带着这个疑问,点进RouteType 源码看看。
public enum RouteType {
ACTIVITY(0, “android.app.Activity”),
SERVICE(1, “android.app.Service”),
PROVIDER(2, “com.alibaba.android.arouter.facade.template.IProvider”),
CONTENT_PROVIDER(-1, “android.app.ContentProvider”),
BOARDCAST(-1, “”),
METHOD(-1, “”),
FRAGMENT(-1, “android.app.Fragment”),
UNKNOWN(-1, “Unknown route type”);
}
首先这是一个枚举,这些就是框架可以具体使用到的路由类型
说完Route 这个注解,我们在来看看@Interceptor 拦截器注解,
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Interceptor {
/**
- The priority of interceptor, ARouter will be excute them follow the priority.
*/
int priority();
/**
- The name of interceptor, may be used to generate javadoc.
*/
String name() default “Default”;
}
哦,我们发现拦截器的注解就2个方法,第一个是定义优先级的,第二个就是拦截器的名字。
接着,@Autowired 注解:
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.CLASS)
public @interface Autowired {
// Mark param’s name or service name.
String name() default “”;
// If required, app will be crash when value is null.
// Primitive type wont be check!
boolean required() default false;
// Description of the field
String desc() default “”;
}
总结
大型分布式系统犹如一个生命,系统中各个服务犹如骨骼,其中的数据犹如血液,而Kafka犹如经络,串联整个系统。这份Kafka源码笔记通过大量的设计图展示、代码分析、示例分享,把Kafka的实现脉络展示在读者面前,帮助读者更好地研读Kafka代码。
麻烦帮忙转发一下这篇文章+关注我
javadoc.
*/
String name() default “Default”;
}
哦,我们发现拦截器的注解就2个方法,第一个是定义优先级的,第二个就是拦截器的名字。
接着,@Autowired 注解:
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.CLASS)
public @interface Autowired {
// Mark param’s name or service name.
String name() default “”;
// If required, app will be crash when value is null.
// Primitive type wont be check!
boolean required() default false;
// Description of the field
String desc() default “”;
}
总结
大型分布式系统犹如一个生命,系统中各个服务犹如骨骼,其中的数据犹如血液,而Kafka犹如经络,串联整个系统。这份Kafka源码笔记通过大量的设计图展示、代码分析、示例分享,把Kafka的实现脉络展示在读者面前,帮助读者更好地研读Kafka代码。
麻烦帮忙转发一下这篇文章+关注我
[外链图片转存中…(img-M19mDRtH-1725869442867)]