在Kotlin中是否可以创建一个适用于多个伴生对象的全局通用函数?

huangapple go评论77阅读模式
英文:

Is it possible to make a global, generic function for multiple companion objects in kotlin

问题

I develop an app in Kotlin that has many Activities. 多个Activities的Kotlin应用程序

Most of the navigation is just basic, starting the new activity, not passing anything to the intent. 大多数导航都很基本,只是启动新的活动,不传递任何内容到意图中。

For a few groups of Activities I might pass flags, which is also repetitive throughout my project (e.g. 5 Activities that set intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK). 对于一些Activity组,我可能会传递标志,这在我的项目中也是重复的(例如,设置intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK的5个Activities)。

So if I could find a way to make that just one implementation would make things a little nicer. 所以如果我能找到一种方法,使这只有一个实现将会使事情变得更加美好。

To make things easier and a little neater, I have created companion objects for the Activities that hold the following function: 为了使事情变得更容易和更整洁,我为Activities创建了伴随对象,其中包含以下函数:

   companion object {
        fun startActivity(context: Context) {
            context.startActivity(
                Intent(context, MyActivity::class.java)
            )
        }
    }
... ``` 

Other classes can simply call `MyActivity.startActivity(context)`. 其他类可以简单地调用`MyActivity.startActivity(context)`。

The function is pretty basic and the only difference between the implementation in different Activities is obviously the `MyActivity::class.java`-part. 这个函数非常基础,不同Activities中的实现唯一的区别显然是`MyActivity::class.java`部分。

So I'd like to know if it's possible to declare this function only ONCE and somehow use it within multiple companion objects for the different activities. 所以我想知道是否可以只声明此函数一次,然后在不同活动的多个伴随对象中以某种方式使用它。

Now, I understand I could do something like this: 现在,我明白我可以这样做:

I define an object that has a function with a generic type and set it up like this: 我定义一个具有泛型类型的对象,并设置如下:

``` object MyObject {
    inline fun <reified T: AppCompatActivity>startActivity(context: Context) {
        context.startActivity(
            Intent(context, T::class.java)
        )
    }
}

class MyActivity() : AppCompatActivity() {
    companion object {
        fun start(context: Context) = MyObject.startActivity<MyActivity>(context)
    }
} ``` 

But this still seems a little hacky. 但这仍然似乎有点巧妙。

What I'm looking for is something like inheritance or an implemented version of an interface to simply add to my companion object. 我在寻找的是类似继承或接口的实现版本,只需添加到我的伴随对象即可。

Something like: 例如:

``` companion object : MyObject<MyActivity>
// Assuming I can somehow put the generic parameter into the object declaration instead of the function or do something similar

or 或者

    import MyObject.startActivity<MyActivity>
} ``` 

The first option would be especially useful, as it would automatically set up multiple functions of `MyObject` for `MyActivity`. 第一个选项特别有用,因为它会自动为`MyActivity`设置多个`MyObject`函数。

Is something like this even possible? 这样的东西是否可能?

<details>
<summary>英文:</summary>

I develop an app in Kotlin that has many `Activities`. Most of the navigation is just basic, starting the new activity, not passing anything to the intent. For a few groups of Activities I might pass flags, which is also repetitive throughout my project (e.g. 5 Activities that set `intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK`). So if I could find a way to make that just one implementation would make things a little nicer.


To make things easier and a little neater, I have created companion objects for the `Activities` that hold the following function:


class MyActivity: AppCompatActivity() {
companion object {
fun startActivity(context: Context) {
context.startActivity(
Intent(context, MyActivity::class.java)
)
}
}
...


Other classes can simply call `MyActivity.startActivity(context)`.

The function is pretty basic and the only difference between the implementation in different Activities is obviously the `MyActivity::class.java`-part. So id like to know if its possible to declare this function only ONCE and somehow use it within multiple companion objects for the different activities.

Now, I understand I could do something like this:

I define an object that has a function with a generic type and set it up like this:

object MyObject {
inline fun <reified T: AppCompatActivity>startActivity(context: Context) {
context.startActivity(
Intent(context, T::class.java)
)
}
}

class MyActivity() : AppCompatActivity() {
companion object {
fun start(context: Context) = MyObject.startActivity<MyActivity>(context)
}
}


But this still seems a little hacky. What I&#39;m looking for is something like inheritance or an implemented version of an interface to simply add to my companion object. Something like:

companion object : MyObject<MyActivity>
// Assuming I can somehow put the generic parameter into the object declaration instead of the function or do something similar


or 

companion object {
import MyObject.startActivity<MyActivity>
}


The first option would be especially useful, as it would automatically set up multiple functions of `MyObject` for `MyActivity`. Is something like this even possible?



</details>


# 答案1
**得分**: 1

只需扩展函数。

内联函数 <reified T: AppCompatActivity> Activity.startActivity() {
    startActivity(Intent(this, T::class.java))
}

如果需要额外配置,可以传递 lambda。

内联函数 <reified T: AppCompatActivity> Activity.startActivity(intentConfiguration: Intent.() -> Unit) {
    startActivity(Intent(this, T::class.java).apply(intentConfiguration))
}

<details>
<summary>英文:</summary>

You don&#39;t even need a companion, just an extension function.

    inline fun &lt;reified T: AppCompatActivity&gt; Activity.startActivity() {
        startActivity(Intent(this, T::class.java))
    }

If you need additional configuration, you can pass a lambda. 

    inline fun &lt;reified T: AppCompatActivity&gt; Activity.startActivity(intentConfiguration: Intent.() -&gt; Unit) {
        startActivity(Intent(this, T::class.java).apply(intentConfiguration))
    }


</details>



# 答案2
**得分**: 1

Companion objects can inherit from other classes. Just make a base implementation somewhere:

    伴随对象可以继承自其他类。只需在某处创建基本实现:

abstract class ActivityCompanion&lt;T: Activity&gt;(val activityClass : Class&lt;T&gt;) {
    fun startActivity(context: Context) {
        context.startActivity(Intent(context, activityClass))
    }
    /** rest of functions that reference activityClass **/
}

And inherit it in your companions:

    并在您的伴随对象中继承它:

class MyActivity() : AppCompatActivity() {
    companion object : ActivityCompanion&lt;MyActivity&gt;(MyActivity::class.java)
}
It is a little verbose but that's just how generics work.

这有点冗长,但这就是泛型的工作方式。

<details>
<summary>英文:</summary>

Companion objects can inherit from other classes. Just make a base implementation somewhere:

    abstract class ActivityCompanion&lt;T: Activity&gt;(val activityClass : Class&lt;T&gt;) {
        fun startActivity(context: Context) {
            context.startActivity(Intent(context, activityClass))
        }
        /** rest of functions that reference activityClass **/
    }

And inherit it in your companions:

    class MyActivity() : AppCompatActivity() {
        companion object : ActivityCompanion&lt;MyActivity&gt;(MyActivity::class.java)
    }
It is a little verbose but that&#39;s just how generics work.

</details>



# 答案3
**得分**: 0

只想指出,更简洁的语法是使用`Context`上的一个具体化扩展函数来完成这个操作。而且你也不需要担心伴生对象。

```kotlin
inline fun <reified T: Activity> Context.startActivity() = 
    startActivity(Intent(this, T::class.java))

//用法示例:
someViewOrActivity.startActivity<MyActivity>()

这也在语义上更合理。一个Context启动一个活动。一个Activity不会启动自己。

英文:

Just want to point out that a more concise syntax would be to do this with a reified extension function on Context. And you wouldn't need to worry about companion objects either.

inline fun &lt;reified T: Activity&gt; Context.startActivity() = 
    startActivity(Intent(this, T::class.java))

//Usage:
someViewOrActivity.startActivity&lt;MyActivity&gt;()

It also semantically makes more sense. A Context starts an activity. An Activity doesn't start itself.

huangapple
  • 本文由 发表于 2020年8月12日 20:11:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/63376269.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定