在 flutter 插件中获取 activity 引用
Get activity reference in flutter plugin
我在创建flutter插件的时候,插件里默认有两个方法class:
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,activity.startActivityForResult()
。
可以使用 registrar.activity()
在 registerWith(registrar: Registrar)
中获取对 activity 的引用。我如何在方法 onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding)
中执行此操作?
找到解决方案here。
实施 ActivityAware
其方法之一是
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
this.activity = binding.activity;
}
注:
您可以通过实现 ActivityAware 接口获得对 activity 的引用 但是 如果您 setMethodCallHandler(...)
在 onAttachToEngine()
方法中 onAttachToActivity()
将永远不会被调用,您永远无法访问 activity
看看下面的例子
什么不起作用:
在下面的例子中 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
}
通过实现 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() {}
}
在我的例子中,alireza-easazade 的分辨率不起作用。我从 onAttachedToEngine
中删除了 MethodChannel
创建,但 ActivityAware
通知仍然没有出现。对我有用的是用 flutterPluginBinding.getFlutterEngine().getDartExecutor()
替换 flutterPluginBinding.getBinaryMessenger()
作为 MethodChannel
构造函数中的参数。一旦我这样做 onAttachedToActivity
在 onAttachedToEngine
.
之后立即被调用
这是我的工作示例:
public class MyPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
private ActivityPluginBinding _activityBinding;
private FlutterPluginBinding _flutterBinding;
private MethodChannel _channel;
// FlutterPlugin overrides
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
_flutterBinding = flutterPluginBinding;
_channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "com.example.test/myplugin");
_channel.setMethodCallHandler(this);
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
_channel.setMethodCallHandler(null);
_channel = null;
_flutterBinding = null;
}
// ActivityAware overrides
@Override
public void onAttachedToActivity(ActivityPluginBinding binding) {
_activityBinding = binding;
}
@Override
public void onDetachedFromActivity() {
_activityBinding = null;
}
@Override
public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) {
_activityBinding = binding;
}
@Override
public void onDetachedFromActivityForConfigChanges() {
_activityBinding = null;
}
// MethodCallHandler overrides
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
// Handle calls
}
// Implementation
public Context getApplicationContext() {
return (_flutterBinding != null) ? _flutterBinding.getApplicationContext() : null;
}
public Activity getActivity() {
return (_activityBinding != null) ? _activityBinding.getActivity() : null;
}
}
我在创建flutter插件的时候,插件里默认有两个方法class:
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,activity.startActivityForResult()
。
可以使用 registrar.activity()
在 registerWith(registrar: Registrar)
中获取对 activity 的引用。我如何在方法 onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding)
中执行此操作?
找到解决方案here。
实施 ActivityAware
其方法之一是
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
this.activity = binding.activity;
}
注:
您可以通过实现 ActivityAware 接口获得对 activity 的引用 但是 如果您 setMethodCallHandler(...)
在 onAttachToEngine()
方法中 onAttachToActivity()
将永远不会被调用,您永远无法访问 activity
看看下面的例子
什么不起作用:
在下面的例子中 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
}
通过实现 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() {}
}
在我的例子中,alireza-easazade 的分辨率不起作用。我从 onAttachedToEngine
中删除了 MethodChannel
创建,但 ActivityAware
通知仍然没有出现。对我有用的是用 flutterPluginBinding.getFlutterEngine().getDartExecutor()
替换 flutterPluginBinding.getBinaryMessenger()
作为 MethodChannel
构造函数中的参数。一旦我这样做 onAttachedToActivity
在 onAttachedToEngine
.
这是我的工作示例:
public class MyPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
private ActivityPluginBinding _activityBinding;
private FlutterPluginBinding _flutterBinding;
private MethodChannel _channel;
// FlutterPlugin overrides
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
_flutterBinding = flutterPluginBinding;
_channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "com.example.test/myplugin");
_channel.setMethodCallHandler(this);
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
_channel.setMethodCallHandler(null);
_channel = null;
_flutterBinding = null;
}
// ActivityAware overrides
@Override
public void onAttachedToActivity(ActivityPluginBinding binding) {
_activityBinding = binding;
}
@Override
public void onDetachedFromActivity() {
_activityBinding = null;
}
@Override
public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) {
_activityBinding = binding;
}
@Override
public void onDetachedFromActivityForConfigChanges() {
_activityBinding = null;
}
// MethodCallHandler overrides
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
// Handle calls
}
// Implementation
public Context getApplicationContext() {
return (_flutterBinding != null) ? _flutterBinding.getApplicationContext() : null;
}
public Activity getActivity() {
return (_activityBinding != null) ? _activityBinding.getActivity() : null;
}
}