Android模块化之登录业务处理
前面介绍过Android模块化的基本方法,能够保证每个模块单独运行。如果没看过,戳这里:Android模块化简单教程。但是这些只是最基本的,一个项目模块化的过程中会遇到许许多多的问题,最重要的就是一个登录问题,当我们单独运行某个模块的时候,我们的前提是必须进行登录操作,如何使得每个模块运行之前都运行登录模块呢?这里有两种方案,示例代码看这里。
方案一:BaseActivity拦截(本方案的代码看git历史记录)
- 在登录模块中将登录状态记录到全局数据中心中
DataCenter.getInstance().setLogin(true);
- 在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配置的地址)带过去,这样登录完毕后才能跳转回当前页面。
- 注册登录后的跳转地址
在第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了。
- 处理登录模块的跳转
@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的使用
更多相关文章
- android_项目_知识积累_mina通信(android手机登录功能)
- 关于多设备登录的思考与实现
- Android下对Cookie的读写操作(附Demo)
- Android(安卓)ApiClound 自定义模块未绑定解决方案
- Android轻松搭建MVP + Retrofit + RxJava(MR篇)
- ReactNative学习笔记之调用原生模块(进阶)之Callback、Promise使用
- Android业务组件化之子模块SubModule的拆分以及它们之间的路由Ro
- Android(安卓)P2P语音通话实现(思路探讨)http://www.cnblogs.com/m
- 使用ARouter进行Android模块化开发