模塊化開發步驟 + 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

完。

轉載請註明出處。

 

 

 

 

 

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