09.使用注解搭建路由[综合案例]php
1.Annotation库的简单介绍 2.@Nullable和@NonNull 3.资源类型注释 4.类型定义注释 5.线程注释 6.RGB颜色纸注释 7.值范围注释 8.权限注释 9.重写函数注释 10.返回值注释 11.@Keep注释 12.@SuppressWarnings注解 13.其余
03.注解详细介绍android
04.APT技术详解git
06.自定义annotation注解github
07.注解之兼容kotlinsegmentfault
什么是apt
编译时注解。
大概原理
annotationProcessor和apt区别
什么是jack编译方式?
Jack工具的主要优点
项目目录结构如图:
使用apt实现点击事件【编译期注解生成代码】
使用apt实现setContentView功能【运行期注解案例】
使用apt实现路由【综合型案例】
以下所示
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化OnceClick,并设置点击事件间隔是2秒 OnceInit.once(this,2000); } @OnceClick(R.id.tv_1) public void Click1(){ Log.d("tag--------------------","tv_1"); }
以下所示,在app/build/generated/source/apt/debug/MainActivity$$_Once_Proxy目录下
// 编译生成的代码,不要修改 // 更多内容:https://github.com/yangchong211 package com.ycbjie.ycapt; import android.view.View; import com.ycbjie.api.Finder; import com.ycbjie.api.AbstractInjector; public class MainActivity$$_Once_Proxy<T extends MainActivity> implements AbstractInjector<T> { public long intervalTime; @Override public void setIntervalTime(long time) { intervalTime = time; } @Override public void inject(final Finder finder, final T target, Object source) { View view; view = finder.findViewById(source, 2131165325); if(view != null){ view.setOnClickListener(new View.OnClickListener() { long time = 0L; @Override public void onClick(View v) { long temp = System.currentTimeMillis(); if (temp - time >= intervalTime) { time = temp; target.Click1(); } }}); } view = finder.findViewById(source, 2131165326); if(view != null){ view.setOnClickListener(new View.OnClickListener() { long time = 0L; @Override public void onClick(View v) { long temp = System.currentTimeMillis(); if (temp - time >= intervalTime) { time = temp; target.Click2(v); } }}); } } }
首先先定义自定义注解
//@Retention用来修饰这是一个什么类型的注解。这里表示该注解是一个运行时注解。 @Retention(RetentionPolicy.RUNTIME) //@Target用来表示这个注解可使用在哪些地方。好比:类、方法、属性、接口等等。 //这里ElementType.TYPE 表示这个注解能够用来修饰:Class, interface or enum declaration。 //当你用ContentView修饰一个方法时,编译器会提示错误。 @Target({ElementType.TYPE}) //这里的interface并非说ContentView是一个接口。 //就像申明类用关键字class。申明枚举用enum。申明注解用的就是@interface。 public @interface ContentView { //返回值表示这个注解里能够存放什么类型值。 int value(); }
而后须要在activity中作注解解析
@SuppressLint("Registered") public class ContentActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //注解解析 //遍历全部的子类 for (Class c = this.getClass(); c != Context.class; c = c.getSuperclass()) { assert c != null; //找到修饰了注解ContentView的类 ContentView annotation = (ContentView) c.getAnnotation(ContentView.class); if (annotation != null) { try { //获取ContentView的属性值 int value = annotation.value(); //调用setContentView方法设置view this.setContentView(value); } catch (RuntimeException e) { e.printStackTrace(); } return; } } } }
关于如何使用,注意你写的Activity须要实现ContentActivity,才能让注解生效
@ContentView(R.layout.activity_four) public class FourActivity extends ContentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); findViewById(R.id.tv_1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(FourActivity.this,"运行期注解",Toast.LENGTH_SHORT).show(); } }); } }
[9.6 路由框架设计注意要点]()
9.9 路由开源库的使用
不带参数直接跳转
@Router(path = Path.six) public class SixActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_six); } } ARouter.getsInstance().build(Path.six) .navigation(MainActivity.this, new NavigationCallback() { @Override public void onFound(Postcard postcard) { Log.e("NavigationCallback","找到跳转页面"); } @Override public void onLost(Postcard postcard) { Log.e("NavigationCallback","未找到"); } @Override public void onArrival(Postcard postcard) { Log.e("NavigationCallback","成功跳转"); } });
带参数跳转
@Router(path = Path.five) public class FiveActivity extends AppCompatActivity { @Extra String title; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_five); //添加这行代码,实际上就是自动生成了下面获取参数值的代码 ARouter.getsInstance().inject(this); //若是不添加插入注解,则能够直接用下面的代码。 //Intent intent = getIntent(); //String title = intent.getStringExtra("title"); Toast.makeText(this, "title=" + title, Toast.LENGTH_SHORT).show(); } } Bundle bundle = new Bundle(); bundle.putString("title","标题-------------"); ARouter.getsInstance() .build(Path.five) .withBundle(bundle) .navigation();
路由注解生成的代码位置