英文:
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. kotlinalso 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。



评论