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 ... }

【ARouter之基础应用篇】可以选择配置路由表自动加载,在项目下面的 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 = https://www.it610.com/article/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);

项目代码

    推荐阅读