【问题标题】:How to pass an interface using intent如何使用意图传递接口
【发布时间】:2020-09-30 19:13:10
【问题描述】:

这是我的接口类

interface InstallerInterface {
     fun onInstallation(context: Context)
}

我在这个类中实现了接口

class FirstActivity : InstallerInterface{
    override fun onInstallation(context: Context) {
         *MyCode*
    }
}

我尝试使用意图传递此上下文

 val intent=Intent(context,SecondActivity::class.java)
        intent.putExtra("NAME",name)
        intent.putExtra("Callback",Interface)
        context.startActivity(intent)    

但是 intent.putExtra 导致了错误 Cannot resolve method 'putExtra() 。所以我在FirstActivity() 类中实现了Serializable。但这导致了错误

06-11 12:28:57.323  4042  4042 E AndroidRuntime: java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = FirstAcitvity)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.os.Parcel.writeSerializable(Parcel.java:1535)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.os.Parcel.writeValue(Parcel.java:1483)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.os.Parcel.writeArrayMapInternal(Parcel.java:732)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1417)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.os.Bundle.writeToParcel(Bundle.java:1157)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.os.Parcel.writeBundle(Parcel.java:772)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.content.Intent.writeToParcel(Intent.java:8703)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3082)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1520)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.app.Activity.startActivityForResult(Activity.java:4229)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:676)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.app.Activity.startActivityForResult(Activity.java:4187)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:663)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.app.Activity.startActivity(Activity.java:4526)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.app.Activity.startActivity(Activity.java:4494)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at foundation.e.apps.XAPK.LaunchUtils.startInstallSplitApksActivity(LaunchUtils.kt:15)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at foundation.e.apps.XAPK.ViewUtils$installXApk$1.onCompedApks(ViewUtils.kt:57)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at foundation.e.apps.XAPK.XApkInstallUtils$installSplitApks$2.run(XApkInstallUtils.kt:191)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.os.Handler.handleCallback(Handler.java:751)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:95)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:154)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:6186)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
06-11 12:28:57.323  4042  4042 E AndroidRuntime: Caused by: java.io.NotSerializableException: ThirdAcivity()
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1224)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1584)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1549)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1472)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1218)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
06-11 12:28:57.323  4042  4042 E AndroidRuntime:        at android.os.Parcel.writeSerializable(Parcel.java:1530)
06-11 12:28:57.323  4042

我相信ThirdActivity() 实现了FirstActivity(),而我没有在ThirdAcivity 中实现Serializable。所以我在 ThirdAcitivity 中实现了 Serializable 。而且我在每个使用FirstAcivity 的活动上都遇到了错误。这是一个大型项目,我无法在每个 Acitivity 上实施 Serializable。 所以我改为实现Parcelable。我的代码是

@Parcelize
class FirstActivity : InstallerInterface, Parcelable{
    override fun onInstallation(context: Context) {
         *MyCode*
    }
}

我得到了像java.lang.RuntimeException: Parcel: unable to marshal value这样的错误 我该如何修复此代码。如果没有,还有什么更好的选择。提前谢谢你

【问题讨论】:

  • 为什么要将接口传递给另一个类?你能补充更多细节吗?
  • 我想您想使用 SecondActivity 中的 FirstActivity 中实现的接口来监听事件?如果是这种情况,请尝试使用 startActivityForResult 方法。您甚至可以将其链接到第 3 次活动到第 1 次活动developer.android.com/training/basics/intents/result
  • 如果你想在非活动类中使用上下文,那么你可以试试这个答案stackoverflow.com/questions/17917968/…
  • 我想从SecondActivity调用FirstActivity()的接口函数onInstallation()。喜欢callback.onInstallation。我无法使用intent.putExtra 将接口传递给SecondActivity。主要思想是获取接口类的上下文
  • gitlab.e.foundation/DayonaJ/apps/-/commit/…。这就是我正在做的事情。我想从InstallSplitApksActivity.kt调用Application.kt类的onInstalationComplete()(这是InstallerInterface.kt方法)

标签: android kotlin android-intent parcelable serializable


【解决方案1】:

您的活动不应实施Parcelable/Serializable。传递活动引用也可能导致内存泄漏和应用程序崩溃(https://proandroiddev.com/everything-you-need-to-know-about-memory-leaks-in-android-d7a59faaf46ahttps://techbeacon.com/app-dev-testing/what-you-need-know-about-android-app-memory-leaks

如果您想在另一个活动中做某事并将结果返回到第一个活动,您可以使用startActivityForResult 或新的Activity Result APIs。更多信息https://developer.android.com/training/basics/intents/result

【讨论】:

  • 我不想从活动中返回结果。我只想知道活动什么时候结束。我试过 startActivityForResult 。但是onActivityResult 没有被调用。
  • 这是我的代码。 ``` fun startInstallSplitApksActivity(context: Activity, apksBean: ApksBean, callback:InstallerInterface) { val intent =installSplitApksActivity.newInstanceIntent(context, apksBean, callback) context.startActivityForResult(intent, 1) } override fun onActivityResult(requestCode: Int, resultCode : Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode==1) { if (resultCode == Activity.RESULT_OK) { myCode() } } } ``
  • I just want to know when activity ends - 我认为活动结束的事件是某种结果。您的带有startActivityForResult 的代码看起来不错,但不要忘记在调用finish() 之前在InstallActivity 中调用setResult()
  • 是的,添加了setResult()。但是覆盖nextStep() 来自另一个类-BaseActivity()。这是问题吗? override fun nextStep() { super.nextStep() apksBean = intent.getParcelableExtra(KEY_PARAM) if (apksBean == null || apksBean!!.splitApkPaths.isNullOrEmpty()){ val intent = Intent() setResult(Activity.RESULT_OK) finish() }abstract class BaseActivity : RxAppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) nextStep() }
【解决方案2】:

您不能“传递接口”。 “接口”是一个抽象的东西。您要传递的是该接口的具体实现,即:一个对象(恰好实现您的接口)。当您实例化您的“接口”时(在您的示例中,如下所示:

intent.putExtra("testInterface", new ITest() {
    @Override 
    void onSuccess(String text) {
    }
}

但是,即使您这样做了,也无法解决您的问题。您需要了解的是,您不能通过将对象(实例)作为 Intent 中的“附加项”来传递对象(实例)。当你这样做时,Android 实际上会序列化然后反序列化对象,这样你最终会得到 2 个对象,一个是原始对象的序列化/反序列化副本。

For more Details:->

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    • 2017-03-11
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    相关资源
    最近更新 更多