美文网首页Android实战
Android模块化之登录业务处理

Android模块化之登录业务处理

作者: 低情商的大仙 | 来源:发表于2017-06-28 16:36 被阅读834次

    前面介绍过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 Map<String,String>activityRouterMap = 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。

     <application
            android:allowBackup="true"
            android:icon="@mipmap/new_house_ic_launcher"
            android:label="@string/new_house_app_name"
            android:supportsRtl="true"
            android:name="com.baronzhang.android.commonbusiness.base.BaseApplication"
            tools:replace="label"
            android:theme="@style/NewHouseAppTheme">
            <activity android:name="com.baronzhang.android.commonbusiness.base.login.LoginActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity
                android:name="com.baronzhang.android.newhouse.NewHouseMainActivity"
                android:label="@string/new_house_label_home_page">
            </activity>
    
        </application>
    

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

    <application
            android:allowBackup="true"
            android:icon="@mipmap/new_house_ic_launcher"
            android:label="@string/new_house_app_name"
            android:supportsRtl="true"
            android:name="com.baronzhang.android.commonbusiness.base.BaseApplication"
            tools:replace="label"
            android:theme="@style/NewHouseAppTheme">
            <activity android:name="com.baronzhang.android.commonbusiness.base.login.LoginActivity">
    

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

    public class ConstantRouter {
        //各个模块首页和跳转地址的映射
        public static Map<String,String>activityRouterMap = 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模块化之登录业务处理

        本文链接:https://www.haomeiwen.com/subject/xsiucxtx.html