11

在我创建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(). registerWith(registrar: Registrar)在using中可以获得对活动的引用registrar.activity()。我怎样才能在方法中做到这一点onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding)

4

4 回答 4

15

在这里找到了解决方案。
实施ActivityAware,其方法之一是

 override fun onAttachedToActivity(binding: ActivityPluginBinding) {
    this.activity = binding.activity;
  }
于 2020-01-25T18:27:05.737 回答
4

笔记:

您可以通过实现 ActivityAware 接口来获取对活动的引用,但是如果您setMethodCallHandler(...)onAttachToEngine()方法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
}


于 2021-02-18T21:57:45.853 回答
0

通过实现 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() {}
}
于 2021-10-28T08:51:17.380 回答
0

就我而言,alireza-easazade的解决方案不起作用。我从中删除了MethodChannel创作,onAttachedToEngineActivityAware仍然没有收到通知。对我有用的是替换flutterPluginBinding.getBinaryMessenger()为构造函数flutterPluginBinding.getFlutterEngine().getDartExecutor()中的参数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;
  }
}
于 2022-02-01T07:54:57.187 回答