美文网首页
ARouter之基础应用篇

ARouter之基础应用篇

作者: 极客天空 | 来源:发表于2020-09-18 10:50 被阅读0次

    一 、ARouter的配置

    在对应的 build.gradle 文件中配置 ARouter 的相关依赖如下:

    android {
        defaultConfig {
            ...
            //arouter start
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [AROUTER_MODULE_NAME: project.getName()]
                }
            }
            //arouter end
        }
    }
    
    dependencies {
        // 替换成最新版本, 需要注意的是api
        // 要与compiler匹配使用,均使用最新版可以保证兼容
       //arouter start
        implementation 'com.alibaba:arouter-api:1.5.0'
        annotationProcessor 'com.alibaba:arouter-compiler:1.2.2'
        annotationProcessor 'com.alibaba:arouter-annotation:1.0.6'
        //arouter end
        ...
    }
    

    可以选择配置路由表自动加载,在项目下面的 build.gradle 文件中进行配置,配置方式如下:

    apply plugin: 'com.alibaba.arouter'
    
    buildscript {
        repositories {
            jcenter()
        }
        dependencies {  
           classpath "com.alibaba:arouter-register:1.0.2"
        }
    }
    

    二、基础设置

    • 打开日志并打印堆栈
     ARouter.openLog();
    
    • 开启调试模式(InstantRun需要开启
     ARouter.openDebug();
    
    • 初始化ARouter
                    // 初始化
                    // 调试模式不是必须开启,但是为了防止有用户开启了InstantRun,但是
                    // 忘了开调试模式,导致无法使用Demo,如果使用了InstantRun,必须在
                    // 初始化之前开启调试模式,但是上线前需要关闭,InstantRun仅用于开
                    // 发阶段,线上开启调试模式有安全风险,可以使用BuildConfig.DEBUG
                    // 来区分环境
                    ARouter.openDebug();
                    ARouter.init(getApplication());
    
    • 关闭ARouter
     ARouter.getInstance().destroy();
    

    三、基础功能

    • 简单的应用内跳转
      只需要在要跳转的 Activity 上添加 @Route 注解即可,具体如下:
    @Route(path = "/test/activity1", name = "测试用 Activity")
    public class ActivityTest1 extends AppCompatActivity {
      ------
    }
      //跳转的地方调用
      ARouter.getInstance().build("/test/activity1")  .navigation();
    
    • 普通跳转ForResult
     startActivityForResult(new Intent(MainActivity.this,
                            ActivityFirst.class), 1);
    
    public class ActivityFirst extends AppCompatActivity {
       ----------
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            // TODO Auto-generated method stub
            super.onActivityResult(requestCode, resultCode, data);
            Log.d(MainActivity.TAG,">>>>-ActivityFirst---requestCode="+requestCode+"--resultCode="+resultCode);
            if (requestCode == 1 && resultCode == 4) {
                Log.d(MainActivity.TAG,">>>>-ActivityFirst---");
                String s=data.getStringExtra("bian");
                textview.setText(s);
            }
        }
    
    }
    
    • 路由跳转ForResult
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    --------
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            // TODO Auto-generated method stub
            super.onActivityResult(requestCode, resultCode, data);
            Log.d(MainActivity.TAG,">>>>----requestCode="+requestCode+"--resultCode="+resultCode);
            if (requestCode == 2 && resultCode == 6) {
                String s=data.getStringExtra("key");
                Log.d(MainActivity.TAG,">>>>-ActivityFirst---s="+s);
            }
        }
    --------
    }
    
     ARouter.getInstance()
                            .build("/test/activity2")
                            .navigation(this, 2);
    
    • 携带参数的应用内跳转
    @Route(path = "/test/activity2")
    public class ActivityTest2 extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test2);
            String value = getIntent().getStringExtra("key1");
            if (!TextUtils.isEmpty(value)) {
                Toast.makeText(this, "exist param :" + value, 
     Toast.LENGTH_LONG).show();
            }
            Button finish=(Button) findViewById(R.id.quit);
            finish.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.d(MainActivity.TAG,">>>>---ActivitySecond--");
                    Intent i=new Intent();
                    i.putExtra("key","result");
                    setResult(6,i);
                    finish();
                }
            });
    
        }
    }
     //    调用的地方
     ARouter.getInstance()
                             .build("/test/activity2")
                             .withString("key1", "value1")
                             .navigation();
    
    • 获取Fragment实例
    @Route(path = "/test/fragment")
    public class BlankFragment extends Fragment {
    
        public BlankFragment() {
            // Required empty public constructor
        }
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_blank, container, false);
        }
    }
    //调用
     Fragment fragment = (Fragment) ARouter.getInstance().build("/test/fragment").navigation();
    
    • 旧版本转场动画
      ARouter.getInstance()
                            .build("/test/activity2")
                            .withTransition(R.anim.slide_in_bottom, R.anim.slide_out_bottom)
                            .navigation(this);
    
    • 新版本转场动画
     if (Build.VERSION.SDK_INT >= 16) {
                        ActivityOptionsCompat compat = ActivityOptionsCompat.
                                makeScaleUpAnimation(v, v.getWidth() / 2, v.getHeight() / 2, 0, 0);
                        ARouter.getInstance()
                                .build("/test/activity2")
                                .withOptionsCompat(compat)
                                .navigation();
                    } else {
                        Toast.makeText(this, "API < 16,不支持新版本动画", Toast.LENGTH_SHORT).show();
                    }
    

    四、进阶用法

    • 通过URL跳转
    @Route(path = "/test/webview")
    public class TestWebview extends Activity {
    
        WebView webview;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test_webview);
    
    
            webview = (WebView) findViewById(R.id.webview);
            webview.loadUrl(getIntent().getStringExtra("url"));
        }
    }
    
     ARouter.getInstance()
                            .build("/test/webview")
                            .withString("url", "file:///android_asset/scheme-test.html")
                            .navigation();
    
    

    在main/assets 放入目标html文件scheme-test.html

    • 拦截器
    @Route(path = "/test/activity4")
    public class ActivityTest4 extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test4);
    
            ((TextView)findViewById(R.id.test)).setText("I am " + ActivityTest4.class.getName());
            String extra = getIntent().getStringExtra("extra");
            if (!TextUtils.isEmpty(extra)) {
                ((TextView)findViewById(R.id.test2)).setText(extra);
            }
        }
    }
    
    //调用地方
     ARouter.getInstance()
                            .build("/test/activity4")
                            .navigation(this, new NavCallback() {
                                @Override
                                public void onArrival(Postcard postcard) {
                                }
                                @Override
                                public void onInterrupt(Postcard postcard) {
                                    Log.d("ARouter", "被拦截了");
                                }
                            });
    
    • 依赖注入
    @Route(path = "/test/activity_jnject", name = "测试用 Activity")
    public class ActivityJnject extends AppCompatActivity {
        @Autowired(desc = "姓名")
        String name = "jack";
    
        @Autowired
        int age = 10;
    
        @Autowired
        int height = 175;
    
        @Autowired(name = "boy", required = true)
        boolean girl;
    
        @Autowired
        char ch = 'A';
    
        @Autowired
        float fl = 12.00f;
    
        @Autowired
        double dou = 12.01d;
    
        @Autowired
        TestSerializable ser;
    
        @Autowired
        TestParcelable pac;
    
        @Autowired
        TestObj obj;
    
        @Autowired
        List<TestObj> objList;
    
        @Autowired
        Map<String, List<TestObj>> map;
    
        private long high;
    
        @Autowired
        String url;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_jnject);
            ARouter.getInstance().inject(this);
    
            String params = String.format(
                    "name=%s,\n age=%s, \n height=%s,\n girl=%s,\n high=%s,\n url=%s,\n ser=%s,\n pac=%s,\n obj=%s \n ch=%s \n fl = %s, \n dou = %s, \n objList=%s, \n map=%s",
                    name,
                    age,
                    height,
                    girl,
                    high,
                    url,
                    ser,
                    pac,
                    obj,
                    ch,
                    fl,
                    dou,
                    objList,
                    map
            );
    
            ((TextView) findViewById(R.id.test)).setText("I am " + ActivityJnject.class.getName());
            ((TextView) findViewById(R.id.test2)).setText(params);
    
        }
    }
    
    //调用部分
     TestSerializable testSerializable = new TestSerializable("Titanic", 555);
                    TestParcelable testParcelable = new TestParcelable("jack", 666);
                    TestObj testObj = new TestObj("Rose", 777);
                    List<TestObj> objList = new ArrayList<>();
                    objList.add(testObj);
                    Map<String, List<TestObj>> map = new HashMap<>();
                    map.put("testMap", objList);
                    ARouter.getInstance().build("/test/activity_jnject")
    //                ARouter.getInstance().build("/test/activity1")
                            .withString("name", "老王")
                            .withInt("age", 18)
                            .withBoolean("boy", true)
                            .withLong("high", 180)
                            .withString("url", "https://a.b.c")
                            .withSerializable("ser", testSerializable)
                            .withParcelable("pac", testParcelable)
                            .withObject("obj", testObj)
                            .withObject("objList", objList)
                            .withObject("map", map)
                            .navigation();
    

    这里有一个坑 报异常

    object2Json(java.lang.Object)' on a null object reference
            at com.alibaba.android.arouter.facade.Postcard.withObject(Postcard.java:230)
    

    解决方案 必须自己实现一个类,用自己项目中的gson 或者fastjson
    这里我选择的是第一种

    @Route(path = "/service/json")
    public class JsonServiceImpl implements SerializationService {
        private Gson mGson;
    
        @Override
        public <T> T parseObject(String input, Type clazz) {
            checkJson();
            return mGson.fromJson(input, clazz);
        }
    
        @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);
        }
    
        public void checkJson() {
            if (mGson == null) {
                mGson = new Gson();
            }
        }
    }
    
    

    如果项目中用的是fastjson 则这个文件定义为

    @Route(path = "/yourservicegroupname/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);
        }
    }
    

    五、服务管理

    需要定义一个接口类 实现 IProvider 与其实现类

    public interface HelloService extends IProvider {
        void sayHello(String name);
    }
    package com.haoran.arouterpro.testservice;
    
    import android.content.Context;
    import android.util.Log;
    import android.widget.Toast;
    
    import com.alibaba.android.arouter.facade.annotation.Route;
    
    /**
     * TODO feature
     *
     * @author Alex <a href="mailto:zhilong.lzl@alibaba-inc.com">Contact me.</a>
     * @version 1.0
     * @since 2017/1/3 10:26
     */
    @Route(path = "/yourservicegroupname/hello")
    public class HelloServiceImpl implements HelloService {
        Context mContext;
    
        @Override
        public void sayHello(String name) {
            Toast.makeText(mContext, "Hello " + name, Toast.LENGTH_SHORT).show();
        }
    
        /**
         * Do your init work in this method, it well be call when processor has been load.
         *
         * @param context ctx
         */
        @Override
        public void init(Context context) {
            mContext = context;
            Log.e("testService", HelloService.class.getName() + " has init.");
        }
    }
    
    
    • 调用服务ByName
     ((HelloService) ARouter.getInstance().build("/yourservicegroupname/hello").navigation()).sayHello("mike");
    
    • 调用服务 ByType
    ARouter.getInstance().navigation(HelloService.class).sayHello("mike");
    
    • 调用单类
    ARouter.getInstance().navigation(SingleService.class).sayHello("Mike");
    

    六、多模块

    • 跳转到模块1
    @Route(path = "/module/1")
    public class ActivityModule1 extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_module1);
        }
    }
    
     ARouter.getInstance().build("/module/1").navigation();
    
    • 跳转到模块2
    @Route(path = "/module/2", group = "m2")
    public class ActivityModule2 extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_module2);
        }
    }
    
     // 这个页面主动指定了Group名
                    ARouter.getInstance().build("/module/2", "m2").navigation();
    

    七、降级策略

    降级策略必须创建一个类 并实现 DegradeService接口,不然会有异常

    ARouter::There is no route match the path
    
    @Route(path = "/xx/xx")
    public class DegradeServiceImpl implements DegradeService{
        Context mContext;
        @Override
        public void onLost(Context context, Postcard postcard) {
    
        }
    
        @Override
        public void init(Context context) {
            this.mContext = context ;
        }
    }
    
    • 跳转失败,单独降级
    ARouter.getInstance().build("/xxx/xxx").navigation(this, new NavCallback() {
                        @Override
                        public void onFound(Postcard postcard) {
                            Log.d("ARouter", "找到了");
                        }
                        @Override
                        public void onLost(Postcard postcard) {
                            Log.d("ARouter", "找不到了");
                        }
    
                        @Override
                        public void onArrival(Postcard postcard) {
                            Log.d("ARouter", "跳转完了");
                        }
    
                        @Override
                        public void onInterrupt(Postcard postcard) {
                            Log.d("ARouter", "被拦截了");
                        }
                    });
    
    • 跳转失败,全局降级
     ARouter.getInstance().build("/xxx/xxx").navigation();
    
    • 服务调用失败
     ARouter.getInstance().navigation(MainActivity.class);
    

    项目代码

    相关文章

      网友评论

          本文标题:ARouter之基础应用篇

          本文链接:https://www.haomeiwen.com/subject/cgqdyktx.html