【问题标题】:Android Kotlin call a function in other activityAndroid Kotlin 在其他活动中调用函数
【发布时间】:2018-11-21 21:07:28
【问题描述】:

我在其他Activity中调用了MainActivity的一个函数,应用关闭并显示如下错误,请帮忙解决这个问题。

MainActivity 函数:

fun checkInternet():Boolean {
    val cm = baseContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val networkInfo = cm.activeNetworkInfo
    if (networkInfo != null && networkInfo.isConnected) {

        alertPopUp("internet ok", "")
        return true
    }
    else {
        val title = getString(R.string.No_Internet)
        val message = getString(R.string.need_internet_for_service)
        alertPopUp(title, message)

        return false
    }

}

在其他活动中调用此函数:

var internetStatus:Boolean = MainActivity().checkInternet()

错误信息:

原因:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“java.lang.Object android.content.Context.getSystemService(java.lang.String)” 在 com.gph.qpon.MainActivity.checkInternet(MainActivity.kt:148) 在 com.gph.qpon.qponClickedActivity.onCreate(qponClickedActivity.kt:32)

【问题讨论】:

  • 只是为了确定 - 您是直接通过构造函数创建 Activity 吗?
  • 正在出于任何未知原因直接使用构造函数创建他的 Activity

标签: android function android-activity kotlin


【解决方案1】:

我宁愿将所有逻辑提取到不同的帮助程序或实用程序类。如果您要重用它,那么将它包含在活动中是一个很大的错误。一个非常简洁的解决方案可能是拥有一个类似于著名的iosched project hasConnectivityUtils 实用程序类,只需将应用程序上下文传递给它:

/**
 * Utility methods for dealing with connectivity
 */
object ConnectivityUtils {
  fun isConnected(context: Context): Boolean {
    val connectivityManager = context.applicationContext.getSystemService(
        Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val activeNetworkInfo = connectivityManager.activeNetworkInfo
    return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting
  }
}

然后,您只需要在这样的任何活动中调用它:

ConnectivityUtils.isConnected(this)

【讨论】:

  • 谢谢!我认为我们的方法是最好的。我想在 Mainactivity 的片段中使用 ConnectivityUtils.isConnected(this)。我应该为 ConnectivityUtils.isConnected(______) 写什么?
  • Fragments 有一个方法来获取它们关联的 Activity。但是,在调用该方法之前确保活动不为空,或者只调用 ConnectivityUtils.isConnected(activity!!) --> 在 Java 中它是一个名为 getActivity() 的 getter 方法
  • 非常感谢!我测试代码 ConnectivityUtils.isConnected(activity!!) 和 ConnectivityUtils.isConnected(this.context!!) 也很好用。能否请您告诉我活动之间的区别!还有this.context!!?
  • 一个 Activity 从一个 Context 扩展而来,但是你可以毫无问题地使用它们中的任何一个。也许我会去寻找上下文。片段可以托管在任何对象中,Android 将这些对象称为“主机”。它们必须从FragmentHostCallback 抽象类扩展而来,该抽象类具有“getActivity()”和getContext() 等方法。所以这些方法只返回主机对象的ActivityContext(如果它们分配了一个)。来源:android.googlesource.com/platform/frameworks/support/+/refs/…
【解决方案2】:

您应该拥有 MainActivity 的上下文而不是创建一个新的,或者您也可以在您的 checkInternet() 方法中传递一个上下文,以便它可以在其他 Activity 中获取上下文。我修改了下面的代码。

companion object {
    fun checkInternet(context: Context):Boolean {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val networkInfo = cm.activeNetworkInfo
        if (networkInfo != null && networkInfo.isConnected) {

            // alertPopUp("internet ok", "")
            return true
        }
        else {
            val title = "no Internet"
            val message = "Need Internet Service"
            // alertPopUp(title, message)

            return false
        }

    }
}

在上面的代码中,我已经将 baseContext 替换为我在方法的构造函数中传递的上下文。同样从调用 checkInternet 的其他活动中,我发送了该活动的上下文。代码如下。

MainActivity.checkInternet(this)

希望对您有所帮助。

【讨论】:

  • MainActivity() 没有。不好
  • @TimCastelijns 我知道为什么我提到你应该有主活动的上下文。但我也认为静态方法可以完成这项工作?另外,您也可以分享一下您对此的看法吗?这会很有帮助。
  • 这不是静态方法。 Kotlin 甚至没有静态方法。您正在使用 () 初始化一个活动,这很糟糕
  • @TimCastelijns 我的意思是通过伴随对象。是的,这不是通过这个。但我也为它编写了代码。
  • 所以我使用了 () - 是的,这就是问题所在。删除它,不要建议人们这样做。你永远不应该通过调用构造函数来手动实例化一个活动
【解决方案3】:

首先,不要由构造函数直接创建活动。 Activity 有自己的生命周期,由操作系统管理。初始化 Activity 的唯一正确方法是使用 Intent(但我想这不是您想要做的)。

另外,不要尝试将 Activity 保留在任何字段中(这会导致内存泄漏)。 如果我要提出一个解决方案,我会建议使用扩展功能(因为您可以检查任何 Context 类中的连接,而不仅仅是那个):

fun Context.checkInternet() {
   /* your code here, to use context use this */
   val cm = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
   /* some code here */
}

当您声明此函数时,您可以在任何上下文类中使用它(如 Activity、Fragment 等 - 它们是上下文的子类型)。那么,如何使用呢?

class MyActivity(): Activity() {
    fun foo() {
        this.checkInternet()
    }
} 

【讨论】:

    猜你喜欢
    • 2020-10-02
    • 2011-02-17
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 2016-08-29
    • 1970-01-01
    相关资源
    最近更新 更多