ARouter之基础应用篇

一 、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 objList;

    @Autowired
    Map> 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 objList = new ArrayList<>();
                objList.add(testObj);
                Map> 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 parseObject(String input, Type clazz) {
        checkJson();
        return mGson.fromJson(input, clazz);
    }

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

    @Override
    public  T json2Object(String text, Class 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 json2Object(String text, Class clazz) {
        return JSON.parseObject(text, clazz);
    }

    @Override
    public String object2Json(Object instance) {
        return JSON.toJSONString(instance);
    }

    @Override
    public  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 Contact me.
 * @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之基础应用篇)