英文:
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
内部调用函数时,我遇到了以下问题:
我该如何做,你能帮我吗?
英文:
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:
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)
}
}
现在你可以在MainActivity
和ConfigurableWidgetConfigureActivity
中都使用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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论