Kotlin就不说了..谷歌爸爸的亲儿子...
MVP就不说了..解耦彻底..利于维护
模块化就不说了..解耦更彻底..更利于维护
dagger就不说了..注入引用..
rx就不说了...跟着潮流走就行...
step1
新建一项目...开始入坑...
具体在Android studio中怎样配置Kotlin...就不多说了..
Android studio 配置Kotlin
step2
0.png上图是模块化的项目的大致结构图...APP为主Application的运行程序...BaseLibrary为整个应用程序的基本组件...很多第三方依赖库和一些相关配置都在此Module中...Provider为中间件连接库..User为用户的登录模块的库...如此的话,就将一个整体项目(只包含登录的部分)分为四个模块...1,主App...2,基本模块...3,中间模块...4,用户登录模块...此时需要注意的是主App为应用程序的启动项..其余的三个是主App所依赖的library...
step3
好了...大致的三个模块库已经建立完毕...那么接下来就需要将三个模块和主App进行关联...
Provider模块依赖BaseLibrary..其余的模块依赖Provider模块..这样所有的模块就都有了关系...当然主App还需要在依赖User模块...
举个例子:--> 一家四口..Base就是爸爸...去赚钱(依赖第三方库和一些配置),Provider就是妈妈...负责给爸爸掌管财务(依赖于BaseLibrary)...User就是长子...爸爸出门在外...给妈妈要钱,依赖着妈妈...主App就是婴儿...爸爸不在,既需要妈妈的照顾也许要哥哥的照顾...所以主App依赖于User和Provider..
1,主App的build.gradle文件中dependencies ---->说明: 如果有和BaseLibrary中的依赖有相同此处删掉即可,避免重复依赖...
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
compile project(':Provider')
compile project(':User')
}
2,Provider中的build.gradle文件中dependencies ---->说明同上
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
compile project(':BaseLibrary')
}
3,User中的build.gradle文件中dependencies ---->说明同上
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
compile project(':Provider')
}
4,BaseLibrary中的build.gradle文件中的dependencies ---> 说明: 所有的依赖的第三方的库和文件都在Base中...此处现在还没有任何依赖
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.+'
testCompile 'junit:junit:4.12'
}
如此就依赖好了各个模块之间的关系...相互联系,相互依赖..想起来白夜行...亮子和雪穗.......
step3User模块中新建LoginActivity
xml布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/MathMathV"
>
<EditText
android:id="@+id/mEtUserName"
style="@style/MathWrap"
android:layout_marginTop="20dp"
android:hint="输入用户名"
/>
<EditText
android:id="@+id/mEtPwd"
style="@style/MathWrap"
android:hint="输入密码"
/>
<Button
android:id="@+id/mBtnLogin"
style="@style/MathWrap"
android:layout_marginTop="20dp"
android:text="登录"
/>
</LinearLayout>
activity代码
class LoginActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
mEtUserName.hint = "请输入用户名"
mEtPwd.hint = "请输入密码"
mBtnLogin.setOnClickListener{
toast("点击了注册按钮..")
}
}
}
上方activity代码中直接用了xml中的控件Id..此处省去了butterknife的@bindView操作...用的也是Kotlin的插件..在User的build.gradle中添加一下依赖
apply plugin: 'kotlin-android-extensions'
之后sync同步即可,就可以直接用控件的id对控件进行操作,不需要再findViewById和@bindView了...
相同的是Toast的弹出事件是依赖的kotlin中的anko依赖...anko提供了四个方面的操作(经典...数据库...布局...协程),具体请移步至github.anko
step4
将User中的build.gradle文件中的apply plugin:'com.android.library'改为apply plugin:'com.android.application'之后进行编译同步..就会出现此模块的运行名称,之后在manifest中添加启动项和theme主题..点击运行即可...一来试试结果二来试试有没有bug 2.png运行成功...可以看到UserCenter的title..UserCenter和上文中的User是同一个Module...(请原谅我.......!!!!)
step5
搞了有那么一会儿了..运行一下吧...突然发现..握了个草..这怎么运行...
User是依赖库...又不是主App...
那把User独立成主App就好了...在User的manifest文件中添加启动项intent-filter就好了么....
不好...还要将build.gradle中的apply plugin:'com.android.library'改为apply plugin:'com.android.application'才行
但是可能在写的过程中,一会儿要作为主App运行,一会儿又要作为Module运行...这一会儿删除启动项,一会儿添加启动项的...莫非骚年真的是意气风发,任劳任怨,劳动模范....别逗了,程序猿都是懒惰的..
在User的Module中..切换到project模式下...在main中创建两个文件夹...一为debug, 一为release...之后将manifest文件拷贝两份分别扔里面..debug时就是主App运行.release时就是模块运行..
1.png
debug下的manifest文件代码
<application
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme"
>
<activity android:name=".ui.activity.LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
release下的manifest文件
<application
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true">
<activity android:name=".ui.activity.LoginActivity">
</activity>
</application>
至此...两套清单文件是OK了,但是怎么样分别在不同的情况下来使用呢...
在整体项目的gradle.properties文件中添加一句代码,声明一个变量
isUserModule = false
之后在User的build.gradle文件中进行两次判断..
if (isUserModule.toBoolean()) {
apply plugin: 'com.android.library' //如果isUserModule为true即为库来运行
} else {
apply plugin: 'com.android.application' //否则为应用程序来运行
}
//与此同时...因为有两套manifest文件..所以需要动态判断使用..
sourceSets {
main {
if (isUserModule.toBoolean()) {
manifest.srcFile 'src/main/release/AndroidManifest.xml' //此处需要注意的是manifest是小写,不是大写....
//release模式下排除debug文件中的所有的Java文件
java {
exclude 'debug/**'
}
} else {
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
}
}
}
OK...进行编译...同步...等待...
可以看到的是,当isUserModule为true时即代表User为一个依赖库..运行的是主App的helloworld界面...
当isUSerModule为false的时候即代表User为一个应用程序运行...运行的是登录的界面...
写到这里,第一步的模块化的初始化差不多已经完成...接下来写登录的MVP模式和Dagger2以及RX等相关...
未完待续...
网友评论