溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Android路由框架ARouter的用法

發(fā)布時(shí)間:2021-06-18 10:08:37 來(lái)源:億速云 閱讀:463 作者:chen 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容介紹了“Android路由框架ARouter的用法”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

目錄
  • 一、添加依賴(lài)和初始化框架

    • 1、添加依賴(lài)

      • 1.1、java版本的依賴(lài)

      • 1.2、kotlin版本的依賴(lài)

    • 2、初始化SDK

    • 二、ARouter的簡(jiǎn)單使用

      • 1、界面跳轉(zhuǎn)

        • 1.1、Activity界面跳轉(zhuǎn)

        • 1.2、獲取fragment實(shí)例

        • 1.3、注意事項(xiàng)

      • 2、攜帶基本參數(shù)的界面跳轉(zhuǎn)

        • 3、攜帶對(duì)象的界面跳轉(zhuǎn)

          • 3.1、攜帶序列化對(duì)象的界面跳轉(zhuǎn)

          • 3.2、攜帶無(wú)序列化對(duì)象的界面跳轉(zhuǎn)

          • 3.3、攜帶集合和數(shù)組的界面跳轉(zhuǎn)

        • 4、界面跳轉(zhuǎn)回調(diào)

          • 5、未用到的知識(shí)點(diǎn)

          一、添加依賴(lài)和初始化框架

          1、添加依賴(lài)

          在需要使用ARouter的module中添加如下代碼:

          1.1、java版本的依賴(lài)
          android {
              defaultConfig {
                  ...
                  javaCompileOptions {
                      annotationProcessorOptions {
                          arguments = [moduleName :project.getName() ]
                      } }
              }
          }
          
          dependencies {
              api 'com.alibaba:arouter-api:1.5.1'
              annotationProcessor 'com.alibaba:arouter-compiler:1.5.1'
          }
          1.2、kotlin版本的依賴(lài)
          plugins {
              ...
              id 'kotlin-kapt'
          }
          
          dependencies {
              ...
              implementation 'com.alibaba:arouter-api:1.5.1'
              kapt 'com.alibaba:arouter-compiler:1.5.1'
          }

          題外話(huà): implementation 和 api 關(guān)鍵字,在Android studio3.0版本中,曾經(jīng)的 compile 關(guān)鍵字被棄用,而 api 則是 compile 的替代品, api 與 compile 沒(méi)有區(qū)別。但最新官方推薦使用 implementation 來(lái)代替 compile 關(guān)鍵字,據(jù)說(shuō) implementation 會(huì)使Android studio的編譯速度更快呦。

          而 implementation 和 api 關(guān)鍵字的區(qū)別則在于用 implementation 來(lái)聲明的依賴(lài)包只限于當(dāng)前module內(nèi)部使用,對(duì)于依賴(lài)其module的模塊是無(wú)法使用到該依賴(lài)包的。而用 api 來(lái)聲明依賴(lài)包時(shí),依賴(lài)于該module的模塊可以正常使用其模塊內(nèi)的依賴(lài)包。

          在這里,由于我是將其放入一個(gè)公共的module,來(lái)讓app module進(jìn)行依賴(lài),因此使用 api 關(guān)鍵字。若沒(méi)有對(duì)項(xiàng)目進(jìn)行組件化,則可以使用 implementation 關(guān)鍵字進(jìn)行依賴(lài)。

          2、初始化SDK

          //初始化ARouter框架
          private boolean isDebugARouter = true;//ARouter調(diào)試開(kāi)關(guān)
          if (isDebugARouter) {
              //下面兩行必須寫(xiě)在init之前,否則這些配置在init中將無(wú)效
              ARouter.openLog();
              //開(kāi)啟調(diào)試模式(如果在InstantRun模式下運(yùn)行,必須開(kāi)啟調(diào)試模式!
              // 線(xiàn)上版本需要關(guān)閉,否則有安全風(fēng)險(xiǎn))
              ARouter.openDebug();
          }
          //官方推薦放到Application中初始化
          ARouter.init((Application) mContext);

          二、ARouter的簡(jiǎn)單使用

          1、界面跳轉(zhuǎn)

          1.1、Activity界面跳轉(zhuǎn)

          目標(biāo)Activity添加注釋?zhuān)ㄌD(zhuǎn)語(yǔ)句,路由路徑建議寫(xiě)成常量,創(chuàng)建路由表進(jìn)行統(tǒng)一管理。)

          @Route(path = "/app/login")
          public class LoginActivity extends AppCompatActivity {

          發(fā)送Activity實(shí)現(xiàn)跳轉(zhuǎn)到

          ARouter.getInstance().build("/app/login").navigation();
          1.2、獲取fragment實(shí)例
          //目標(biāo)界面
          @Route(path = "/app/fragment")
          public class EmptyFragment extends BaseFragment {
          }
          
          //啟動(dòng)界面
          Fragment fragment= (Fragment) ARouter.getInstance().build("/app/fragment").navigation();
          FragmentManager manager = getSupportFragmentManager();
          FragmentTransaction transaction = manager.beginTransaction();
          transaction.add(R.id.fl_fragment_content, fragment);
          transaction.commit();
          1.3、注意事項(xiàng)

          如果像我一樣對(duì)項(xiàng)目進(jìn)行了組件化的同學(xué)就會(huì)發(fā)現(xiàn),此時(shí)跳轉(zhuǎn)并沒(méi)有成功,而是彈出錯(cuò)誤提示。

          Android路由框架ARouter的用法

          這是因?yàn)榻M件化后,即時(shí)我們使用了 api 作為依賴(lài)的關(guān)鍵字,但仍需在使用ARouter的其他module中配置代碼。這里一般習(xí)慣的做法是把a(bǔ)router-api的依賴(lài)放在基礎(chǔ)服務(wù)的module里面,因?yàn)榧热挥玫搅私M件化,那么肯定是所有的module都需要依賴(lài)arouter-api庫(kù)的,而arouter-compiler的依賴(lài)需要放到每一個(gè)module里面。

          java

          android {
              defaultConfig {
                  ...
                  javaCompileOptions {
                      annotationProcessorOptions {
                          arguments = [moduleName :project.getName() ]
                      } }
              }
          }
          
          dependencies {
              annotationProcessor 'com.alibaba:arouter-compiler:1.5.1'
          }

          kotlin

          plugins {
              ...
              id 'kotlin-kapt'
          }
          
          dependencies {
              ...
              kapt 'com.alibaba:arouter-compiler:1.5.1'
          }

          否則無(wú)法匹配路由,并且在使用withObject方法攜帶對(duì)象時(shí)也會(huì)報(bào)錯(cuò),這個(gè)后面再說(shuō),再試一次發(fā)現(xiàn)界面成功跳轉(zhuǎn)。關(guān)于注釋 @Route 的 path 參數(shù),也需要注意規(guī)范,必須要以“/”開(kāi)頭,并且路徑至少為兩級(jí),不然會(huì)編譯不通過(guò)或者報(bào)錯(cuò)。

          Android路由框架ARouter的用法

          意思是路徑必須以“/”開(kāi)頭,并且包含的值超過(guò)2個(gè)“/”。

          2、攜帶基本參數(shù)的界面跳轉(zhuǎn)

          使用方法如下,傳入鍵值對(duì)

          Bundle bundle = new Bundle();
          bundle.putString("bundleStringKey", "bundleStringValue");
          
          ARouter.getInstance().build("/app/login")
                       .withString("stringKey", "stringValue")
                       .withInt("intKey", 100)
                       .withBoolean("booleanKey", true)
                       .withBundle("bundle", bundle)
                       .navigation();

          目標(biāo)界面使用 @Autowired 注解進(jìn)行注入

          @Route(path = "/app/login")
          public class LoginActivity extends AppCompatActivity {
              @Autowired
              String stringKey;
              @Autowired
              int intKey;
              @Autowired
              boolean booleanKey;
              @Autowired
              Bundle bundle;
          
              @Override
              protected void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.activity_login);
                  //注入ARouter
                  ARouter.getInstance().inject(this);
                  
                  Log.e(TAG, stringKey + "..." + intKey + "..." + booleanKey);
                  Log.e(TAG, bundle.getString("bundleStringKey"));
              }
          }

          注意:注入的屬性名要和之前攜帶的key值完全相同,并且要在需要注入的界面通過(guò)ARouter.getInstance().inject(this)注入ARouter,否則無(wú)法注入成功。建議將ARouter.getInstance().inject(this)操作放在BaseActivity的onCreate方法中進(jìn)行。既然有注入,就一定有資源的釋放,因此釋放資源在Application中進(jìn)行。

          @Override
              public void onTerminate() {
                  super.onTerminate();
                  ARouter.getInstance().destroy();
              }

          如果釋放資源放在BaseActivity的onDestroy方法中調(diào)用了 ARouter.getInstance().destroy( ) ; 在進(jìn)入目標(biāo)Activity之后,然后按back鍵返回原界面的時(shí)候,APP會(huì)報(bào)錯(cuò)崩潰,下面是崩潰日志:

          Android路由框架ARouter的用法

          3、攜帶對(duì)象的界面跳轉(zhuǎn)

          3.1、攜帶序列化對(duì)象的界面跳轉(zhuǎn)

          攜帶 Serializable 和 Parcelable 序列化的對(duì)象

          TestSerializableBean serializableBean = new TestSerializableBean();
          serializableBean.setName("serializable");
          
          TestParcelableBean parcelableBean = new TestParcelableBean();
          parcelableBean.setName("parcelable");
          
          ARouter.getInstance().build("/app/login")
                  .withParcelable("parcelableBean", parcelableBean)
                  .withSerializable("serializableBean", serializableBean)
                  .navigation();

          目標(biāo)界面

          @Autowired
          TestParcelableBean parcelableBean;
          @Autowired
          TestSerializableBean serializableBean;
          
          @Override
          protected void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.activity_login);
                  Log.e(TAG, parcelableBean + "");
                  Log.e(TAG, serializableBean + "");
          }

          Android路由框架ARouter的用法

          我們發(fā)現(xiàn)Serializable序列化的對(duì)象為null,我們查看withSerializable方法發(fā)現(xiàn)其被裝進(jìn)了Bundle

          public Postcard withSerializable(@Nullable String key, @Nullable Serializable value) {
                  mBundle.putSerializable(key, value);
                  return this;
              }

          因此換一種方法來(lái)取值,發(fā)現(xiàn)打印成功

          TestSerializableBean serializableBean = (TestSerializableBean) getIntent().getExtras().getSerializable("serializableBean");
          Log.e(TAG, serializableBean + "");

          Android路由框架ARouter的用法

          3.2、攜帶無(wú)序列化對(duì)象的界面跳轉(zhuǎn)

          沒(méi)有進(jìn)行過(guò)序列化的對(duì)象也可以通過(guò)withObject對(duì)象進(jìn)行傳遞,接收方式相同

          NormalTest normalTest = new NormalTest();
          normalTest.setName("normal");
          ARouter.getInstance().build("/app/login")
                  .withObject("normalTest", normalTest)
                  .navigation();

          但是我們直接使用該方法運(yùn)行會(huì)報(bào)錯(cuò),分析源碼發(fā)現(xiàn)該方法中用到了SerializationService

          public Postcard withObject(@Nullable String key, @Nullable Object value) {
                  serializationService = ARouter.getInstance().navigation(SerializationService.class);
                  mBundle.putString(key, serializationService.object2Json(value));
                  return this;
              }

          因此我們需要實(shí)現(xiàn)該服務(wù)

          @Route(path = "/service/json")
          public class JsonServiceImpl 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();
              }
          }

          我們可以在里面定義所需的json解析器,再次運(yùn)行成功打印該對(duì)象。那序列化的對(duì)象可以使用該方法傳遞嗎?

          TestParcelableBean objParcelableBean = new TestParcelableBean();
          objParcelableBean.setName("objParcelable");
          
          TestSerializableBean objSerializableBean = new TestSerializableBean();
          objSerializableBean.setName("objSerializable");
          
          NormalTest normalTest = new NormalTest();
          normalTest.setName("normal");
          
          ARouter.getInstance().build("/app/login")
                  .withObject("objParcelableBean", objParcelableBean)
                  .withObject("objSerializableBean", objSerializableBean)
                  .withObject("normalTest", normalTest)
                  .navigation();
          
          //目標(biāo)界面
          @Autowired(name = "objParcelableBean")
          TestParcelableBean objParcelableBean;
          @Autowired(name = "objSerializableBean")
          TestSerializableBean objSerializableBean;
          @Autowired(name = "normalTest")
          NormalTest normalTest;
          
          Log.e(TAG, objParcelableBean + "");
          Log.e(TAG, objSerializableBean + "");
          Log.e(TAG, normalTest + "");

          Android路由框架ARouter的用法

          我們發(fā)現(xiàn)用 Parcelable 序列化的對(duì)象為空,分析build的編譯文件

          @Override
            public void inject(Object target) {
              serializationService = ARouter.getInstance().navigation(SerializationService.class);
              LoginActivity substitute = (LoginActivity)target;
              substitute.objParcelableBean = substitute.getIntent().getParcelableExtra("objParcelableBean");
              if (null != serializationService) {
                substitute.objSerializableBean = serializationService.parseObject(substitute.getIntent().getStringExtra("objSerializableBean"), new com.alibaba.android.arouter.facade.model.TypeWrapper<TestSerializableBean>(){}.getType());
              } else {
                Log.e("ARouter::", "You want automatic inject the field 'objSerializableBean' in class 'LoginActivity' , then you should implement 'SerializationService' to support object auto inject!");
              }
              if (null != serializationService) {
                substitute.normalTest = serializationService.parseObject(substitute.getIntent().getStringExtra("normalTest"), new com.alibaba.android.arouter.facade.model.TypeWrapper<NormalTest>(){}.getType());
              } else {
                Log.e("ARouter::", "You want automatic inject the field 'normalTest' in class 'LoginActivity' , then you should implement 'SerializationService' to support object auto inject!");
              }
            }

          我們可以看到唯獨(dú)通過(guò) Parcelable 方式序列化的對(duì)象沒(méi)有使用SerializationService進(jìn)行解析,而是直接從Bundle去取,但我們并不是通過(guò)withParcelable方法去設(shè)置的值,因此取得的數(shù)據(jù)為null。

          小結(jié):因此,為了方便我們的操作,沒(méi)有序列化和使用 Serializable 序列化的對(duì)象使用 withObject 方法傳遞,使用 Parcelable 方式序列化的對(duì)象則采用 withParcelable 方法進(jìn)行傳遞。

          3.3、攜帶集合和數(shù)組的界面跳轉(zhuǎn)

          集合和數(shù)組的界面跳轉(zhuǎn)統(tǒng)一使用 withObject 方法傳遞,并且能夠支持成員的各種序列化方式。

           List<NormalTest> listNormal = new ArrayList<>();
           listNormal.add(new NormalTest());
           listNormal.add(new NormalTest());
          
           List<TestSerializableBean> listSerializable = new ArrayList<>();
           listSerializable.add(new TestSerializableBean());
           listSerializable.add(new TestSerializableBean());
          
           List<TestParcelableBean> listParcelable = new ArrayList<>();
           listParcelable.add(new TestParcelableBean());
           listParcelable.add(new TestParcelableBean());
          
           Map<String, NormalTest> map = new HashMap<>();
           map.put("1", new NormalTest());
           map.put("2", new NormalTest());
          
           ARouter.getInstance().build("/app/login")
                   .withObject("listNormal", listNormal)
                   .withObject("listSerializable",listSerializable)
                   .withObject("listParcelable",listParcelable)
                   .withObject("map", map)
                   .navigation();
          
           //目標(biāo)界面
           @Autowired
           List<NormalTest> listNormal;
           @Autowired
           List<TestSerializableBean> listSerializable;
           @Autowired
           List<TestParcelableBean> listParcelable;
           @Autowired
           Map<String, NormalTest> map;
          
           Log.e(TAG, listNormal + "");
           Log.e(TAG, listSerializable + "");
           Log.e(TAG, listParcelable + "");
           Log.e(TAG, map + "");

          Android路由框架ARouter的用法

          4、界面跳轉(zhuǎn)回調(diào)

          //啟動(dòng)界面
          ARouter.getInstance().build("/app/login")
                  .navigation(MainActivity.this, REQUEST_CODE);
          
          @Override
              protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
                  super.onActivityResult(requestCode, resultCode, data);
                  if (requestCode == REQUEST_CODE&& resultCode == RESULT_CODE) {
                      LogUtils.e(data.getStringExtra("data"));
                  }
              }
          
          
          //目標(biāo)界面
          Intent intent = new Intent();
          intent.putExtra("data", "resultData");
          setResult(RESULT_CODE, intent);
          finish();

          5、未用到的知識(shí)點(diǎn)

          由于項(xiàng)目中沒(méi)有用到ARouter攔截器、ARouter自定義分組,這兩塊知識(shí)點(diǎn),所以就沒(méi)研究。

          “Android路由框架ARouter的用法”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

          向AI問(wèn)一下細(xì)節(jié)

          免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

          AI