模块化开发步骤 + ARouter的使用 + 结合mvp结构分模块(三)

模块化开发步骤 + ARouter的使用 + 结合mvp结构分模块(一) 

模块化开发步骤 + ARouter的使用 + 结合mvp结构分模块(二)

模块化开发步骤 + ARouter的使用 + 结合mvp结构分模块(三)


接下来我们结合MVP模式结构分模块:

首先分模块我们知道模块间是不能互相调用的,所以自己封装的mvp结构和一些公用的底层封装我们新建模块的时候选择Library,里面放所有公用的东西,然后每个模块只要依赖它就可以了。

这一块需要结合我前面文章说的Retrofit+Rxjava封装的MVP来讲解

demo按导航栏中分4个模块+1个Library库。

1、mvp_library模块。以library模式存在,所以不用管它的AndroidManifest,只需要按模块化开发步骤中提到的SDK配置即可

 

1.1、关于bean的疑问:

mvp + api + utils 公用大家都比较容易理解,这个bean实体为何会在这里?

1、api接口声明的时候就已经需要声明这个实体了;

2、这些实体只是做数据的载体,没有任何逻辑,是可以复用的。

1.2、其他公用部分:

除了截图中的类文件,还有raw资源,第三方库的依赖,这些都是所有模块通用的,所以都放到这个library里面。

对第三方库的依赖需要特别注意,把所有其他模块会用到的第三方库的implementation改成api,只有自己模块才用的依赖就不用改。

这里顺便说一下implementation和api的区别:项目implementation依赖一个库(假设叫a库),则项目不能引用a库里面声明却没有用到的库,而api可以引用到。我们这里是自己的library引用这些第三方库来再被依赖到各个模块中使用,所以要用api。

1.3、ARouter依赖:

implementation 'com.alibaba:arouter-api:1.5.0'

annotationProcessor 'com.alibaba:arouter-compiler:1.2.2'

上面我们是把它们写在一起,但是在这里我们需要把它们分开,咱们这个library里只要添加第一个,api 'com.alibaba:arouter-api:1.5.0'。

annotationProcessor 这个是帮我们自动生成文件的东西,需要在各个模块里面分别写,才能生成本模块所需的文件。

对了,还有前面说的arguments = [AROUTER_MODULE_NAME: project.getName()]代码块也是分别在每个模块的build.gradle中写,本library中不需要写。

1.4、关于BaseArouter类:

BaseArouter类为分模块封装的类注解字符串路径常量,类里面再按模块分4个内部类,每个内部类里面写自己的Activity或者Fragment的字符串

/**
 * @author : xaeHu
 * e-mail : [email protected]
 * @date : 2019/8/13 12:07
 * desc   :Arouter类注解声明path常量
 */
public class BaseArouter {
    /**
     * 主页模块
     */
    public class Home{
        public final static String HomeFragment = "/Home/HomeFragment";
        public final static String SearchActivity = "/Home/SearchActivity";
        public final static String SearchDetailActivity = "/Home/SearchDetailActivity";
    }

    /**
     * 个人中心模块
     */
    public class Person{
        public final static String PersonFragment = "/Person/PersonFragment";
    }
    
    ······//其他模块
}

 

2、主模块。就是项目的app模块,这个模块是躯壳,只做欢迎页WecomeActivity或者界面启动的MainActivity还有Application的声明(或者还有微信SDK所需wxapi)。

说类之前先说一下他的AndroidManifest和build.gradle:

2.1、首先AndroidManifest只需要添加所有权限和改继承了Application的那个类名id给application元素:

<uses-permission android:name="android.permission.INTERNET" />
<application
    android:name=".App"
    ······

2.2、build.gradle:

2.2.1、上面说的SDK版本配置

2.2.2、阿里ARouter配置

android{
    ······
    javaCompileOptions {
        annotationProcessorOptions {
            arguments = [AROUTER_MODULE_NAME: project.getName()]
        }
    }
    ······
}

2.2.3、依赖:

 

dependencies{
    ······
    api project(':mvp_library')
    annotationProcessor 'com.alibaba:arouter-compiler:1.2.2'
    if(!MODULE_IS_APPLICATION.toBoolean()){
        implementation project(':home_module')
        implementation project(':search_module')
        implementation project(':detail_module')
        implementation project(':person_module')
    }
}

 

我这个模块里面直接定义两个类,一个MainActivity,还有一个继承了Appalachian的App类。

 2.3、MainActivity的界面是ViewPager+SlidingTabLayout,ViewPager放其他四个模块的主Fragment:

//private ViewPager viewpager;
//private SlidingTabLayout tab;
//private String []title = {"首页","搜索","详细搜索","个人中心"};
ArrayList<Fragment> fragmentList = new ArrayList<>();
fragmentList.add((Fragment) ARouter.getInstance().build(BaseArouter.Home.HomeFragment).navigation());
fragmentList.add((Fragment) ARouter.getInstance().build(BaseArouter.Search.SearchFragment).navigation());
fragmentList.add((Fragment) ARouter.getInstance().build(BaseArouter.Detail.SearchDetailFragment).navigation());
fragmentList.add((Fragment) ARouter.getInstance().build(BaseArouter.Person.PersonFragment).navigation());
tab.setViewPager(viewpager,title,this, fragmentList);

 

2.4、App类里面做必要的初始化:

public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        // 这两行必须写在init之前,否则这些配置在init过程中将无效
        if (BaseConstant.IS_DEBUG) {
            ARouter.openLog();     // 打印日志
            ARouter.openDebug();   // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
        }
        // 尽可能早,推荐在Application中初始化
        ARouter.init(this);
    }
}

 

3、其他模块

AndroidManifest和build.gradle的修改如模块化开发步骤所说。

另外:需要添加library模块和ARouter配置:

android{
    ······
    javaCompileOptions {
        annotationProcessorOptions {
            arguments = [AROUTER_MODULE_NAME: project.getName()]
        }
    }
    ······
}
······
dependencies {
    ······
    api project(":mvp_library")
    annotationProcessor 'com.alibaba:arouter-compiler:1.2.2'
}

Activity和Fragment的注解:

@Route(path = BaseArouter.Home.SearchActivity)
public class SearchActivity extends BaseActivity<SearchPresenter>

@Route(path = BaseArouter.Home.HomeFragment)
public class HomeFragment extends BaseFragment<HomeP>

 

最后,还有个关键的地方,如果你的模块可独立运行,那它得有入口,并且在主模块的App里初始化的东西这里也拿不到对吧。

所以我们可以利用新建模块的时候那个入口Activity类做这些:

界面只放一个FrameLayout布局,用于显示本模块最外层的这个Fragment。app里初始化的东西也都搬到这里初始化。

因为这个入口类只是做单独运行的时候用,打包的时候是不用的,所以我们不需给他添加ARouter的注解,我们不需要跳转到这个界面来。

 

public class HomeMainActivity extends BaseStaticActivity {

    @Override
    protected int getLayoutId() {
        return R.layout.acticity_home;
    }

    @Override
    protected void initView() {
    }

    @Override
    protected void initData() {
        // 这两行必须写在init之前,否则这些配置在init过程中将无效
        if (BaseConstant.IS_DEBUG) {
            ARouter.openLog();     // 打印日志
            ARouter.openDebug();   // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
        }
        // 尽可能早,推荐在Application中初始化
        ARouter.init(getApplication());
        FragmentManager fm = getSupportFragmentManager();
        if(fm != null) {
            Fragment fragment = fm.findFragmentById(R.id.activity_home_fragment);
            if(fragment == null){
                fragment = new HomeFragment();
                fm.beginTransaction().add(R.id.activity_home_fragment, fragment).commit();
            }
        }
    }

    @Override
    protected void initListener() {
    }
}

 

最后附上demo地址:github

完。

转载请注明出处。

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章