在外部类中声明一个可以多次使用但需要上下文的 Android Kotlin 函数。

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

Android kotlin declare a function in an external class that can be used multiple times but needs a context

问题

I have the following function pinAppWidget which I am using in MainActivity but I would need to be able to use it also in ConfigurableWidgetConfigureActivity to not have a duplicate of the function I would like to create a class that contains them.

但我遇到了一些问题。

原始代码:

    fun pinAppWidget(text: String?) {
        val urlCode = extractLinks(text)
        if (urlCode != "" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val mAppWidgetManager = getSystemService(
                AppWidgetManager::class.java
            )

            if (!mAppWidgetManager.isRequestPinAppWidgetSupported) {
                Toast.makeText(
                    this@MainActivity,
                    "Pin app widget is not supported",
                    Toast.LENGTH_SHORT
                ).show()
                return
            }

            val myProvider = ComponentName(this@MainActivity, MyWidget::class.java)


            val pinnedWidgetCallbackIntent = Intent(this@MainActivity, MyWidget::class.java)
            val successCallback = PendingIntent.getBroadcast(
                this@MainActivity, 0,
                pinnedWidgetCallbackIntent, PendingIntent.FLAG_IMMUTABLE
            )
            mAppWidgetManager.requestPinAppWidget(myProvider, Bundle(), successCallback)
        }
    }

fun extractLinks(text: String?): String {
        val index = text!!.lastIndexOf("/")
        return text.substring(index + 1)
    }

类函数:


import android.app.Activity
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.widget.Toast

class function : Activity() {
    fun pinAppWidget(text: String?) {
        val urlCode = extractLinks(text)
        if (urlCode != "" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val mAppWidgetManager = getSystemService(
                AppWidgetManager::class.java
            )
            if (!mAppWidgetManager.isRequestPinAppWidgetSupported) {
                Toast.makeText(
                    this@function,
                    "Pin app widget is not supported",
                    Toast.LENGTH_SHORT
                ).show()
                return
            }

            val myProvider = ComponentName(this@function, MyWidget::class.java)
            val pinnedWidgetCallbackIntent = Intent(this@function, MyWidget::class.java)
            val successCallback = PendingIntent.getBroadcast(
                this@function, 0,
                pinnedWidgetCallbackIntent, PendingIntent.FLAG_IMMUTABLE
            )
            mAppWidgetManager.requestPinAppWidget(myProvider, Bundle(), successCallback)
        }
    }

    fun extractLinks(text: String?): String {
        val index = text!!.lastIndexOf("/")
        return text.substring(index + 1)
    }

}

当我在MainActivity内部调用函数时,我遇到了以下问题:

在外部类中声明一个可以多次使用但需要上下文的 Android Kotlin 函数。

我该如何做,你能帮我吗?

英文:

I have the following function pinAppWidget which I am using in MainActivity but I would need to be able to use it also in ConfigurableWidgetConfigureActivity to not have a duplicate of the function I would like to create a class that contains them.

But I'm having some problems.

Code original:

    fun pinAppWidget(text: String?) {
        val urlCode = extractLinks(text)
        if (urlCode != "" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val mAppWidgetManager = getSystemService(
                AppWidgetManager::class.java
            )

            if (!mAppWidgetManager.isRequestPinAppWidgetSupported) {
                Toast.makeText(
                    this@MainActivity,
                    "Pin app widget is not supported",
                    Toast.LENGTH_SHORT
                ).show()
                return
            }

            val myProvider = ComponentName(this@MainActivity, MyWidget::class.java)


            val pinnedWidgetCallbackIntent = Intent(this@MainActivity, MyWidget::class.java)
            val successCallback = PendingIntent.getBroadcast(
                this@MainActivity, 0,
                pinnedWidgetCallbackIntent, PendingIntent.FLAG_IMMUTABLE
            )
            mAppWidgetManager.requestPinAppWidget(myProvider, Bundle(), successCallback)
        }
    }

fun extractLinks(text: String?): String {
        val index = text!!.lastIndexOf("/")
        return text.substring(index + 1)
    }

Class function:


import android.app.Activity
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.widget.Toast

class function : Activity() {
    fun pinAppWidget(text: String?) {
        val urlCode = extractLinks(text)
        if (urlCode != "" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val mAppWidgetManager = getSystemService(
                AppWidgetManager::class.java
            )
            if (!mAppWidgetManager.isRequestPinAppWidgetSupported) {
                Toast.makeText(
                    this@function,
                    "Pin app widget is not supported",
                    Toast.LENGTH_SHORT
                ).show()
                return
            }

            val myProvider = ComponentName(this@function, MyWidget::class.java)
            val pinnedWidgetCallbackIntent = Intent(this@function, MyWidget::class.java)
            val successCallback = PendingIntent.getBroadcast(
                this@function, 0,
                pinnedWidgetCallbackIntent, PendingIntent.FLAG_IMMUTABLE
            )
            mAppWidgetManager.requestPinAppWidget(myProvider, Bundle(), successCallback)
        }
    }

    fun extractLinks(text: String?): String {
        val index = text!!.lastIndexOf("/")
        return text.substring(index + 1)
    }

}

When I call inside the MainActivity function I get the following problem:

在外部类中声明一个可以多次使用但需要上下文的 Android Kotlin 函数。

How can I do it, can you help me?

答案1

得分: 1

你可以将 pinAppWidget 方法放入一个对象中,这样你可以在 Activity 中轻松调用它:

object Function {
    fun pinAppWidget(text: String?, activity: Activity) {}
}

另一种方式是,你可以创建一个 BaseActivity 并将 pinAppWidget 放入其中。然后让你的 MainActivity 继承自 BaseActivity,这样你可以在这里轻松调用 pinAppWidget:

open class BaseActivity : AppCompatActivity() {
    fun pinAppWidget() {}
}

class MainActivity : BaseActivity() {
    // 调用 pinAppWidget()
}
英文:

you could put pinAppWidget method into an object, so you can easy call it in both Activity:

class function : Activity() {
    fun pinAppWidget(text: String?){}
}

//convert to
object function {
    fun pinAppWidget(text: String?, activity: Activity){}
}

Another way, you could create BaseActivity and put pinAppWidget into it. Then make your MainActivity extend BaseActivity, you can easy call pinAppWidget from here

class BaseActivity : AppCompatActivity() {
   fun pinAppWidget (){}
}

class MainActivity : BaseActivity() {
   //call pinAppWidget()
}

答案2

得分: 1

你可以将Context对象作为参数传递给function类中的pinAppWidget函数。

import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.widget.Toast

class MyWidgetFunction {
    fun pinAppWidget(context: Context, text: String?) {
        val urlCode = extractLinks(text)
        if (urlCode != "" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val mAppWidgetManager = context.getSystemService(
                AppWidgetManager::class.java
            )
            // 其余部分的代码...
        }
    }

    private fun extractLinks(text: String?): String {
        val index = text!!.lastIndexOf("/")
        return text.substring(index + 1)
    }
}

现在你可以在MainActivityConfigurableWidgetConfigureActivity中都使用MyWidgetFunction类。在调用pinAppWidget函数时,请确保传递适当的Context对象。

MainActivity中:

val myWidgetFunction = MyWidgetFunction()
myWidgetFunction.pinAppWidget(this, text)

ConfigurableWidgetConfigureActivity中:

val myWidgetFunction = MyWidgetFunction()
myWidgetFunction.pinAppWidget(this, text)

注意:请确保用你的小部件类的实际名称替换MyWidget

英文:

You can pass the Context object as a parameter to the pinAppWidget function in the function class.

import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.widget.Toast

class MyWidgetFunction {
    fun pinAppWidget(context: Context, text: String?) {
        val urlCode = extractLinks(text)
        if (urlCode != "" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val mAppWidgetManager = context.getSystemService(
                AppWidgetManager::class.java
            )
            // Rest of your code...
        }
    }

    private fun extractLinks(text: String?): String {
        val index = text!!.lastIndexOf("/")
        return text.substring(index + 1)
    }
}

Now you can use the MyWidgetFunction class in both MainActivity and ConfigurableWidgetConfigureActivity. When calling the pinAppWidget function, make sure to pass the appropriate Context object.

In MainActivity:

val myWidgetFunction = MyWidgetFunction()
myWidgetFunction.pinAppWidget(this, text)

In ConfigurableWidgetConfigureActivity:

val myWidgetFunction = MyWidgetFunction()
myWidgetFunction.pinAppWidget(this, text)

Note: Make sure to replace MyWidget with the actual name of your widget class.

答案3

得分: 0

这个问题涉及至少两个方面:架构决策和Android平台的限制。

从软件架构角度看,你可以:

  • 创建一个共同的父类,将这部分和其他共同逻辑放在其中;其他活动将扩展这个类并继承其行为。
  • 创建实用类来封装共同逻辑,并在每个活动中实例化这个类。
  • 内部类(在kotlin中称为object:)可以是这两个选项的替代方法。
  • kotlin还提供了扩展函数这样的东西,这可能是实现你的任务的第四种方式。

从Android平台的角度看,组件代码应该只能从组件(Activity、Service、BroadcastReceiver、ContentProvider)中调用。你的函数使用了组件代码(mAppWidgetManager.requestPinAppWidget(...)),最好将其保留在组件内部,不要放在外部。尽管如此,仍然可以将其放入一个单独的类中,并传递一个context来运行这段代码。

英文:

This questions covers at least two things: architecture decision and android platform limitations.

From software architecture perspective you could:

  • create a common parent class and put this and the rest common logic inside; other activities will extend this class and inherit its behaviour.
  • create utility class to encapsulate common logic and instantiate this class within each activity.
  • inner classes (aka object: in kotlin) could be an alternative to this two options.
  • kotlin also provide such things as extensions which could a fourth way to achieve your task.

From Android platform perspective component code should be called only from component (Activity, Service, BroadcastReceiver, ContentProvder). Your function uses component code (mAppWidgetManager.requestPinAppWidget(...)) and it would be good to keep it within component and do not put outside. Although, it is still possible to put it into a separate class and pass a context to run this code.

huangapple
  • 本文由 发表于 2023年5月17日 16:13:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76269902.html
匿名

发表评论

匿名网友

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

确定