什么是MVP?
先來分享下,我對MVP架構的理解,如果有不正確的地方,請提出來,我一定改正。
看了很多文章之后,我認為:M代指Model,V代指Activity,P代指Presenter。下面詳細說明:
Google在某個項目Demo中用了上述那種結構,從而被大多數人接收并推廣,原地址:【https://github.com/googlesamples/android-architecture/tree/todo-mvp】,在推廣過程中,有很多個版本,各自都有各自的說法,但是Goole卻沒有明確說明,這也并不影響MVP這個架構模式的使用和推廣,而我比較贊同Goole的那種做法的,一個功能或者模塊一個Package,M作為儲存數據的倉庫的,Goole給出的Demo中,由于數據只是樣例,所以把Model作為公用,P(Presenter)用來管理M和V。
AppLib中MVP是怎么設計的?
為了方便,我們約定M用IModel,V用IView,P用IPresenter,并用Base*進行封裝出來,你可以通過繼承的方式來使用M、V、P。當然你也可以用IModel來指代M,IView指代V,IPresenter指代P。
M作為存放數據的倉庫,我們給出了接口(IRepsoitoryManager)交由使用者實現,可以用來請求網絡數據,數據緩存,數據處理等等。
Activity方面,我們仍然用Base*進行封裝。需要注意的是,BaseActivity繼承AppCompatActivity(),不再繼承Activity(),當然AppLib中的AppManager還是支持Activity()
將MVP模塊存放到mvp,方便源碼閱讀。
使用示例
在介紹MVP使用之前,我們推薦你這樣做:
1、重寫Application,并繼承AppLib中的BaseApplication(),這樣你就可以使用Debug,但你需要在
Application
中開啟:
class APP : BaseApplication() {
override fun onCreate() {
super.onCreate()
isDebug = true
}
}
記得要使用
2、實現 IRepositoryManager
:
class RepositoryManager : IRepositoryManager {
override fun onDestroy() {
}
override fun getNetData(url : String, params : Any, callBack : ICallback<Any>) {
}
}
特別提醒,雖然參數設為Any,但并不代表可以提交任何格式的數據,雖然也是可以的,但我們并推薦那么做。
3、下面以登錄為例,實現MVP的代碼,當然這代碼是可以通用的,命名也是為了這么做:
class LoginMVP {
class Activity : BaseActivity<Presenter>(), IView {
override fun initFragment() = null
override fun isUseFragment() = false
override fun initPresenter() = Presenter()
override fun getLayoutId() = R.layout.activity_login
// click events
override fun click() {
// TODO
}
override fun init() {
// mPresenter為Presenter對象,用來操作Prensenter,你可以直接使用
toast(mPresenter.tipText())
log("Hello iWenyi") // Debug模式,需要在Application中開啟,TAG默認為iWenyi,暫不支持修改
}
}
class Presenter : BasePresenter<Model, Activity>() {
fun tipText() = "Hello iWenyi"
}
class Model : BaseModel(RepositoryManager()) {
}
class Fragment : BaseFragment() {
override fun init() {
}
}
}
4、注冊一下吧:
<application
android:name=".APP"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".login.LoginMVP$Activity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
5、引入:
allprojects {
repositories {
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
compile 'com.github.fengwenyi:AppLib:0.0.9'
// gson
compile 'com.google.code.gson:gson:2.8.1'
}
示例代碼只是樣例,并不能代碼AppLib中MVP的全部內容。