Android Apt之Activity Route的示例

 更新时间:2018年01月30日 09:15:00   转载 作者:三十二蝉  
本篇文章主要介绍了Android Apt之Activity Route的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

前言

什么是Apt

APT从原理上讲是一个编译期的注解处理工具(Annotation Processing Tool)。一些主流的三方库(ButterKnife,Glide)都用到了这个技术来生成代码。

Apt有什么好处

  1. 自动生成模板代码,提高了开发效率
  2. 编译期对注解的处理,相对于运行期对注解的处理,性能上要好的多。

Gradle脚本中的apt和annotationProcessor

这两个从广义上说都是编译期的注解处理工具。只不过android-apt(其实是一个gradle插件,apt是插件命令)是早期的github的一个开源项目,annotationProcessor是gradle build tools 2.2之后自带的编译期注解工具(官方支持的,可替代开源的gradle插件android-apt)。android-apt的作者已经发表声明表示Android Studio插件已经支持annotationProcessor,并且会警告和阻止使用android-apt。总的来说,看你的gradle build tools的版本,低版本用android-apt(需要引入插件),高版本用annotationProcessor(无需引入插件)

代码设计

需求分析

这里将route模块分成三部分(一个android library,两个java library)
1、router-annotation(java library)

这里java工程里面只放注解的声明类。这里只实现了两个注解RouterActivity、RouterField。

2、router-compiler (java library)

这个工程是编译期依赖的工程,作用是编译期扫描代码,根据RouterActivity、RouterField这两个注解的使用,生成相关代码。这里需要讲下如何扫描代码并且生成代码的。这部分功能的实现主要依赖两个库:Google的auto-service(扫描代码),Squareup的javapoet(生成代码)

3、router (android library)

主要逻辑代码。在这个模块中会定义一些功能类和接口。router-compiler模块可以根据这些接口和功能类generate逻辑代码。需要注意的是router-compiler是不需要依赖router的,router-compiler是根据包名+类名的方式获取类的。

代码实现

router-annotation

RouterActivity是一个注解,用此注解修饰的Activity根据指定的路由地址,会自动添加到路由表中,当系统挂载了路由表之后,就可根据指定的路由地址来访问特定的Activity了。代码如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface RouterActivity {
  String[] value();
}

这里Activity可用多个路由地址修改。

RouterField是一个用于表示Activity跳转时参数传递的注解,用这个注解修饰的成员变量,表示为接收Intent参数的变量。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RouterField {
  String[] value();
}

router-compiler

这个模块只包含一个类RouterProcessor,这个类的大致结构如下:

//此处用AutoService注解,就可实现编译期自动扫描代码
@AutoService(Processor.class)
public class RouterProcessor extends AbstractProcessor{
  private Elements elementUtils;
  private String targetModuleName = "";
  @Override
  public Set<String> getSupportedAnnotationTypes() {
    //支持的注解类型
    return Collections.singleton(RouterActivity.class.getCanonicalName());
  }

  @Override
  public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
   //处理代码扫描结果的关键函数
   ...
    return true;
  }

  @Override
  public synchronized void init(ProcessingEnvironment processingEnvironment) {
    super.init(processingEnvironment);
    //在扫描代码之前可从build.gradle中读取一些配置项
  }

  @Override
  public SourceVersion getSupportedSourceVersion() {
    //表示支持的Jdk版本
    return SourceVersion.RELEASE_7;
  }
}

下面分别讲解一下函数的实现:

1、init函数

我们的项目大多都是多module的形式,这时候我们就需要为每个module创建一个Activity路由注册表,然后在Application初始化的时候将所有的路由注册表挂载上,达到Activity路由跳转的目的。这里我们在init函数中,配置每个模块路由表的前缀名称。

 @Override
  public synchronized void init(ProcessingEnvironment processingEnvironment) {
    super.init(processingEnvironment);
    elementUtils = processingEnvironment.getElementUtils();
    Map<String, String> map = processingEnvironment.getOptions();
    Set<String> keys = map.keySet();
    for (String key: keys) {
      if ("targetModuleName".equals(key)) {
        this.targetModuleName = map.get(key);
      }
      System.out.println(key + " + " + map.get(key));

并在module的build.gradle文件下配置如下代码:

apt {
  arguments {
    targetModuleName 'moduleName'
  }
}

2、process函数

这个函数的大致流程如下:找到所有被RouterActivity修饰的Activity;实现router模块中的RouterInitializer接口,将每个Activity的路由地址加入路由表中;同时为每个Activity创建一个XXXActivityHelper(用于更友好的Activity调整),并将每个XXXAcitivyHelper放入RouterHelper中,提供get方法获取。process函数的具体实现,可详见项目源码(都是一些代码生成的语句,没有多少逻辑)。

router

  1. RouterInitializer接口,用于每个module注册表的实现
  2. ActivityHelper,封装了一些参数解析逻辑,更方便的Activity跳转
  3. SafeBundle, 对Activity的参数进行了封装
  4. Router, 路由核心类,支持url跳转,解析url,并实现跳转。
  5. 'RouterCenterActivity', 可被外部浏览器唤起的中转Activity(外面根据url scheme唤醒RouterCenterActivity,RouterCenterActivity分发路由地址)

代码使用

初始化Router

public class DemoApp extends Application {

  @Override
  public void onCreate() {
    super.onCreate();
    Router.init("demo"); //自定义scheme协议
  }
}

Activity跳转

@RouterActivity({"main"})
public class MainActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    findViewById(R.id.btn_second).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        RouterHelper.getSecondActivityHelper().start(MainActivity.this);
      }
    });
  }
}

@RouterActivity({"second"})
public class SecondActivity extends AppCompatActivity {
  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
  }
}

build目录生成的代码如下:

详细代码可查看:Github项目

现阶段代码还不完善,后期会添加更多功能。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Android RecyclerView艺术般的控件使用完全解析

    Android RecyclerView艺术般的控件使用完全解析

    这篇文章主要介绍了Android RecyclerView艺术般的控件使用完全解析的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-07-07
  • Android开发中软键盘的显示和隐藏

    Android开发中软键盘的显示和隐藏

    本篇内容通过代码示例给大家详细讲解了关于Android开发中软键盘的显示和隐藏的代码实现过程以及容易忽略的问题,来学习下吧。
    2017-12-12
  • Android使用BottomNavigationBar实现导航栏功能

    Android使用BottomNavigationBar实现导航栏功能

    这篇文章主要介绍了Android使用BottomNavigationBar实现导航栏功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-08-08
  • Android实现手机壁纸改变的方法

    Android实现手机壁纸改变的方法

    这篇文章主要介绍了Android实现手机壁纸改变的方法,以完整实例形式分析了Android手机壁纸改变的方法,包括页面布局及属性设置的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-09-09
  • Android开发之ListView列表刷新和加载更多实现方法

    Android开发之ListView列表刷新和加载更多实现方法

    这篇文章主要介绍了Android开发之ListView列表刷新和加载更多实现方法,实例分析了ListView列表操作的相关技巧,需要的朋友可以参考下
    2015-06-06
  • Retrofit 源码分析初探

    Retrofit 源码分析初探

    这篇文章主要介绍了Retrofit 源码分析初探,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • Android实现手电筒电源键关闭功能

    Android实现手电筒电源键关闭功能

    这篇文章主要介绍了Android实现手电筒电源键关闭功能,在打开手电筒之后,机器休眠,客户要求点击电源键,手电筒需要关闭,下面小编给大家分享实现代码,需要的朋友可以参考下
    2017-11-11
  • Android自定义View实现自动吸附功能

    Android自定义View实现自动吸附功能

    这篇文章主要为大家详细介绍了Android自定义View实现自动吸附功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-01-01
  • 分享Android开发中最有效率最快的循环代码

    分享Android开发中最有效率最快的循环代码

    分享Android开发中最有效率最快的循环代码,需要的朋友可以参考下
    2013-01-01
  • Android 中ViewPager中使用WebView的注意事项

    Android 中ViewPager中使用WebView的注意事项

    这篇文章主要介绍了Android 中ViewPager中使用WebView的注意事项的相关资料,希望通过本文大家在使用过程中遇到这样的问题解决,需要的朋友可以参考下
    2017-09-09

最新评论