栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android—简单路由框架实践

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android—简单路由框架实践

简单路由框架实现:

1.目录结构

        

         

 annotation和factory-compiler是两个java library,分别负责接口还有APT。

2.依赖关系

app作为主工程依赖所有

implementation project(':annotation')
implementation project(':router')
implementation project(':secondmodule')
annotationProcessor project(':factory-compiler')

secondmodule作为组件

implementation project(':annotation')
implementation project(path: ':router')
annotationProcessor project(':factory-compiler')

factory-compiler

implementation 'com.google.auto.service:auto-service:1.0-rc6'
implementation project(':annotation')
implementation 'com.squareup:javapoet:1.10.0'
annotationProcessor 'com.google.auto.service:auto-service:1.0-rc6'

3.在annotation中创建注解类

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface Router {
    String value();
}

4.使用注解

在app的MainActivity类类名打上注解

@Router(value = "MainActivity")

在secondmodule的SecondActivity类类名打上注解

@Router(value = "SecondActivity")

5.在router工程创建路由类

public class TextRouter {

    // 页面路由表
    private static final List paths = new ArrayList<>();

    // 将页面插入到路由表中
    public static void add(String path, Class activity) {
        paths.add(new Path(path, activity));
    }

    
    public static void navigate(Context context, String path, Bundle bundle) {
        // 遍历路由表,进行 uri 的匹配,匹配成功,则启动对面的 Activity 页面
        for (Path p : paths) {
            if (p.value.equals(path)) {
                Intent intent = new Intent(context, p.getActivity());
                intent.putExtra(path,bundle);
                context.startActivity(intent);
                return;
            }
        }
    }

    // 路由记录
    public static class Path {
        private final String value;
        private final Class activity;

        public Path(String path, Class activity) {
            this.value = path;
            this.activity = activity;
        }

        public Class getActivity() {
            return activity;
        }
    }
}

我们只有通过该类的add方法添加进value值跟对应的Activity即可完成注册,当我们需要跳转到某个类时,就用navigate方法传入对应的value值就可以完成跳转。

接下来就可以用APT来实现对用上注解的Activity(既MainActivity跟SecondActivity)进行add操作。

6.在factory-compiler中创建Processer

@AutoService(Processor.class)
public class RouterProcessor extends AbstractProcessor {

    @Override
    public boolean process(Set set, RoundEnvironment roundEnvironment) {
        String pkgName = null;
        // 首先获取注解元素
        Set elements = roundEnvironment.getElementsAnnotatedWith(Router.class);

        if (elements.isEmpty()) return false;

        // 定义一个 public static 类型的 map 方法
        MethodSpec.Builder mapMethod = MethodSpec.methodBuilder("init").addModifiers(Modifier.PUBLIC, Modifier.FINAL, Modifier.STATIC);

        // 遍历注解元素
        for (Element element: elements) {
            if (element.getKind() == ElementKind.CLASS) {
                pkgName = String.valueOf(processingEnv.getElementUtils().getPackageOf(element).getQualifiedName());
                Router router = element.getAnnotation(Router.class);
                // 获取 activity 的 class name
                ClassName className = ClassName.get((TypeElement) element);
                // 获取 uri 地址
                String path = router.value();
                // 生成代码 Routers.map(uri, xxx.class);
                ClassName router1 = ClassName.get("com.example.router", " TextRouter");
                mapMethod.addStatement("$T.add($S, $T.class)",router1, path, className);
            }
        }

        mapMethod.addCode("n");

        // 生成 RouterMapping 文件
        TypeSpec helloWorldClass = TypeSpec.classBuilder("RouterMapping")
                .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                .addMethod(mapMethod.build())
                .build();

        assert pkgName != null;
        JavaFile javaFile = JavaFile.builder(pkgName, helloWorldClass).build();

        try {
            javaFile.writeTo(processingEnv.getFiler());
        } catch (IOException e) {
             e.printStackTrace();
        }
        return true;

    }

    @Override
    public Set getSupportedAnnotationTypes() {
        Set annotations = new linkedHashSet<>();
        annotations.add(Router.class.getCanonicalName());
        return annotations;
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }
}

Rebuild之后我们就可以看到编译生成的.java文件

 App工程下面也会生成

 不过我们还需要调用RouterMapping.init()方法才能让这两个activity注册成功。可以选择在app的Application中完成初始化操作

public class TextApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        init();
        SecondModule.init();
    }

    private void init(){
        RouterMapping.init();
    }
}

secondmodule中的初始化 

public class SecondModule {

    public static void init(){
        RouterMapping.init();
    }
}

8.实现路由跳转

@Router(value = "MainActivity")
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv = findViewById(R.id.tv);
        tv.setonClickListener(new View.onClickListener() {
            @Override
            public void onClick(View v) {
                   TextRouter.navigate(MainActivity.this,"SecondActivity", null);
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
    }
}

SecondActivity也是同样的操作即可跳转到MainActivity。

因为这里只示范了两个module的跳转,app作为主工程需要对其他子module进行初始化操作所以依赖了所有子工程,不过可以发现MainActivity在没有import入SecondModule的情况下也可以实现跳转,因此路由可以解决不相互依赖的组件之间相互跳转问题,只要在需要被跳转的类上进行注解。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/305861.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号