使用阿里ARouter路由實現組件化(模塊化)開發流程

Android平臺中對頁面、服務提供路由功能的中間件,個人目標是 —— 簡單且夠用。html

這是阿里對Arouter的定位,那麼咱們一塊兒來梳理一下Arouter使用流程,和使用中我所遇到的一些問題!java

先來看看有哪些功能android

 

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

模塊化的要解決的問題

  • 模塊間頁面跳轉(路由);web

  • 模塊間事件通訊;json

  • 模塊間服務調用;api

  • 模塊的獨立運行;安全

  • 模塊間頁面跳轉路由攔截(登陸)服務器

  • 其餘注意事項;app

對項目模塊進行劃分

這裏寫圖片描述

app模塊:主模塊,主要進行搭載各個模塊的功能。

lib_base:對ARouter進行初始化,和放置一些各個模塊公用的封裝類。

lib_icon:放置圖片、assets、xml等公用資源文件

module_home,module_caht,module_recom,module_me:分別對應「首頁」、「微聊」、「推薦」、「個人」模塊!

ARouter各個模塊的gradle配置

  • 由於路由跳轉是子模塊都須要用到的,因此咱們在lib_base 模塊中引入
    compile 'com.alibaba:arouter-api:1.2.4'
    
    annotationProcessor "com.alibaba:arouter-compiler:1.1.4"
    
    包括整個項目中都會用到的其餘依賴,例如:
    
     compile 'com.android.support:design:26.0.0-alpha1'
    
    compile 'org.simple:androideventbus:1.0.5.1'
    
    compile 'com.alibaba:fastjson:1.2.9'

    由於我把攔截器等公用類在base註冊,在編譯期間生成路徑映射。同時也須要在build中加入框架

    defaultConfig {
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [moduleName: project.getName()]
                }
            }
        }
  • 而後在各子模塊的build文件中導入(也就是module_home,module_caht,module_recom,module_me):
    /**
     * 及時在base已經引入了com.alibaba:arouter-compiler:1.1.4
     * 這裏也須要引入,否則報錯
     */
      annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'
    
      compile project(':lib_base')
    
      compile project(':lib_icon')

    在編譯期間生成路徑映射。同時也須要在各子模塊的build中加入:

    defaultConfig {
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [moduleName: project.getName()]
                }
            }
        }
  • 在app模塊對各個子模塊進行依賴:
      compile project(':module_home')
      compile project(':module_chat')
      compile project(':module_recom')
      compile project(':module_me')

    模塊可插拔單獨編譯運行

    模塊化的好處之一就是單一模塊能夠獨立的開發編譯運行安裝到用戶的手機上,這樣就方便了對某一模塊的單獨開發調試,單一模塊生成的apk體積也小,編譯時間也快,開發效率會高不少。

  • 項目根目錄gradle.properties配置:
    # 是否須要單獨編譯 true表示不須要,false表示須要
    isNeedHomeModule=true
    #isNeedHomeModule=false
    isNeedChatModule=true
    #isNeedChatModule=false
    isNeedRecomModule=true
    #isNeedRecomModule=false
    isNeedMeModule=true
    #isNeedMeModule=false
  • 在各個子模塊中配置(例如module_me):
    if (!isNeedMeModule.toBoolean()) {
        apply plugin: 'com.android.application'
    } else {
        apply plugin: 'com.android.library'
    }
    defaultConfig {
            if (!isNeedMeModule.toBoolean()) {
                applicationId "tsou.cn.module_me"
            }
     }
  • 在app主模塊中:
    if (isNeedHomeModule.toBoolean()) {
            compile project(':module_home')
        }
        if (isNeedChatModule.toBoolean()) {
            compile project(':module_chat')
        }
        if (isNeedRecomModule.toBoolean()) {
            compile project(':module_recom')
        }
        if (isNeedMeModule.toBoolean()) {
            compile project(':module_me')
        }

    若是須要單獨運行某個模塊時,修改gradle.properties配置,

    例如單獨運行module_home模塊時,開啓isNeedHomeModule=false,

  • 方式一:直接在AndroidManifest.xml的MainActivity添加
     <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>

    反之則關閉!固然比較lou

    • 方式二:經過build自動配置

    一、主目錄下AndroidManifest.xml不變

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="tsou.cn.module_home">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
            </activity>
        </application>
    
    </manifest>

    二、在src目錄下建立debug文件夾包含一個AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="tsou.cn.module_home">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>

    三、在子模塊的build中配置

    android {
        ...
    
        sourceSets {
            main {
                if (!isNeedHomeModule.toBoolean()) {
                    manifest.srcFile 'src/debug/AndroidManifest.xml'
                } else {
                    manifest.srcFile 'src/main/AndroidManifest.xml'
                    java {
                        //所有Module一塊兒編譯的時候剔除debug目錄
                        exclude '**/debug/**'
                    }
                }
            }
        }
    }

    四、運行module_home便可

    這裏寫圖片描述

    ARouter初始化

    在lib_base中建立MyApplication

    public class MyApplication extends Application {
        /**
         * 上下文
         */
        private static MyApplication instance;
    
        @Override
        public void onCreate() {
            super.onCreate();
            instance = this;
            initRouter(this);
        }
    
        public static Context getInstance() {
            return instance;
        }
    
        private void initRouter(MyApplication mApplication) {
            // 這兩行必須寫在init以前,不然這些配置在init過程當中將無效
            if (UIUtils.isApkInDebug(instance)) {
                //打印日誌
                ARouter.openLog();
                //開啓調試模式(若是在InstantRun模式下運行,必須開啓調試模式!
                //線上版本須要關閉,不然有安全風險)
                ARouter.openDebug();
            }
            // 儘量早,推薦在Application中初始化
            ARouter.init(mApplication);
    
    
        }
    }
    /**
         * 判斷當前應用是不是debug狀態
         */
    
        public static boolean isApkInDebug(Context context) {
            try {
                ApplicationInfo info = context.getApplicationInfo();
                return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
            } catch (Exception e) {
                return false;
            }
        }

    這裏要注意:若是你在debug模式下進行調試代碼,ARouter.openDebug();必定要調用,不然ARouter會出現無效狀況。

    首頁的搭建

    這裏寫圖片描述

    使用ARouter來獲取到各個模塊的Fragment

    package tsou.cn.lib_base.utils;
    
    /**
     * Created by Administrator on 2017/12/4 0004.
     */
    
    public class RouteUtils {
        //得到home模塊fragment
        public static final String Home_Fragment_Main = "/home/main";
        //得到chat模塊fragment
        public static final String Chat_Fragment_Main = "/chat/main";
        //得到Recom模塊fragment
        public static final String Recom_Fragment_Main = "/recom/main";
        //得到Me模塊fragment
        public static final String Me_Fragment_Main = "/me/main";
        //跳轉到登陸頁面
        public static final String Me_Login = "/me/main/login";
        //跳轉到eventBus數據接收頁面
        public static final String Me_EventBus = "/me/main/EventBus";
        //跳轉到TextOne數據接收頁面
        public static final String Me_TextOne = "/me/main/TextOne";
        //跳轉到Test公用頁面
        public static final String Me_Test = "/me/main/Test";
        //路由攔截
        public static final String Me_Test2 = "/me/main/Test2";
        //跳轉到webview頁面
        public static final String Me_WebView = "/me/main/WebView";
    
        //跳轉到依賴注入頁面
        public static final String Me_Inject = "/me/main/Inject";
        /**
         * 依賴注入使用,注意:必須實現SerializationService進行註冊,
         */
        public static final String Home_Json_Service = "/huangxiaoguo/json";
    
        //跳轉ForResult
        public static final String Chat_ForResult = "/chat/main/ForResult";
        //模塊間服務調用,調用chat模塊的接口
        public static final String Service_Chat = "/chat/service";
        //路由攔截
        public static final String Chat_Interceptor = "/chat/main/Interceptor";
    
        /**
         * 專門的分組,這裏就叫作needLogin組,凡是在這個組下的,都會進行登陸操做
         */
        public static final String NeedLogin_Test3 = "/needLogin/main/Test3";
    
    }
    package tsou.cn.myaroutertest.utils;
    
    import android.support.v4.app.Fragment;
    
    import com.alibaba.android.arouter.launcher.ARouter;
    
    import tsou.cn.lib_base.utils.RouteUtils;
    
    /**
     * Created by Administrator on 2017/12/4 0004.
     */
    
    public class FragmentUtils {
    
        public static Fragment getHomeFragment() {
            Fragment fragment = (Fragment) ARouter.getInstance().build(RouteUtils.Home_Fragment_Main).navigation();
            return fragment;
        }
    
        public static Fragment getChatFragment() {
            Fragment fragment = (Fragment) ARouter.getInstance().build(RouteUtils.Chat_Fragment_Main).navigation();
            return fragment;
        }
    
        public static Fragment getRecomFragment() {
            Fragment fragment = (Fragment) ARouter.getInstance().build(RouteUtils.Recom_Fragment_Main).navigation();
            return fragment;
        }
    
        public static Fragment getMeFragment() {
            Fragment fragment = (Fragment) ARouter.getInstance().build(RouteUtils.Me_Fragment_Main).navigation();
            return fragment;
        }
    }
    package tsou.cn.myaroutertest;
    
    import android.os.Bundle;
    import android.support.design.widget.TabLayout;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentStatePagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.support.v7.app.AppCompatActivity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    import java.util.ArrayList;
    
    import tsou.cn.myaroutertest.utils.FragmentUtils;
    
    public class MainActivity extends AppCompatActivity {
    
        private ViewPager mMViewPager;
        private TabLayout mToolbarTab;
        /**
         * 圖標
         */
        private int[] tabIcons = {
                R.drawable.tab_home,
                R.drawable.tab_weichat,
                R.drawable.tab_recommend,
                R.drawable.tab_user
        };
        private String[] tab_array;
        private DemandAdapter mDemandAdapter;
        private ArrayList<Fragment> fragments = new ArrayList<>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initData();
            initView();
    //         給viewpager設置適配器
            setViewPagerAdapter();
            setTabBindViewPager();
            setItem();
        }
    
        private void initData() {
            tab_array = getResources().getStringArray(R.array.tab_main);
            fragments.clear();
            fragments.add(FragmentUtils.getHomeFragment());
            fragments.add(FragmentUtils.getChatFragment());
            fragments.add(FragmentUtils.getRecomFragment());
            fragments.add(FragmentUtils.getMeFragment());
        }
    
        private void initView() {
            mMViewPager = (ViewPager) findViewById(R.id.mViewPager);
            mToolbarTab = (TabLayout) findViewById(R.id.toolbar_tab);
    
        }
    
        private void setViewPagerAdapter() {
            mDemandAdapter = new DemandAdapter(getSupportFragmentManager());
            mMViewPager.setAdapter(mDemandAdapter);
        }
    
        private void setTabBindViewPager() {
            mToolbarTab.setupWithViewPager(mMViewPager);
        }
    
        private void setItem() {
            /**
             * 必定要在設置適配器以後設置Icon
             */
            for (int i = 0; i < mToolbarTab.getTabCount(); i++) {
                mToolbarTab.getTabAt(i).setCustomView(getTabView(i));
            }
        }
    
        public View getTabView(int position) {
            View view = LayoutInflater.from(this).inflate(R.layout.item_tab, null);
            ImageView tab_image = view.findViewById(R.id.tab_image);
            TextView tab_text = view.findViewById(R.id.tab_text);
            tab_image.setImageResource(tabIcons[position]);
            tab_text.setText(tab_array[position]);
            return view;
        }
    
        /**
         * 適配器
         */
        public class DemandAdapter extends FragmentStatePagerAdapter {
    
    
            public DemandAdapter(FragmentManager fm) {
                super(fm);
            }
    
            @Override
            public Fragment getItem(int position) {
    
                return fragments.get(position);
            }
    
            @Override
            public int getCount() {
                return fragments.size();
            }
    
        }
    }

    代碼中有註釋,切很簡單,不會出現什麼毛病!若是有小毛病,就clean一下解決

    使用ARouter路由實現各類功能

  • 跨模塊跳轉Activity
    • 實現這個Activity跳轉的路徑。

      //跳轉到個人模塊登陸頁面
          public static final String Me_Login = "/me/main/login";

      ARouter跳轉Activity,在這個Activity上加入註解。

      @Route(path = RouteUtils.Me_Login)
      public class LoginActivity extends AppCompatActivity implements View.OnClickListener {

      跳轉邏輯是

      //登陸(跨模塊跳轉Activity)
      
      ARouter.getInstance().build(RouteUtils.Me_Login).navigation();

      跨模塊實現ForResult返回數據(activity中使用)

      實現這個Activity跳轉的路徑。

      //跳轉ForResult
          public static final String Chat_ForResult = "/chat/main/ForResult";

      ARouter跳轉Activity,在這個Activity上加入註解。

      @Route(path = RouteUtils.Chat_ForResult)
      public class ForResultActivity extends AppCompatActivity implements View.OnClickListener {

      跳轉邏輯是

      //跳轉ForResult,在fragment中使用不起做用
      
         ARouter.getInstance().build(RouteUtils.Chat_ForResult).navigation(this, 666);

      接收數據數據

         @Override
          protected void onActivityResult(int requestCode, int resultCode, Intent data) {
              super.onActivityResult(requestCode, resultCode, data);
              switch (requestCode) {
                  case 666:
                      String name = data.getStringExtra("name");
                      UIUtils.showToast(name + ",resultCode===>" + resultCode);
                      break;
                  default:
                      break;
              }
          }

      返回數據

       Intent intent = new Intent();
                  intent.putExtra("name", "ForResult返回的數據");
                  setResult(999, intent);
                  finish();
    • 跳轉並攜帶參數和Eventbus誇模塊通訊
       EventBus.getDefault().register(this);
      
       EventBus.getDefault().unregister(this);
      
       @Subscriber(tag = EvenBusTag.GOTO_EVENTBUS)
          public void onEvent(String s) {
              UIUtils.showToast(s);
          }
       //跳轉到eventBus數據接收頁面
          public static final String Me_EventBus = "/me/main/EventBus";
      @Route(path = RouteUtils.Me_EventBus)
      public class EventBusActivity extends AppCompatActivity implements View.OnClickListener {
      // 跳轉並攜帶參數,基本涵蓋因此類型傳遞,具體能夠查看Postcard類
                  //傳遞過去的值使用getIntent()接收
                  //在fragment中沒法使用ForResult進行誇模塊傳遞數據
                  //在activity中能夠(詳細請看LoginActivity)這裏的EventBusBean 已經實現了Parcelable接口
      
                  EventBusBean eventBusBean = new EventBusBean();
                  eventBusBean.setProject("android");
                  eventBusBean.setNum(3);
      
                  ARouter.getInstance().build(RouteUtils.Me_EventBus)
                          .withString("name", "haungxiaoguo")
                          .withLong("age", 25)
                          .withParcelable("eventbus", eventBusBean)
                          .navigation();
      @Route(path = RouteUtils.Me_EventBus)
      public class EventBusActivity extends AppCompatActivity implements View.OnClickListener {
      
          /**
           * eventBus數據接收頁面
           */
          private TextView mTextView;
          /**
           * eventBus返回數據
           */
          private Button mBtnBackData;
      
          private String name;
      
          private long age;
          private EventBusBean eventbus;
      
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_event_bus);
              ARouter.getInstance().inject(this);
              initData();
              initView();
          }
      
          private void initData() {
              name = getIntent().getStringExtra("name");
              age = getIntent().getLongExtra("age", 0);
              eventbus = getIntent().getParcelableExtra("eventbus");
          }
      
          private void initView() {
              mTextView = (TextView) findViewById(R.id.textView);
              mBtnBackData = (Button) findViewById(R.id.btn_back_data);
              mBtnBackData.setOnClickListener(this);
              mTextView.setText("name=" + name + ",\tage=" + age + ",\tproject=" + eventbus.getProject() +
                      ",\tnum=" + eventbus.getNum());
          }
      
          @Override
          public void onClick(View v) {
              int i = v.getId();
              if (i == R.id.btn_back_data) {
                  EventBus.getDefault().post(name, EvenBusTag.GOTO_EVENTBUS);
                  finish();
              } else {
              }
          }
      }

      路徑配置都是同樣,如下只介紹跳轉方式

      • 使用Uri應用內跳轉
          EventBusBean eventBusBean = new EventBusBean();
                    eventBusBean.setProject("android");
                    eventBusBean.setNum(3);
        
                    Uri testUriMix = Uri.parse("arouter://tsou.cn.huangxiaoguo/me/main/EventBus");
                    ARouter.getInstance().build(testUriMix)
                            .withString("name", "haungxiaoguo")
                            .withLong("age", 25)
                            .withParcelable("eventbus", eventBusBean)
                            .navigation();
      • 舊版本轉場動畫
        //舊版本轉場動畫
                    ARouter.getInstance()
                            .build(RouteUtils.Me_Test)
                            .withTransition(R.anim.slide_in_bottom, R.anim.slide_out_bottom)
                            .navigation(getContext());//context上下文不傳無效果
      • 新版本轉場動畫
        //新版本轉場動畫
                    if (Build.VERSION.SDK_INT >= 16) {
                        ActivityOptionsCompat compat = ActivityOptionsCompat.
                                makeScaleUpAnimation(v, v.getWidth() / 2, v.getHeight() / 2, 0, 0);
                        ARouter.getInstance()
                                .build(RouteUtils.Me_Test)
                                .withOptionsCompat(compat)
                                .navigation();
                    } else {
                        UIUtils.showToast("API < 16,不支持新版本動畫");
                    }
      • 經過URL跳轉(webview)
        //經過URL跳轉(webview)
                    ARouter.getInstance()
                            .build(RouteUtils.Me_WebView)
                            .withString("url", "file:///android_asset/schame-test.html")
                            .navigation();

        攔截器操做

        首先實現IInterceptor:

        這裏寫圖片描述

        package tsou.cn.lib_base.interceptor;
        
        import android.content.Context;
        import android.util.Log;
        
        import com.alibaba.android.arouter.facade.Postcard;
        import com.alibaba.android.arouter.facade.annotation.Interceptor;
        import com.alibaba.android.arouter.facade.callback.InterceptorCallback;
        import com.alibaba.android.arouter.facade.template.IInterceptor;
        import com.alibaba.android.arouter.launcher.ARouter;
        
        import tsou.cn.lib_base.utils.RouteUtils;
        
        /**
         * Created by Administrator on 2017/12/6 0006.
         * 添加攔截器的時候,建議clean再打包運行,否則會出現,無效的狀況
         * <p>
         * 切記一個項目裏面priority的值保證惟一,否則會出毛病
         */
        @Interceptor(priority = 1, name = "從新分組進行攔截")
        public class MyDataInterceptor implements IInterceptor {
        
            @Override
            public void process(Postcard postcard, InterceptorCallback callback) {
                if (postcard.getGroup().equals("needLogin")) {
                    Log.e("huangxiaoguo", "須要去登錄");
                    //直接執行
                    // callback.onContinue(postcard);
        
                    //直接攔截,走onLost方法
                    //  callback.onInterrupt(null);
        
                    //添加數據
        //        postcard.withString("extra", "我是在攔截器中附加的參數");
        //        callback.onContinue(postcard);
                    callback.onInterrupt(null);
                    ARouter.getInstance().build(RouteUtils.Me_Login)
                            .withString("path", postcard.getPath()).navigation();
                } else {
                    postcard.withString("extra", "我是在攔截器中附加的參數");
                    callback.onContinue(postcard);
                }
            }
        
            @Override
            public void init(Context context) {
        
            }
        }

        接收未攔截時攔截器添加的數據(postcard.withString(「extra」, 「我是在攔截器中附加的參數」);)

         private void initData() {
                extra = getIntent().getStringExtra("extra");
        
            }

        對目標Activity指定新的分組(組名爲「needLogin」,注意同時也是「me」組下的成員)

        @Route(path = RouteUtils.Me_Test2, group = "needLogin")
        public class Test2Activity extends AppCompatActivity {
        • 攔截器操做(利用從新分組攔截)
          /**
                       * 若是利用從新分組,就須要在build中進行指定的分組否則沒有效果
                       */
                      ARouter.getInstance()
                              .build(RouteUtils.Me_Test2, "needLogin")
                              .navigation(getContext(), new NavCallback() {
                                  @Override
                                  public void onFound(Postcard postcard) {
                                      super.onFound(postcard);
                                      //路由目標被發現時調用
                                      Log.e("huangxiaoguo", "發現了");
                                  }
          
                                  @Override
                                  public void onLost(Postcard postcard) {
                                      super.onLost(postcard);
                                      //路由被丟失時調用
                                      Log.e("huangxiaoguo", "丟失了");
                                  }
          
                                  @Override
                                  public void onArrival(Postcard postcard) {
                                      //路由到達以後調用
                                      Log.e("huangxiaoguo", "到達了");
                                  }
          
                                  @Override
                                  public void onInterrupt(Postcard postcard) {
                                      super.onInterrupt(postcard);
                                      //路由被攔截時調用
                                      Log.e("huangxiaoguo", "攔截了");
                                  }
                              });
        • 攔截器操做(利用原有分組)
          /**
               * 專門的分組,這裏就叫作needLogin組,凡是在這個組下的,都會進行登陸操做
               */
              public static final String NeedLogin_Test3 = "/needLogin/main/Test3";
          @Route(path = RouteUtils.NeedLogin_Test3)
          public class Test3Activity extends AppCompatActivity {
          //攔截器操做(利用原有分組)
                      ARouter.getInstance().build(RouteUtils.NeedLogin_Test3).navigation();
        • 攔截器操做(綠色通道,跳過攔截器)
          //攔截器操做(綠色通道,跳過攔截器)
                      ARouter.getInstance().build(RouteUtils.NeedLogin_Test3)
                              .withString("extra", "我是綠色通道直接過來的,不通過攔截器")
                              .greenChannel()
                              .navigation();
        • 依賴注入
        • 必須先初始化JsonServiceImpl實現SerializationService
          • 這裏寫圖片描述

            package tsou.cn.lib_base.JsonService;
            
            import android.content.Context;
            
            import com.alibaba.android.arouter.facade.annotation.Route;
            import com.alibaba.android.arouter.facade.service.SerializationService;
            import com.alibaba.fastjson.JSON;
            
            import java.lang.reflect.Type;
            
            import tsou.cn.lib_base.utils.RouteUtils;
            
            /**
             * 依賴注入使用,注意:必須實現SerializationService進行註冊,
             */
            @Route(path = RouteUtils.Home_Json_Service,name = "序列化JavaBean使用")
            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);
                }
            }

            實現跳轉

            /**
                         * 序列化過得
                         * 必須先初始化JsonServiceImpl實現SerializationService
                         */
                        EventBusBean eventBusBean = new EventBusBean();
                        eventBusBean.setProject("android");
                        eventBusBean.setNum(3);
                        /**
                         * 普通的javaBean
                         */
                        JavaBean javaBean = new JavaBean();
                        javaBean.setName("huangxiaoguo");
                        javaBean.setAge(25);
            
                        List<JavaBean> objList = new ArrayList<>();
                        objList.add(javaBean);
            
                        Map<String, List<JavaBean>> map = new HashMap<>();
                        map.put("testMap", objList);
            
                        ARouter.getInstance().build(RouteUtils.Me_Inject)
                                .withString("name", "老王")
                                .withInt("age", 18)
                                .withBoolean("boy", true)
                                .withLong("high", 180)
                                .withString("url", "https://www.baidu.com")
                                .withParcelable("pac", eventBusBean)
                                .withObject("obj", javaBean)
                                .withObject("objList", objList)
                                .withObject("map", map)
                                .navigation();

            接收數據

            package tsou.cn.module_me.activity;
            
            import android.os.Bundle;
            import android.support.v7.app.AppCompatActivity;
            import android.widget.TextView;
            
            import com.alibaba.android.arouter.facade.annotation.Autowired;
            import com.alibaba.android.arouter.facade.annotation.Route;
            import com.alibaba.android.arouter.launcher.ARouter;
            
            import java.util.List;
            import java.util.Map;
            
            import tsou.cn.lib_base.bean.EventBusBean;
            import tsou.cn.lib_base.bean.JavaBean;
            import tsou.cn.lib_base.utils.RouteUtils;
            import tsou.cn.module_me.R;
            
            /**
             * 依賴注入使用,注意:必須實現SerializationService進行註冊,
             */
            @Route(path = RouteUtils.Me_Inject)
            public class InjectActivity extends AppCompatActivity {
                @Autowired
                String name = "hahahha";
            
                @Autowired
                int age = 13;
            
                @Autowired(name = "boy")//映射參數名
                        boolean sex;
            
                @Autowired
                long high = 160;
            
                @Autowired
                String url;
            
                @Autowired
                EventBusBean pac;
            
                @Autowired
                JavaBean obj;
            
                @Autowired
                List<JavaBean> objList;
            
                @Autowired
                Map<String, List<JavaBean>> map;
            
                @Autowired
                int height = 21;//上頁面沒有傳遞
            
                private TextView mTextView;
            
                @Override
                protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_inject);
                    ARouter.getInstance().inject(this);
                    initView();
                }
            
                private void initView() {
                    mTextView = (TextView) findViewById(R.id.textView);
                    String params = String.format(
                            "name=%s,\n age=%s, \n height=%s,\n girl=%s,\n high=%s,\n url=%s,\n pac=%s,\n obj=%s \n" +
                                    "  objList=%s, \n map=%s",
                            name,
                            age,
                            height,
                            sex,
                            high,
                            url,
                            pac.getProject(),
                            obj.getName(),
                            objList.get(0).getName(),
                            map.get("testMap").get(0).getName()
                    );
                    mTextView.setText(params);
                }
            }

            模塊間服務調用

            首先,爲了全部子類模塊都能共享這個方法,咱們在lib_base中定義一個服務接口:

            package tsou.cn.lib_base.provider;
            
            import com.alibaba.android.arouter.facade.template.IProvider;
            
            /**
             * Created by Administrator on 2017/12/5 0005.
             * 若是是共有的module_base裏的方法,不一樣模塊均可以調用。
             * 但若是屬於兩個模塊的獨有方法,其餘模塊是不能調用的,
             * 此時使用ARouter的IProvider來實現
             */
            
            public interface IChatModuleService extends IProvider {
                String getUserName(String userId);
            }

            該接口有個未實現的方法叫getUserName,獲取用戶名稱,接口寫好了由誰來實現呢?獲取用戶所在的地址只有chat模塊纔有這個方法,因此就須要在chat模塊中來實現這個接口了,咱們把它叫作ChatModuleService

            package tsou.cn.module_chat.module_service;
            
            import android.content.Context;
            
            import com.alibaba.android.arouter.facade.annotation.Route;
            
            import tsou.cn.lib_base.provider.IChatModuleService;
            import tsou.cn.lib_base.utils.RouteUtils;
            import tsou.cn.module_chat.net.ChatService;
            
            /**
             * Created by Administrator on 2017/12/5 0005.
             */
            
            @Route(path = RouteUtils.Service_Chat)
            public class ChatModuleService implements IChatModuleService {
            
                @Override
                public String getUserName(String userId) {
                    return ChatService.getUserName();
                }
            
                @Override
                public void init(Context context) {
            
                }
            }

            和Activity和Fragment同樣,咱們也須要在實現的Service上加上path路由註解,這樣ARouter框架才能發現這個服務,並且不一樣模塊的Service的path前的組「/chat/」必定要是不同的,否則會出現找不到的狀況:

            //模塊間服務調用,調用chat模塊的接口
                public static final String Service_Chat = "/chat/service";

            ChatService類中簡單的寫了一個getUserName方法,返回用戶的名稱

            package tsou.cn.module_chat.net;
            
            /**
             * Created by Administrator on 2017/12/5 0005.
             */
            
            public class ChatService {
                public static String getUserName() {
                    return "從服務器獲取的數據「hangxiaoguo」";
                }
            }

            接下來就是服務的發現(我放在了base中方便各個模塊的使用),調用方法:

            package tsou.cn.lib_base.route_service;
            
            /**
             * Created by Administrator on 2017/12/5 0005.
             * <p>
             * 服務的發現
             */
            
            public class ModuleRouteService {
            
                public static String getUserName(String userId) {
                    IChatModuleService chatModuleService = ARouter.getInstance().navigation(IChatModuleService.class);
                    if (chatModuleService != null) {
                        return chatModuleService.getUserName(userId);
                    }
                    return "";
                }
            
            }
          • 模塊間服務調用(普通調用)
            //模塊間服務調用
                        //例如home模塊調用chat模塊的方法
                        String userName = ModuleRouteService.getUserName("userId");
                        UIUtils.showToast(userName);
          • 模塊間經過路徑名稱調用服務
            //模塊間經過路徑名稱調用服務
                        String userName = ((IChatModuleService) ARouter.getInstance()
                                .build(RouteUtils.Service_Chat)
                                .navigation())
                                .getUserName("userid");
                        UIUtils.showToast(userName);
          • 模塊間經過類名調用服務
            //模塊間經過類名調用服務
                        String userName = ARouter.getInstance()
                                .navigation(IChatModuleService.class)
                                .getUserName("userid");
                        UIUtils.showToast(userName);

            跳轉失敗

             //跳轉失敗
                        ARouter.getInstance().build("/xxx/xxx").navigation(getContext(), new NavCallback() {
                            @Override
                            public void onFound(Postcard postcard) {
                                UIUtils.showToast("找到了");
                            }
            
                            @Override
                            public void onLost(Postcard postcard) {
                                UIUtils.showToast("找不到了");
                            }
            
                            @Override
                            public void onArrival(Postcard postcard) {
                                UIUtils.showToast("跳轉完了");
                            }
            
                            @Override
                            public void onInterrupt(Postcard postcard) {
                                UIUtils.showToast("被攔截了");
                            }
                        });

            由於/xxx/xxx這個路徑沒有對應的activity或fragment因此會跳轉失敗,走onLost方法。

相關文章
相關標籤/搜索