前面介绍过Android模块化的基本方法,能够保证每个模块单独运行。如果没看过,戳这里:Android模块化简单教程。但是这些只是最基本的,一个项目模块化的过程中会遇到许许多多的问题,最重要的就是一个登录问题,当我们单独运行某个模块的时候,我们的前提是必须进行登录操作,如何使得每个模块运行之前都运行登录模块呢?这里有两种方案,示例代码看这里。

方案一:BaseActivity拦截(本方案的代码看git历史记录)

  1. 在登录模块中将登录状态记录到全局数据中心中
    DataCenter.getInstance().setLogin(true);
  2. 在BaseActivity中判断是否登录
if(!DataCenter.getInstance().isLogin()){            String curUrl = ConstantRouter.getCurRouter(this.getClass().getSimpleName());            ARouter.getInstance().build(ConstantRouter.LOGIN_ACTIVITY)                    .withString("targetUrl",curUrl)                    .navigation();            finish();        }

在BaseActivity中,首先判断是否登录了,如果登录了自然继续走下去,如果没有登录过,那么则要跳转到登录页面去登录,并结束当前页面,这里注意,跳转到登录页面时要把当前页面的地址(ARouter配置的地址)带过去,这样登录完毕后才能跳转回当前页面。

  1. 注册登录后的跳转地址
    在第2步中,我们要将当前页面的url传入到LoginActivity中,但是,我们是在BaseActivity中处理这个跳转的,而每个url是在子activity中配置的,BaseActivity中是拿不到这个url的。为了解决这个问题,我们统一静态配置登录时跳转的路由表:
public class ConstantRouter {    public static MapactivityRouterMap = new HashMap<>();    //主页    public static final String APP_MAINACTIVITY = "/app/MainActivity";    //即时通讯首页    public static final String IM_MAINACTIVITY = "/im/InstantMessagingMainActivity";    //新房首页    public static final String NEW_HOUSE_MAINACTIVITY = "/new_house/NewHouseMainActivity";    //二手房首页    public static final String SECOND_HOUSE_MAINACTIVITY = "/second_house/SecondHouseMainActivity";    /**     * 登录     */    public static final String LOGIN_ACTIVITY = "/common_business/LoginActivity";    static{        activityRouterMap.put(getActivityName(APP_MAINACTIVITY),APP_MAINACTIVITY);        activityRouterMap.put(getActivityName(IM_MAINACTIVITY),IM_MAINACTIVITY);        activityRouterMap.put(getActivityName(NEW_HOUSE_MAINACTIVITY),NEW_HOUSE_MAINACTIVITY);        activityRouterMap.put(getActivityName(SECOND_HOUSE_MAINACTIVITY),SECOND_HOUSE_MAINACTIVITY);        activityRouterMap.put(getActivityName(LOGIN_ACTIVITY),LOGIN_ACTIVITY);    }    private static String getActivityName(String routerUrl){        int pos = routerUrl.lastIndexOf("/");        return routerUrl.substring(pos+1);    }    public static String getCurRouter(String activityName){        return activityRouterMap.get(activityName);    }}

配置ARouter的url时,我们遵从一个原则,该url结尾必然是该Activity的类名称,然后我们将该Activity的名称和他的ARouter的url建立一个静态映射,这样,在BaseActivity中,我们就能够通过运行时的类名获得它的url:
String curUrl = ConstantRouter.getCurRouter(this.getClass().getSimpleName());
这样就可以实现将当前页面的url传给LoginActivity了。

  1. 处理登录模块的跳转
@Route(path = "/common_business/LoginActivity")public class LoginActivity extends CommonBaseActivity{    @Autowired    String targetUrl;    @BindView(R2.id.progressBar)    ProgressBar progressBar;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_login);        ARouter.getInstance().inject(this);        if(targetUrl == null){            //默认跳转到MainActivity            targetUrl = ConstantRouter.APP_MAINACTIVITY;        }        //此处用来模拟登录事件        progressBar.postDelayed(new Runnable() {            @Override            public void run() {                DataCenter.getInstance().setLogin(true);                ARouter.getInstance().build(targetUrl).navigation();                LoginActivity.this.finish();            }        },2000);    }}

在LoginActivity中登录完成后,直接跳转到之前的页面即可。

方案二:登录模块跳转判断

本方案核心思想就是每个模块统一先走登录流程,登录完成后再根据当前运行的是哪个模块跳转到该模块的首页。
1.在每个module的单独运行时的AndroidManifest.xml中指定登录模块为启动activity。

                                                                                             

2.判断当前运行的是那个Module
由于LoginActivity是在CommonBusiness模块中的,只是一个子module而已,我们要在这个模块中获取当前运行的module是比较困难的,这里提供一种方法,我们可以在每个module的debug时的AndroidManifest.xml中指定一个label,然后子module中可以取到这个label,从而可以判断当前运行的是哪个模块。

        

这里要确保每个module的label不一样,不然会出现跳转错误。
3.注册路由表
每个module都有自己的label,然后我们将该label和该模块首页的url建立一个映射,形成路由表,方便跳转。

public class ConstantRouter {    //各个模块首页和跳转地址的映射    public static MapactivityRouterMap = new HashMap<>();    //主页    public static final String APP_MAINACTIVITY = "/app/MainActivity";    //即时通讯首页    public static final String IM_MAINACTIVITY = "/im/InstantMessagingMainActivity";    //新房首页    public static final String NEW_HOUSE_MAINACTIVITY = "/new_house/NewHouseMainActivity";    //二手房首页    public static final String SECOND_HOUSE_MAINACTIVITY = "/second_house/SecondHouseMainActivity";    /**     * 登录     */    public static final String LOGIN_ACTIVITY = "/common_business/LoginActivity";    static{        activityRouterMap.put(BaseApplication.getApplication().getString(R.string.label_app),APP_MAINACTIVITY);        activityRouterMap.put(BaseApplication.getApplication().getString(R.string.label_instant_messaging),IM_MAINACTIVITY);        activityRouterMap.put(BaseApplication.getApplication().getString(R.string.label_second_house),SECOND_HOUSE_MAINACTIVITY);        activityRouterMap.put(BaseApplication.getApplication().getString(R.string.label_new_house),NEW_HOUSE_MAINACTIVITY);    }    public static String getCurRouter(String label){        return activityRouterMap.get(label);    }}

4.在LoginActivity中根据label进行跳转

 /**     * 获取当前登录完毕要跳转到哪个模块首页     * @return     */    private String getCurModuleUrl(){        String label = null;        try {            label = getResources().getString(                    getPackageManager().getApplicationInfo(getPackageName(), 0).labelRes);            return ConstantRouter.getCurRouter(label);        } catch (PackageManager.NameNotFoundException e) {            e.printStackTrace();        }        return null;    }         targetUrl = getCurModuleUrl();        if(targetUrl == null){            targetUrl = ConstantRouter.APP_MAINACTIVITY;        }        //此处用来模拟登录事件        progressBar.postDelayed(new Runnable() {            @Override            public void run() {                DataCenter.getInstance().setLogin(true);                ARouter.getInstance().build(targetUrl).navigation();                LoginActivity.this.finish();            }        },2000);   

总结

两种方案,方案一有一个缺点,就是在未登录情况下,模块首页会先跳转到登录页然后结束自己,这样会导致一个一闪而过的情况,还是有点明显的,当然,这个只在开发时会出现,发布后肯定是以一整个App发布出去,不会出现单独运行Module情况,自然不会出现这种情况。所以,我采用的是第二种方案,只要确保每个module的label不重复即可。

最后可以继续看下我的另一篇文章:Android模块化之ButterKnife和Dagger2的使用

更多相关文章

  1. android_项目_知识积累_mina通信(android手机登录功能)
  2. 关于多设备登录的思考与实现
  3. Android下对Cookie的读写操作(附Demo)
  4. Android(安卓)ApiClound 自定义模块未绑定解决方案
  5. Android轻松搭建MVP + Retrofit + RxJava(MR篇)
  6. ReactNative学习笔记之调用原生模块(进阶)之Callback、Promise使用
  7. Android业务组件化之子模块SubModule的拆分以及它们之间的路由Ro
  8. Android(安卓)P2P语音通话实现(思路探讨)http://www.cnblogs.com/m
  9. 使用ARouter进行Android模块化开发

随机推荐

  1. Android(安卓)- android.process.media意
  2. javap -s 查看java方法签名
  3. Android(安卓)LitePal介绍与使用说明
  4. android 添加核心层服务
  5. Android——调用系统摄像头拍照的问题
  6. android 布局方式 像素单位
  7. 【ERROR】---Error executing "adb devic
  8. Android(安卓)上的 HTTP 服務相關函式 (I
  9. Android(安卓)ImageView 图片设置为透明
  10. Android开发报错: Authentication scheme