欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ARouter的介绍和使用

程序员文章站 2024-03-23 22:53:52
...

官方使用说明

官网

典型应用

  1. 从外部URL映射到内部页面,以及参数传递与解析
  2. 跨模块页面跳转,模块间解耦
  3. 拦截跳转过程,处理登陆、埋点等逻辑
  4. 跨模块API调用,通过控制反转来做组件解耦

基础功能

1, 添加依赖和配置

android {
    defaultConfig {
        ...
        //每一个用的build.都要加
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [AROUTER_MODULE_NAME: project.getName()]
            }
        }
    }
}

dependencies {
    // 替换成最新版本, 需要注意的是api
    // 要与compiler匹配使用,均使用最新版可以保证兼容
    compile 'com.alibaba:arouter-api:1.5.0'
    annotationProcessor 'com.alibaba:arouter-compiler:1.2.2'
    ...
}
// 旧版本gradle插件(< 2.2),可以使用apt插件,配置方法见文末'其他#4'
// Kotlin配置参考文末'其他#5'

2 初始化sdk

public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        ARouter.openLog();     // 打印日志
        ARouter.openDebug();   // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
        ARouter.init(this); // 尽可能早,推荐在Application中初始化
    }
}

清单 文件中设置name属性.

2,添加注解-配置路径(无参)

// 在支持路由的页面上添加注解(必选)
// 这里的路径需要注意的是至少需要有两级,/xx/xx
/**
 * 配置路径
 */
@Route( path = "/shop/main2")
public class Main2Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
    }
}

特别注意事项:

如果是接着用calces来做项目的话, Main2Activity文件可能提示找不到.
这要在修改两个地方,一个是.

app {
            applicationName '.App'
            modules ':news',':shop'
        }

给启动添加一个app. 用来初始化ARouter.
另一个是:如果清单文件没有Main2Activity 需要在,project的目录下的src的文件夹下的清单文件中添加.而不是calces中的文件中添加.

3. 跳转并携带参数

ARouter.getInstance().build("/test/1")
            .withString("key3", "888")
            .navigation();

4,接收参数方


@Route(path = "/app/main3")
public class Main3Activity extends AppCompatActivity {
    @Autowired
    String key3;    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        //注入
        ARouter.getInstance().inject(this);
        Toast.makeText(this, key3, Toast.LENGTH_SHORT).show();
    }
}

5 组件之间的跳转

ARouter.getInstance().build("/news/main").navigation();
链接方法是一样的.
只是要跳转过去的模块必须是library加入到当前的项目中的.
如果用了calces管理,则可以直接跳转.
如果不是,则手动添加library.

注意的问题
如果用calces管理,清单文件会合并,那么类名相同的则会有冲突.

6 对象的传递

ARouter.getInstance().build("/app/main3")
                .withString("key3", "888")
                .withObject("test",new Test("hehe","haha")) //对象
                .navigation();

6.1 主要是实现一个接口


@Route(path = "/transerver/gson")
public class JSonBean implements SerializationService {
    private Gson gson;

    @Override
    public <T> T json2Object(String input, Class<T> clazz) {
        return gson.fromJson(input,clazz);
    }

    @Override
    public String object2Json(Object instance) {
        return gson.toJson(instance);
    }

    @Override
    public <T> T parseObject(String input, Type clazz) {
        return gson.fromJson(input,clazz);
    }

    @Override
    public void init(Context context) {
        gson = new Gson();
    }
}

此接口的路径随意. 它的主要目的是把字符串和对象直接相互转换.
它提供框架,我们实现逻辑.比如可以用Gson 也可以用FastJson.

7, 用路由动态添加fragment

创建fragment

@Route(path = "/fragment/blank")
public class BlankFragment extends Fragment {
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_blank, container, false);
    }
}

使用路由查找

 public void btn3(View view) {

        Fragment fragment = (Fragment) ARouter.getInstance().build("/fragment/blank").navigation();

       getSupportFragmentManager().beginTransaction().add(R.id.ll,fragment).commit();

8 拦截器的实现

// 比较经典的应用就是在跳转过程中处理登陆事件,这样就不需要在目标页重复做登陆检查
// 拦截器会在跳转之间执行,多个拦截器会按优先级顺序依次执行
@Interceptor(priority = 8, name = "测试用拦截器")
public class TestInterceptor implements IInterceptor {
    @Override
    public void process(Postcard postcard, InterceptorCallback callback) {
    ...
    callback.onContinue(postcard);  // 处理完成,交还控制权
    // callback.onInterrupt(new RuntimeException("我觉得有点异常"));      // 觉得有问题,中断路由流程

    // 以上两种至少需要调用其中一种,否则不会继续路由
    }

    @Override
    public void init(Context context) {
    // 拦截器的初始化,会在sdk初始化的时候调用该方法,仅会调用一次
    }
}

应用:

ARouter.getInstance().build("/news/main").navigation(this, new NavigationCallback() {
            @Override
            public void onFound(Postcard postcard) {

            }

            @Override
            public void onLost(Postcard postcard) {

            }

            @Override
            public void onArrival(Postcard postcard) {

            }

            //子线程
            @Override
            public void onInterrupt(Postcard postcard) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "拦截了", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });