精华内容
参与话题
问答
  • Arouter使用

    2019-06-29 15:09:25
    ARouter使用与原理 简单使用 1.添加依赖 在根目录下的build.gradle中添加如下代码 javaCompileOptions { annotationProcessorOptions { arguments = [moduleName :project.getName()] } } 在app下的build.gradle...

    ARouter使用与原理

    简单使用

    1.添加依赖
    在app下的build.gradle中添加如下代码

    android {
        defaultConfig {
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [moduleName :project.getName()]
                }
            }
        }
    }
    

    在app下的build.gradle中添加如下代码

    implementation 'com.alibaba:arouter-api:1.3.1'
    annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'
    

    2.自定义一个Application并继承自ApplicationonCreate()方法中初始化Arouter

    ARouter.init(this);
    

    不要忘记在AndroidManifest.xml文件中加入自定义的Application

    3.在Activity/Fragment类上面写上Route path注解
    注意:这里的路径需要注意的是至少需要两级,/xx/xx

    4.Activity/Fragment中将Arouter注入,在onCreate()中加入以下代码即可

    ARouter.getInstance().inject(this);
    

    5.接着在目标Activity/Fragment中声明注解,用来对应
    注意:如果无法对应上则会有Toast提示:路径不匹配

    @Route(path = "/app/MainActivity")
    

    6.调用要打开的Activity/Fragment

    Arouter.getInstance().build("/app/MainActivity").navigation();
    

    完整代码如下:

    @Route(path = "/app/MainActivity")
    public class MainActivity extends AppCompatActivity {
        private static final String TAG = MainActivity.class.getSimpleName();
        private ActivityMainBinding mBinding;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
            ARouter.getInstance().inject(this);
            initClick();
        }
        
        private void initClick() {
            mBinding.btnSecond.setOnClickListener(v ->
            		//打开SecondActivity
                    ARouter.getInstance().build("/app/SecondActivity") .navigation());
        }
    }
    
    

    7.这个框架有注入和绑定那就必然会有解绑或者释放资源的API,这样做的目的是优化内存。

    Arouter.getInstance().destroy();
    

    onDestroy()中调用上面的代码即可释放资源

    以上就是一次Arouter的基本使用,但是后期随着Activity增多,一个Activity可能会被多个Activity打开,上面的写法就会无法管理,所以我们进行一些封装

    1.将注入代码放入到基类中,这样实现一个方法调用

    public void injectARouter() {
        ARouter.getInstance().inject(this);
    }
    

    2.将 Route path进行封装

    public class ActivityConsts {
        public static final String PATH = "path";
    
        public static final String ACTIVITY_URL_MAIN = "/app/MainActivity";
    
        public static final String ACTIVITY_URL_SECOND = "/app/SecondActivity";
    
        public static final String ACTIVITY_URL_LOGIN = "/app/LoginActivity";
    
        public static final String ACTIVITY_URL_THIRD = "/app/ThirdActivity";
    }
    

    3.封装完成后即可实现如下调用方式

    @Route(path = ActivityConsts.ACTIVITY_URL_MAIN)
    public class MainActivity extends AppCompatActivity {
        private static final String TAG = MainActivity.class.getSimpleName();
        private ActivityMainBinding mBinding;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
            ARouter.getInstance().inject(this);
            initClick();
        }
    
        private void initClick() {
            mBinding.btnSecond.setOnClickListener(v ->
                    ARouter.getInstance().build(ActivityConsts.ACTIVITY_URL_SECOND)
                            .navigation());
            mBinding.btnThird.setOnClickListener(v ->
                    ARouter.getInstance()
                            .build(ActivityConsts.ACTIVITY_URL_THIRD)
                            .navigation());
        }
    }
    

    传递参数

    Arouter传递对象的时候,首先该对象需要Parcelable或者Serializable序列化,Parcelable写起来较为麻烦,但是Android Studio有一些插件帮我们自动生成Parcelable序列化了

    Arouter可传递的参数类型还是够我们日常使用的

    如图所示
    可以传递参数,那就可以接收参数,@Autoired()便是接收参数的方法,使用时有两个点要注意。

    1. 括号中最好注明要接受的参数的key值,如@Autoired(name = "age"),否则会出现null或者无法接受到你传递的参数;
    2. 接受参数的变量声明时不要加修饰符,否则会出现无法编译的情况。
    @Autowired(name = "name")
    String mName;
    
    @Autowired(name = "age")
    int mAge;
    
    @Autowired(name = "hero")
    boolean isHero;
    

    简单举个例子:
    传递参数

     mBinding.btnThird.setOnClickListener(v ->
                    ARouter.getInstance()
                            .build(ActivityConsts.ACTIVITY_URL_THIRD)
                            .withString("name", "Tony")
                            .withInt("age", 56)
                            .withBoolean("hero", true)
                            .navigation(this, new CustomNavigationCallback()));
    

    接收参数

    @Route(path = ActivityConsts.ACTIVITY_URL_THIRD, extras = ActivityExtras.EXTRA_LOGIN)
    public class ThirdActivity extends AppCompatActivity {
        private static final String TAG = ThirdActivity.class.getSimpleName();
        
        @Autowired(name = "name")
        String mName;
    
        @Autowired(name = "age")
        int mAge;
    
        @Autowired(name = "hero")
        boolean isHero;
        
    	@Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_third);
            Log.i(TAG, mName + ",  age:" + mAge + ", isHero:" + isHero);
        }
    

    在这里插入图片描述

    界面跳转动画
     mBinding.btnThird.setOnClickListener(v ->
                    ARouter.getInstance()
                            .build(ActivityConsts.ACTIVITY_URL_THIRD)
       						.withTransition(R.anim.xxxxxxx)		//传入动画即可
                            .navigation());
    
    使用URI进行跳转

    在这里插入图片描述

    如何实现startActivityForResult()呢?

    1.在调用Arouter进行Activity进行跳转时,在navigation()中加入requestCode即可。

    2.调用setRsult(requestCode)

    3.在onActivityResult()中根据响应的requestCode获取参数
    在这里插入图片描述
    在这里插入图片描述

    让人兴奋的功能——拦截器

    有些App进入时不需要登录,只有在需要的时候才会登录,这个时候就需要逐一判断,涉及页面较少时也没什么的,但是多了就会影响很麻烦,Arouter很好地解决了这个问题,只需要判断一次,后期可直接进行配置。

    Arouter的拦截器是通过实现IInterceptor接口,重写init()process()方法去完成拦截器内部操作的。

    1.首先定义一个拦截器
    定义UseIInterceptor实现IInterceptor及其方法
    在这里插入图片描述
    2.定义一个被拦截后的处理类
    这一步的目的是我们可以在这类面添加自己需要的操作,不写也行可以直接在拦截时调用NavigationCallback,但是会比较麻烦。
    在这里插入图片描述
    3.这一步就是使用了
    在需要拦截的Activity中加入定义好的拦截常量
    extras = ActivityExtras.EXTRA_LOGIN
    在这里插入图片描述
    在触发事件的里面加入刚才定义的CustomNavigationCallback即可
    在这里插入图片描述
    这时候可能会有疑问UseIInterceptor没有在任何地方调用,怎么会产生拦截呢,卖个关子,讲原理的时候再解开这个疑问。

    上面的代码中在UseIInterceptor的顶部定义了一个@Interceptor(priority = 1),这个是拦截器的优先级,此处有两个点需要注意一下

    1.priority的数值越小优先级越高,越先执行,这根四大组件的广播是相反的。

    2.不可以同时定义两个一样优先级的拦截器,这样会导致项目无法正常编译,而且这也没必要。

    展开全文
  • ARouter 使用教程

    千次阅读 2018-07-13 19:34:51
    ARouter 是阿里开源的,可以看成是 Android 平台中对页面、服务提供路由功能的中间件。 ARouter 直接翻译过来就是路由,可以用来映射页面关系,实现跳转相关的功能。在 Android 中,常被用来进行组件化通讯。 ...

    ARouter 使用教程

    简介

    ARouter 是阿里开源的,可以看成是 Android 平台中对页面、服务提供路由功能的中间件。

    ARouter 直接翻译过来就是路由,可以用来映射页面关系,实现跳转相关的功能。在 Android 中,常被用来进行组件化通讯。


    为什么要使用 ARouter

    我们知道 Android 中默认为我们提供了跳转的功能,比如 startActivity,startService 等。那为什么还需要路由框架呢?在我看来,主要有以下几点吧:

    • 在一些复杂的业务场景下(比如电商),灵活性比较强,很多功能都是运营人员动态配置的,比如下发一个活动页面,我们事先并不知道具体的目标页面,但如果事先做了约定,提前做好页面映射,便可以自由配置。

    • 随着业务量的增长,客户端必然随之膨胀,开发人员的工作量越来越大,比如64K问题,比如协作开发问题。App一般都会走向组件化、插件化的道路,而组件化、插件化的前提就是解耦,那么我们首先要做的就是解耦页面之间的依赖关系。


    ARouter 基本使用

    ARouter github 地址: ARouter

    ARouter 的接入也非常简单,一般来说,需要以下几个步骤。

    第一步:配置 gradle 文件

    android {
        defaultConfig {
    	...
    	javaCompileOptions {
    	    annotationProcessorOptions {
    		arguments = [ moduleName : project.getName() ]
    	    }
    	}
        }
    }
    
    dependencies {
        // Replace with the latest version
        compile 'com.alibaba:arouter-api:?'
        annotationProcessor 'com.alibaba:arouter-compiler:?'
        ...
    }
    

    第二步:初始化 SDK

    if (isDebug()) {           // These two lines must be written before init, otherwise these configurations will be invalid in the init process
        ARouter.openLog();     // Print log
        ARouter.openDebug();   // Turn on debugging mode (If you are running in InstantRun mode, you must turn on debug mode! Online version needs to be closed, otherwise there is a security risk)
    }
    ARouter.init(mApplication); // As early as possible, it is recommended to initialize in the Application
    

    第三步:添加 @Route 注解

    // Add annotations on pages that support routing (required)
    // The path here needs to pay attention to need at least two levels : /xx/xx
    @Route(path = ARouterConstants.COM_ACTIVITY1)
    public class ActivityOne extends AppCompatActivity {
    
        -----
    }
     public static final String COM_ACTIVITY1 = COM + "Activity1";
    

    第四步:调用跳转的代码

    ARouter.getInstance().build(ARouterConstants.COM_ACTIVITY1).navigation();
    

    Activity 之间的跳转

    假设我们现在要从 A 页面跳转到 B 页面,那我们要怎么办呢?

    第一步:在目标页面使用 @Route 注解,并指定 path

    @Route(path = ARouterConstants.COM_ACTIVITY1)
    public class ActivityOne extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_one);
        }
    }
    

    第二步:调用 navigation 方法实现跳转

    ARouter.getInstance().build(ARouterConstants.COM_ACTIVITY1).navigation();
    

    这样,从 A 跳转到 B 的功能便实现了。

    传递参数

    Arouter 的跳转页非常简单,我们可以调用 PostCard 的 withX 等方法传递相应的参数

    image

    比如,我们想传递 String,可以调用 withString,想传递 int,可以调用 withInt ,想传递 Parceable 对象,可以调用 withParcelable。

    ARouter.getInstance().build(ARouterConstants.COM_PARSE_ACTIVITY).withString(NAME,"jun")
            .withInt(AGE,1).withParcelable(PERSON,person).withObject(TEST_OBJ,testObj)
    

    同时 ARouter 还支持传递 Object 对象,只需调用 withObject 方法,同时需要在我们的 moudle 下面增加相关的类。实际上,它的原理是通过将 object 转化成 String,然后存进 intent 中,在解析参数的时候,再通过相应的 key 去除 String,然后转化成 object。

    如果你的项目使用的是 Gson,那可以使用下面的类

    @Route(path = "/service/json")
    public class JsonServiceImpl implements SerializationService {
    
        private Gson mGson;
    
        @Override
        public void init(Context context) {
            mGson = new Gson();
    
        }
    
        @Override
        public <T> T json2Object(String text, Class<T> clazz) {
            checkJson();
            return mGson.fromJson(text, clazz);
        }
    
        @Override
        public String object2Json(Object instance) {
            checkJson();
            return mGson.toJson(instance);
        }
    
        @Override
        public <T> T parseObject(String input, Type clazz) {
            checkJson();
            return mGson.fromJson(input, clazz);
        }
    
        public void checkJson() {
            if (mGson == null) {
                mGson = new Gson();
            }
        }
    }
    
    

    如果你的项目使用的是阿里巴巴的 fastjson,那可以在你的项目增加该类。

    @Route(path = "/service/json")
    public class JsonServiceImpl implements SerializationService {
        @Override
        public void init(Context context) {
    
        }
    
        @Override
        public <T> T json2Object(String text, Class<T> clazz) {
            return JSON.parseObject(text, clazz);
        }
    
        @Override
        public String object2Json(Object instance) {
            return JSON.toJSONString(instance);
        }
    
        @Override
        public <T> T parseObject(String input, Type clazz) {
            return JSON.parseObject(input, clazz);
        }
    }
    
    

    解析参数

    在 ActivityB 中获取参数有两种方式

    • 一种是普通 Activity 那样 getIntent().getXXX,这里就不展开了
    • 另外一种是使用 @Autowired 注解的方式
    @Route(path = ARouterConstants.COM_PARSE_ACTIVITY)
    public class ParseActivity extends AppCompatActivity {
    
        private static final String TAG = "ParseActivity";
    
    
        @Autowired
        String name;
    
        @Autowired
        int age;
    
        @Autowired
        Person person;
    
        @Autowired
        TestObj mTestObj;
    
        @Autowired // 注意字段的名称必须与 withObject 的 key 一致
        TestObj testObj;
        private android.widget.TextView tv;
        
        
            @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_parse);
            // 调用 inject 方法,如果传递过来的参数含有,这样使用 @Autowired 的会自动解析 
            ARouter.getInstance().inject(this);
    }
    

    实现跳转并获取返回结果

    在 activity 的跳转中,我们知道,我们可以用 startActivityForResult 来获取返回结果,那在 ARouter 中要怎么实现呢。

    ARouter 中并没有提供这样的接口,但是我们可以采用曲线救国的原理,通过 Postcard 实现

    Postcard postcard = ARouter.getInstance().build(ARouterConstants.COM_ACTIVITY_RESULT);
    LogisticsCenter.completion(postcard);
    Class<?> destination = postcard.getDestination();
    

    这里得到的 destination 类就是我们要跳转的类,这样 fragment 的 startActivityForResult 就好办了

    Intent intent = new Intent(getContext(),destination);
    startActivityForResult(intent,requestCode);
    

    暴露服务

    这里说到的服务不是 Android 四大组件中的 Service,这里的服务是接口开发的概念。即把部分功能或者业务封装起来。

    比如,我们想调用某个接口,一般来说,可以这样做。

    • 首先我们定义一个接口,并实现该接口,并采用 @Route 注解指定相应的 path:
    public interface HelloService extends IProvider {
        String sayHello(String name);
    }
    
    // 实现接口
    @Route(path = ARouterConstants.SERVICE_HELLO, name = "test service")
    public class HelloServiceImpl implements HelloService {
    
        private Context mContext;
    
        @Override
        public String sayHello(String name) {
            Toast.makeText(mContext,this.getClass().getSimpleName()+": sayHello"+" "+name,Toast.LENGTH_SHORT).show();
            return "hello, " + name;
        }
    
        @Override
        public void init(Context context) {
            mContext = context;
        }
    }
    
    
    • 接着调用 Poatcard 的 navigation 方法获取到我们的实例:
    HelloService helloService = (HelloService) ARouter.getInstance().build(ARouterConstants.SERVICE_HELLO).navigation();
    String result = helloService.sayHello("xujun");
    

    URL 跳转

    我们先来看一下我们 URL 跳转的设计

    image

    从图中可以看到,我们是用一个中间跳转页面来管理所有 Activity 的跳转的,当接受到跳转指令的时候,中转 Activity 会进行相应的处理,从而跳转到响应的页面。

    这样设计的好处是:

    • 我们的目标 Activity(页面 A,页面 B 等)不需要对外暴露

    中转 Activity:

    public class UrlSchemeActivity extends AppCompatActivity {
    
        private static final String TAG = "UrlSchemeActivity";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_url);
            //        直接通过ARouter处理外部Uri
            final Uri uri = getIntent().getData();
            Log.i(TAG, "onCreate: uri=" + uri);
            ARouter.getInstance().build(uri).navigation(this, new NavCallback() {
                @Override
                public void onArrival(Postcard postcard) {
                    finish();
                }
    
                @Override
                public void onLost(Postcard postcard) {
                    super.onLost(postcard);
                    Log.i(TAG, "onLost: uri=" + uri);
                    //                Toast.makeText(UrlSchemeActivity.this,String.format("找不到可以处理该
                    // URI %s 的 Activity",uri),Toast.LENGTH_SHORT).show();
                    // 找不到的时候 finish 掉当前 activity
                    finish();
                }
            });
            
        }
    }
    

    当我们接收到跳转 uri 的时候,我们将它交给路由 ARouter,去进行分发。

    接下来我们来看一下我们在 AndroidManifest 的配置

    <activity android:name=".testAcivity.UrlSchemeActivity">
        <intent-filter>
            <data
                android:host="m.aliyun.com"
                android:scheme="arouter"/>
    
            <action android:name="android.intent.action.VIEW"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.BROWSABLE"/>
        </intent-filter>
    </activity>
    
    
    

    这里面的 host 、scheme 字段很重要。点击 url 会根据这两个字段会调起本地的 Activity 。

    接下来,看一下我们的 HTML

    <!DOCTYPE html>
    <html>
    <head>
        <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
        <title></title>
    </head>
    
    <body>
    
    <h2>跳转测试</h2>
    
    <h2>自定义Scheme[通常来说都是这样的]</h2>
    <p>
        <a href="arouter://m.aliyun.com/test/activity1">arouter://m.aliyun.com/test/activity1
        </a>
    </p>
    <p>
        <a href="arouter://m.aliyun.com/test/activity1?url=https%3a%2f%2fm.abc.com%3fa%3db%26c%3dd">
            测试URL Encode情况
        </a>
    </p>
    <p>
        <a href="arouter://m.aliyun.com/test/activity1?name=alex&age=18&boy=true&high=180&obj=%7b%22name%22%3a%22jack%22%2c%22id%22%3a666%7d">
            arouter://m.aliyun.com/test/activity1?name=alex&age=18&boy=true&high=180&
            obj={"name":"jack","id":"666"}
        </a>
    </p>
    
    </body>
    </html>
    
    

    注意 a 标签里面的 arouter://m.aliyun.com 分别代表着 scheme 、host ;/com/URLActivity1 就是目标 Activity 的注解。

    如果需要接收 URL 中的参数,需要在 Activity 调用自动注入初始化方法;

    ARouter.getInstance().inject(this);
    

    需要注意的是,如果不使用自动注入,那么可以不写 ARouter.getInstance().inject(this),但是需要取值的字段仍然需要标上 @Autowired 注解,因为 只有标上注解之后,ARouter 才能知道以哪一种数据类型提取 URL 中的参数并放入 Intent 中,这样您才能在 intent 中获取到对应的参数


    其他用法

    监听 ARouter 的执行过程

    ARouter.getInstance()
            .build(ARouterConstants.COM_ACTIVITY1)
            .navigation(this, new NavCallback() {
    
                @Override
                public void onFound(Postcard postcard) {
                    Log.e(TAG, "onArrival: 找到了 ");
                }
    
                @Override
                public void onLost(Postcard postcard) {
                    Log.e(TAG, "onArrival: 找不到了 ");
                }
    
                @Override
                public void onArrival(Postcard postcard) {
                    Log.e(TAG, "onArrival: 跳转完了 ");
                }
    
                @Override
                public void onInterrupt(Postcard postcard) {
                    Log.e(TAG, "onArrival: 被拦截了 ");
                }
            });
    
    
    

    在当前的 moudle 中,如果有找到 @Route(path=ARouterConstants.COM_ACTIVITY1) 注解的目标 activity,会先后回调 onFound,onArrival;如果找不到的话,会回调 onLost;如果被拦截了,会回调 onInterrupt 方法。

    Interceptor 拦截器

    @Interceptor(priority = 8, name = "test interceptor")
    public class TestInterceptor implements IInterceptor {
        @Override
        public void process(Postcard postcard, InterceptorCallback callback) {
            ...
            // No problem! hand over control to the framework
            callback.onContinue(postcard);  
            
            // Interrupt routing process
            // callback.onInterrupt(new RuntimeException("Something exception"));      
    
            // The above two types need to call at least one of them, otherwise it will not continue routing
        }
    
        @Override
        public void init(Context context) {
    	    // Interceptor initialization, this method will be called when sdk is initialized, it will only be called once
        }
    }
    

    Demo 地址


    推荐阅读

    一步步拆解 LeakCanary

    Android 面试必备 - http 与 https 协议

    Android 面试必备 - 计算机网络基本知识(TCP,UDP,Http,https)

    Android 面试必备 - 线程

    Android_interview github 地址

    扫一扫,欢迎关注我的微信公众号 stormjun94, 目前专注于 Android 开发,主要分享 Android开发相关知识和技术人成长历程,包括个人总结,职场经验,面试经验等。

    展开全文
  • Arouter踩坑小记

    千次阅读 2018-04-07 20:29:41
    Error:Error converting bytecode to dex: 不同的模块使用了相同的分组,例如 AMoudle 定义了 @router(path=”/com/a”), BMoudle也定义了@router(path=”/com/b”) 就会出现这个问题,暴露服务出现这个问题同理......

    Error:Error converting bytecode to dex:

    不同的模块使用了相同的分组,例如 AMoudle 定义了 @router(path=”/com/a”), BMoudle也定义了@router(path=”/com/b”) 就会出现这个问题,暴露服务出现这个问题同理。

    使用拦截器实现登录校验

    流程如下:
    1,标记Activity需要登录(利用Arouter的extras参数,值为int类型)

    @Route(path = RouterPath.IntentPath.AcgApp.Debug.HOBBIES_ACTIVITY, extras = ArouterConfig.NEED_LOGIN)
    public class HobbiesActivity extends BaseActivity {
    }

    2,声明拦截器,如果跳转的是需要登录的Activity则判断是否已经登录

    @Interceptor(priority = 999)
    public class LoginInterceptor implements IInterceptor {
        private Context mContext;
    
        @Override
        public void process(Postcard postcard, InterceptorCallback callback) {
            //判断是否需要登录
            if (postcard.getExtra() == ArouterConfig.NEED_LOGIN) {
                boolean isLogin = xxx;
                if (isLogin) {
                    callback.onContinue(postcard);
                } else {
                //跳转到登录,并且把需要跳转的url带给登录页,登录成功跳转该url
                    String originPath = postcard.getPath();
                    ARouter.getInstance().build(RouterPath.IntentPath.AcgApp.Debug.PHONE_LOGIN_ACTIVITY)
                            .withString(ArouterConfig.AROUTER_LOGIN_SKIP_PATH, originPath)
                            .navigation(mContext);
                }
            } else {
                callback.onContinue(postcard);
            }
    
        }
    
        @Override
        public void init(Context context) {
            mContext = context;
        }
    }
    展开全文
  • ARouter的使用

    2020-08-29 11:26:06
    ARouter是阿里Android技术团队开源的一款路由框架,可以使我们在进行模块化开发时提供更好更方便的页面跳转。 阿里巴巴开源的路由gitHub地址 下面介绍一下它的基本使用以及会出现的问题: 同一模块下的活动的跳转 ...

    简介:
    ARouter是阿里Android技术团队开源的一款路由框架,可以使我们在进行模块化开发时提供更好更方便的页面跳转。

    阿里巴巴开源的路由gitHub地址

    下面介绍一下它的基本使用以及会出现的问题:


    简单页面跳转
    • 同一模块下的活动的跳转
      (1)首先我们要在bulid.gradle中添加依赖:
    android {
       ···
        defaultConfig {
           ···
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [AROUTER_MODULE_NAME:project.getName()]
                }
            }
        }
    
       ···
    
    dependencies {
       //这里的版本根据github上面lastest version为准
        implementation 'com.alibaba:arouter-api:1.5.0'  
     
         //这里的版本根据github上面lastest version为准
        annotationProcessor 'com.alibaba:arouter-compiler:1.2.2'   
    }
    

    (2)在Application中进行ARouter的初始化,释放资源一般也在Application的销毁方法写

    public class HomeApplication extends Application {
        //ARouter调试开关
        private boolean isDebug = true;
        @Override
        public void onCreate() {
            super.onCreate();
            if (isDebug) {
                //以下两种属性必须在初始化之前开启
                //打印日志
                ARouter.openLog();
                //开启调试模式(如果在InstantRun模式下进行,必须开启调试模式)
                // 线上版本需要关闭,否则会有安全风险
                ARouter.openDebug();
            }
            ARouter.init(this);
        }
    }
    
    

    (3)在AndroidManifest中配置自定义的Application
    在这里插入图片描述
    (4)在同一模块下建立两个活动,并注册
    在这里插入图片描述

    @Route(path = "/app/SecondActivity")
    public class SecondActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_second);
        }
    }
    

    在这里插入图片描述


    跳转的页面的Route path 注解一定与在跳转页面之前ARouter.getInstance().bulid函数参数一致

    出现 ARouter::Compiler >>> No module name, for more information, look at gradle log.的错误原因:

    全部module包括module依赖的module,在每个module的 build.gradle中加上依赖的代码

    在添加依赖时一定要 arguments = [AROUTER_MODULE_NAME:project.getName()] AROUTER_MODULE_NAME 不是 moduleName

    出现there is no route matched的错误原因(个人在项目中使用了java的配置,用kotlin写的项目,浪费了很多时间)所以在这里给大家看看java和kotlin两种配置,希望大家要犯这种错误:

    • Java配置
      在这里插入图片描述
    • kotlin配置
    apply plugin: 'kotlin-android'
    apply plugin: 'kotlin-android-extensions'
    apply plugin: 'kotlin-kapt'
    
    android {
    
        defaultConfig {
            .......
            kapt {
                arguments {
                    arg("AROUTER_MODULE_NAME", project.getName())
                }
            }
        }
        ......
    }
    
    dependencies {
        implementation fileTree(dir: "libs", include: ["*.jar"])
        implementation project(":base")
       //组件化项目一般在base类中引入依赖
       // implementation 'com.alibaba:arouter-api:1.3.1'
        kapt 'com.alibaba:arouter-compiler:1.1.4'
    }
    
    
    • 不同模块下的活动的跳转和上面的方式是一样的,但有几条注意事项要注意一下
      (1) 不同模块下活动的跳转,必须有依赖关系,比如说Module A 中想要跳转到Module B的页面,Module A 必须依赖Module B
      (2) 不同模块的注解名的一级包名不可以相同

    带参数的页面跳转
    ARouter.getInstance().build("/show/second").navigation(this,123)
    

    在接受数据的页面重写onActivityResult()方法

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
            super.onActivityResult(requestCode, resultCode, data)
            when(requestCode) {
                123 -> if(resultCode == 1)
                    if (data != null) {
                        Log.e("MAIN","接收到了 ${data.getStringExtra("name")}")
                    }
                else -> Log.e("MAIN","无")
            }
        }
    

    在传递数据的页面设置如下(设置了返回码以及需要传递的数据):

    		val intent = Intent()
            intent.putExtra("name","zyy")
            setResult(1,intent)
    

    onActivityResult()方法是活动销毁之后调用的方法,我们可以在传递参数的页面调用finish()
    如果我们通过返回键来调用,则需要重写onBackPressed()方法


    查看回调
    ARouter.getInstance().build("/show/second").navigation(this,object : NavCallback() {
                    override fun onArrival(postcard: Postcard?) {
                        //TODO("Not yet implemented")
                        Log.e("SHOW","跳转成功")
                    }
    
                    override fun onFound(postcard: Postcard?) {
                        super.onFound(postcard)
                        Log.e("SHOW","找到了")
                    }
    
                    override fun onInterrupt(postcard: Postcard?) {
                        super.onInterrupt(postcard)
                        Log.e("SHOW","被拦截了")
                    }
    
                    override fun onLost(postcard: Postcard?) {
                        super.onLost(postcard)
                        Log.e("SHOW","找不到了")
                    }
                })
    

    拦截器
    @Interceptor(priority = 1)
    class MyIIntercepter() : IInterceptor {
        override fun init(context: Context?) {
    //        TODO("Not yet implemented")
    
        }
    
        override fun process(postcard: Postcard, callback: InterceptorCallback?) {
    //        TODO("Not yet implemented")
            if (postcard.path.equals("/show/second")) {
                Log.e("MAIN","成功拦截")
            }
        }
    }
    

    自定义拦截器需要实现IInterceptor接口,并且添加@Interceptor的注解,其中priority为拦截器的优先级,值越小,优先级越高;然后实现pocess()和init()方法。

    优先级不能相同,否则编译会出现问题

    展开全文
  • ARouter 基础使用详解

    2019-04-16 23:05:10
    文章目录参考资料配置ARouter初始化与销毁初始化销毁路由注解与跳转Activity之间的跳转路径定义代码示例Fragment之间的切换Fragment注入路由Fragment的获取与切换带参数的跳转示例代码接收传递的参数示例代码路由回...
  • ARouter 原理浅析

    千次阅读 2019-02-18 11:31:42
    ARouter ARouter 是通过注解的方式结合android提供的启动Activity的API实现页面的跳转及参数的传递的。 ARouter 提供三种注解类型: @Route:注解跳转页面或是需要实例化的的类 @Interceptor:注解自定义拦截器 ...
  • ARouter实现分析

    2019-05-14 16:21:58
    网络上已经有很多分析ARouter的文章了,但是各有偏重;这里整理一些关键技术点,尽量能够将完整的流程都覆盖到,并且将一些容易错误使用的细节列举出来。 Java注解处理 ARouter大量使用了Java注解,并且通过APT...
  • Android 路由框架ARouter最佳实践

    万次阅读 多人点赞 2017-07-27 18:05:45
    本文出自【赵彦军的博客】 一:什么是路由?说简单点就是映射页面跳转关系的,当然它也包含跳转相关的一切功能。二:为什么需要路由Android系统已经给我们提供了api来做页面跳转,比如startActivity,为什么还需要...
  • ARouter原理剖析和自己实现EasyRouter

    千次阅读 2018-08-17 14:46:39
    本篇文章分为两个部分,第一部分着重剖析ARouter路由的原理,第二部分会带着大家仿照ARouter撸一个自己的路由框架,我们自己撸的路由框架可能没有Arouter众多的功能如过滤器、provider等,但是却实现了...
  • ARouter源码解析

    千次阅读 2019-07-09 23:13:33
    文章目录ARouter概述ARouter使用ARouter源码分析arouter-annotation注解arouter-compiler注解编译器arouter-api路由控制ARouter 初始化ARouter API跳转拦截器原理参考文档 ARouter概述 ARouter 是一个用于帮助 ...
  • ARouter基本使用详情

    万次阅读 2017-08-13 22:09:59
    由于公司项目进行了拆分,我司就用上了阿里的这个ARouter框架。对于为啥使用这个框架,我相信很多人知道原因,借用阿里的云栖社区的一段话:我们所使用的原生路由方案一般是通过显式intent和隐式intent两种方式实现...
  • 但是由于各个组件在不同的model甚至在不同的项目中,这样他们之间的通信就成了问题,而 ARouter的出现就是让组件间、模块间是实现完全的独立。 并且后台还可以通过路由的机制控制Android界面调用实现...
  • 在使用ARouter时在小模块内的页面跳转多个参数的页面传参构建也长长的 举个栗子… ARouter.getInstance().build(Constants.PATH_TEST1) .withString(Constants.PARAM_NAME, name) .withInt(&amp;amp;amp;...
  • Android跳转-ARouter详细使用教程

    万次阅读 2017-09-14 16:28:04
    一、简介Android平台中对页面、服务提供路由功能(跳转)的一个库1.1 最新版本 ...支持直接解析标准URL进行跳转,并自动注入参数到目标页面中 支持多模块工程使用 支持添加多个拦截器,自定义拦截顺序 支持依赖注入,可单
  • ARouter

    2019-12-24 10:03:44
    更快捷的同步开发与更简单的单独调试,而ARouter的出现就是让组件间、模块间是实现完全的独立。 ARouter是:阿里巴巴自研路由框架,主要解决组件间、模块间的 界面跳转 问题。 今天用最简单的方式讲解Arouter的...
  • 使用阿里ARouter路由实现组件化(模块化)开发流程

    万次阅读 多人点赞 2017-12-08 17:05:20
    这是阿里对Arouter的定位,那么我们一起来梳理一下Arouter使用流程,和使用中我所遇到的一些问题! 先来看看有哪些功能 模块化的要解决的问题 模块间页面跳转(路由); 模块间事件通信; 模块间服务...
  • 理解Arouter,实现Arouter基础功能

    千次阅读 2018-07-25 14:27:43
    一 使用注解在编译时将路径的数据封装在RouteMeta类中 并且在实现IRouteGroup类中 添加到参数atlas map中 特殊的类 @AutoService(Processor.class) 主要的作用是注解 processor类,并对其生成 META-INF 的配置...
  • ARouter路由框架解析

    千次阅读 2018-04-01 14:23:03
    一、ARouter介绍及主要应用场景: 1、介绍: 是ARouter是阿里巴巴开源的Android平台中对页面、服务提供路由功能的中间件,提倡的是简单且够用。 2、原生的路由方案存在的问题 首先谈一谈原生的路由方案存在...
  • ARouter源码解析05-自动参数注入

    千次阅读 2017-07-23 20:53:55
    这篇文章来分析ARouter的自动参数注入 以ARouter示例程序中的BlankFragment为例 @Route(path = "/test/fragment") public class BlankFragment extends Fragment { @Autowired String name; @Autowired(required = ...
  • ddad

空空如也

1 2 3 4 5 ... 20
收藏数 5,019
精华内容 2,007
关键字:

arouter