Android开发之接口继承

265 阅读2分钟

正文

在安卓开发过程中, BaseActivity BaseFragment 是我们要经常设计的,通常情况下我们将其定义为抽象类,并在其中扩充我们自己定义的方法,例如:

abstract class BaseActivity : AppCompatActivity(){

    // 自定义加载函数
    fun loading(){
    
    }
    
    // 自定义获取日志tag
    fun getDefaultTag() = this.javaClass.simpleName

}

但是随着开发,这样的自定义函数会越来越多, BaseActivity 可能会的臃肿繁琐,因此可以用接口去约束这些方法,使其便于管理。

// 接口定义
interface BaseActivityMethod{
    fun loading()
    
    fun getDefaultTag()
}

// BaseActivity
abstract class BaseActivity : AppCompatActivity() , BaseActivityMethod{

    // 自定义加载函数
    override fun loading(){
    
    }
    
    // 自定义获取日志tag
    override fun getDefaultTag() = this.javaClass.simpleName

}

接口定义有助于我们后期进行维护,但是这样依旧无法处理好复杂度,同时 getDefaultTag 这样的方法也无法被 BaseFragment 复用, 为此我们可以使用接口继承来实现功能的细分。设计思路如下:

graph LR
A[BaseActive]-->B[BaseVisActive]
B-->C[BaseActivity]
B-->D[BaseFragment]
A-->E[BaseService]
  • BaseActive 表示基础的活动
  • BaseVisActive 表示可见的活动

再来看接口的定义

interface BaseActive {
    // Default tag for log.
    fun getDefaultTag(): String
    // Create mainScope
    fun createMainScope(): CoroutineScope
    // Construct a network request builder.
    fun getRequestBuilder(): RequestBuilder
}

interface BaseVisActive : BaseActive {
    // Get self or attached [Activity].
    fun getBaseActivity(): Activity
    // Get the ViewBinding
    fun getBinding(): ViewBinding {
        throw IllegalStateException("You should not call getBinding().")
    }
    // Get the ViewModel
    fun getViewModel(): ViewModel {
        throw IllegalStateException("You should not call getViewModel().")
    }
}

interface BaseActivity : BaseVisActive {
    // Get the [Context].
    fun getContext(): Context
    // Get default [Snackbar] for activity.
    fun getSnackbar(): Snackbar
    // True if you want to show the ActionBar,false otherwise. 
    fun enableActionBar(enable: Boolean)
    // True if you want to set fullscreen,false otherwise
    fun enableFullScreen(enable: Boolean)
}

interface BaseFragment : BaseVisActive {
    // When [setVmBySelf] is true, the ViewModel representing the Fragment is
    // retained by itself. When you want the ViewModel to be retained by its
    // associated Activity, please set [setVmBySelf] to false.
    fun setVmBySelf(): Boolean = false
}

在这种设计下,既可以保证 getDefaultTag getBinding 这类方法在 ActivityFragment 中都可以被调用,同时也保证了 Activity 有自己独有的拓展方法,例如 enableActionBar。这就达到了复用的同时又有粗细度之分。

源码

如果你需要查看源码,请访问 VastUtils 来查看