在颤振插件中获取活动参考
Posted
技术标签:
【中文标题】在颤振插件中获取活动参考【英文标题】:Get activity reference in flutter plugin 【发布时间】:2020-05-10 06:38:23 【问题描述】:我在创建flutter插件时,插件类默认有两个方法:
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding)
和
fun registerWith(registrar: Registrar)
文件上的评论说:
It is encouraged to share logic between onAttachedToEngine and registerWith to keep them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called depending on the user's project. onAttachedToEngine or registerWith must both be defined in the same class.
现在,我需要从这里开始另一个活动,activity.startActivityForResult()
。
可以使用registrar.activity()
获得对registerWith(registrar: Registrar)
中活动的引用。如何在方法onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding)
中做到这一点?
【问题讨论】:
【参考方案1】:通过实现 ActivityAware 接口
https://www.codenong.com/jseb7df49fdfb1/
package com.example.fluttertoast
import android.app.Activity
import android.content.Context
import android.widget.Toast
import androidx.annotation.NonNull;
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry.Registrar
/** FluttertoastPlugin */
class FluttertoastPlugin: FlutterPlugin, MethodCallHandler, ActivityAware
private lateinit var channel : MethodChannel
private lateinit var activity:Activity
private lateinit var context: Context
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding)
channel = MethodChannel(flutterPluginBinding.flutterEngine.dartExecutor, "fluttertoast")
channel.setMethodCallHandler(this)
this.context = flutterPluginBinding.applicationContext
companion object
@JvmStatic
fun registerWith(registrar: Registrar)
val channel = MethodChannel(registrar.messenger(), "fluttertoast")
channel.setMethodCallHandler(FluttertoastPlugin())
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result)
if (call.method == "getPlatformVersion")
Toast.makeText(activity,"Hello!",Toast.LENGTH_SHORT).show()
result.success("Android $android.os.Build.VERSION.RELEASE")
else
result.notImplemented()
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding)
channel.setMethodCallHandler(null)
override fun onDetachedFromActivity()
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding)
onAttachedToActivity(binding)
override fun onAttachedToActivity(binding: ActivityPluginBinding)
this.activity = binding.activity
override fun onDetachedFromActivityForConfigChanges()
【讨论】:
【参考方案2】:注意:
您可以通过实现 ActivityAware 接口来获取对活动的引用但是如果您在 onAttachToEngine()
方法中 setMethodCallHandler(...)
将永远不会调用 onAttachToActivity()
并且您将永远无法访问活动
看看下面的例子
什么不起作用:
在下面的例子中,onAttachToActivity()
永远不会被调用
class AndroidLongTaskPlugin : FlutterPlugin, ActivityAware
private var activity: FlutterActivity? = null
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding)
//activity is null here
//also onAttachToActivity will never be called because we are calling setMethodHandler here
channel = MethodChannel(binaryMessenger, CHANNEL_NAME)
channel.setMethodCallHandler call, result ->
//our code
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding)
channel?.setMethodCallHandler(null)
override fun onAttachedToActivity(binding: ActivityPluginBinding)
activity = binding.activity as FlutterActivity
//rest of the methods
这是一个工作示例:
class MyPlugin : FlutterPlugin, ActivityAware
private var activity: FlutterActivity? = null
private var binaryMessenger: BinaryMessenger? = null
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding)
binaryMessenger = flutterPluginBinding.binaryMessenger
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding)
Log.d("DART/NATIVE", "onDetachedFromEngine")
channel?.setMethodCallHandler(null)
override fun onAttachedToActivity(binding: ActivityPluginBinding)
Log.d("DART/NATIVE", "onAttachedToActivity")
activity = binding.activity as FlutterActivity
//here we have access to activity
//also make sure to setMethodCallHandler here
channel.setMethodCallHandler call, result ->
//our code
//rest of the methods
【讨论】:
@Alexufo。看看这个库pub.dev/packages/android_long_task 你知道我可以在哪里附加 startActivityForResult 吗?我想打开新活动。 我找到了解决方案bitbucket.org/prathap_kumar/mvbarcodescan/raw/… 在我的情况下onAttachedToEngine
这个代码工作 MethodChannel channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), channelName); channel.setMethodCallHandler(this);
而在 onAttachedToActivity
我使用 activity = activityPluginBinding.getActivity(); activityPluginBinding.addActivityResultListener(this);
【参考方案3】:
找到解决方案here。
实现ActivityAware
,其方法之一是
override fun onAttachedToActivity(binding: ActivityPluginBinding)
this.activity = binding.activity;
【讨论】:
@Neeraj,我尝试了上述解决方案,但令人惊讶的是,在方法调用中,活动为空。我在 AttachedToActivity 回调中分配了活动,并且在立即 onMethodCall 之后,this.activity 为空。有什么建议吗? 阅读更多the documentation @Satya Attili 我也有同样的问题。你找到解决办法了吗? 您在什么条件下尝试@SatyaAttili?如果您在 Service 或静态广播接收器中使用后台消息处理程序,则尚未创建 Activity,因此从未调用过onAttachedToActivity
。所以this.activity
将为空。以上是关于在颤振插件中获取活动参考的主要内容,如果未能解决你的问题,请参考以下文章