Android/Kotlin:将不同的活动“特征”组合成一个活动

Posted

技术标签:

【中文标题】Android/Kotlin:将不同的活动“特征”组合成一个活动【英文标题】:Android/Kotlin: Composing different Activity "traits" into one activity 【发布时间】:2020-04-18 12:09:17 【问题描述】:

我正在寻找一种在 android 活动中组合不同功能的方法,该方法应该可重复用于不同的活动类。具体来说,问题出在重写 open 方法,其中还必须调用 super 的实现。

open class FirstActivity : FragmentActicity() 
  override fun onStart() 
    super.onStart()
    doSomething()
  

这很简单,但它不可重复使用。我可以例如想要使用不同的基础活动类具有相同的行为:

open class SecondActivity : AppCompatActivity() 
  override fun onStart() 
    super.onStart()
    doSomething()
  

我必须复制代码。如果我有一个非常基本的功能,比如跟踪活动的状态,我会或多或少地希望在我所有具有不同基类的活动中使用它。 当我想创建更多可以组合的功能时,情况会变得更糟:

open class ThirdActivity : FragmentActivity() 
  override fun onResume() 
    super.onResume()
    doSomeResuming()
  


open Class FirstActivityAgain : ThirdActivity 
  override fun onStart() 
    super.onStart()
    doSomething()
  


class MyFragmentActivity : FirstActivity() 
  override fun onStop() 
    doSomethingElse()
    super.onStop()
  


class MyFragmentActivityWithResuming : FirstActivityAgain() 
  override fun onStop() 
    doSomethingElse()
    super.onStop()
  


class MyTopBarActivity : SecondActivity() 
  override fun onStop() 
    doSomethingElse()
    super.onStop()
  



In Scala I can use Traits 这样做stackable modification,它允许非常灵活的功能混合。甚至可以一遍又一遍地修改相同的方法,只需要小心linearization order。 这在 Kotlin 中是不可能的,因为 Scala Trait 既不等同于 Kotlin 抽象类也不等同于 Kotlin 接口。

Kotlin 的代表似乎也不可能。我还考虑过使用泛型,在我有限的想象中可能是这样的:

open class FirstActivity<BaseActivity : Activity> : BaseActivity() 
  ...

这当然也是不可能的。

有什么我忽略的吗?可以使用 Dagger 来完成吗?

【问题讨论】:

【参考方案1】:

您在 Kotlin 中所指的内容称为 interfaces 以及一些基本的 delegation。

interface Base 
    fun printMessage()
    fun printMessageLine()


class BaseImpl(val x: Int) : Base 
    override fun printMessage()  print(x) 
    override fun printMessageLine()  println(x) 


class Derived(b: Base) : Base by b 
    override fun printMessage()  print("abc") 


fun main() 
    val b = BaseImpl(10)
    Derived(b).printMessage()
    Derived(b).printMessageLine()

虽然它不会让您摆脱 super 问题,因为它是 Android 框架问题而不是 Kotlin 语言问题。

对于你的情况,我会做类似的事情

interface BaseActivityContainer
 var activity: Activity


class MainActivity: BaseActivityContainer

override var activity: Activity = this



interface BaseDoable: BaseActivityContainer

fun doActivityStuff()
 activity.getString(...)




interface BaseDoableSecond: BaseActivityContainer

fun doActivityStuff()
 activity.getDrawable(...)




class SomeActivity: MainActivity, BaseDoableSecond by this

借助 Android 生命周期处理 Lyfecycle 事件

这还不完整,几乎没有功能,但我希望它能为你清除一些东西。

【讨论】:

感谢您的回答,但它不包括将功能“插入”到 Android Activity 框架函数(如 onCreate 等)的方法。 另外,如果我没记错的话,在委托接口属性时不可能以任何方式使用“this”,因为“this”在委托时还不存在!跨度> 关于这一点,您是正确的 - 正如我在答案中所写的那样,代码“不完整且几乎没有功能”。使用组合而不是继承将使这成为可能。

以上是关于Android/Kotlin:将不同的活动“特征”组合成一个活动的主要内容,如果未能解决你的问题,请参考以下文章

Android kotlin:无法读取类文件

Android Kotlin 无法从另一个活动中获取结果

Android Kotlin:如果当前活动或应用程序关闭,则进行集成测试

如何将editText值传递给viewModel和Livedata(Kotlin)

如何从 seekbar Android Kotlin 更改字符串的长度

Android Kotlin viewBinder - 从 Activity 更改 RecyclerView Item 的 ItemView