英文:
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'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't even need a companion, just an extension function.
inline fun <reified T: AppCompatActivity> Activity.startActivity() {
startActivity(Intent(this, T::class.java))
}
If you need additional configuration, you can pass a lambda.
inline fun <reified T: AppCompatActivity> Activity.startActivity(intentConfiguration: Intent.() -> 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<T: Activity>(val activityClass : Class<T>) {
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<MyActivity>(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<T: Activity>(val activityClass : Class<T>) {
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<MyActivity>(MyActivity::class.java)
}
It is a little verbose but that'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 <reified T: Activity> Context.startActivity() =
startActivity(Intent(this, T::class.java))
//Usage:
someViewOrActivity.startActivity<MyActivity>()
It also semantically makes more sense. A Context starts an activity. An Activity doesn't start itself.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论