gpt4 book ai didi

android - 如何将 StreamHandler 与无法访问的对象的监听器连接起来?

转载 作者:IT王子 更新时间:2023-10-29 06:50:13 24 4
gpt4 key购买 nike

我正在编写一个 GeoFire 插件,我试图让 Dart 代码中的查询监听器可用,但没有成功。我似乎无法弄清楚如何为 EventChannel 设置 StreamHandler。要了解我的挣扎,您需要看一下我如何创建查询。
这是相关代码:

if (call.method.equals("addGeoQueryEventListener")) {
String refPath = call.argument("refPath");
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref = refPath != null ? ref.child(refPath) : ref;
GeoFire geofire = new GeoFire(ref);
List<Double> center = call.argument("center");
double radius = call.argument("radius");
GeoQuery query = geofire.queryAtLocation(new GeoLocation(center.get(0), center.get(1)), radius);
query.addGeoQueryEventListener(new GeoQueryEventListener() {
@Override
public void onKeyEntered(String key, GeoLocation location) {
System.out.println("entered");
}

@Override
public void onKeyExited(String key) {
System.out.println("exited");
}

@Override
public void onKeyMoved(String key, GeoLocation location) {
System.out.println("moved");
}

@Override
public void onGeoQueryReady() {

}

@Override
public void onGeoQueryError(DatabaseError error) {
System.out.println(error.getMessage());
}
});
}

每次调用 addGeoQueryEventListener 时,我都会创建一个全新的 DatabaseReference,就像在 FlutterFire 插件中所做的那样。我做同样的事情来创建查询。这意味着在此 if 语句 之外没有查询的引用。

所以我创建了一个 EventChannel 来从 onKeyEntered 事件中获取数据。

final EventChannel geoQueryKeyEnteredEventChannel = new EventChannel(registrar.messenger(), "com.bram.vanbilsen.geofire.keyEnteredChannel");  

之后,我尝试为该 channel 设置 StreamHandler:

geoQueryKeyEnteredEventChannel.setStreamHandler(new StreamHandler() {
@Override
public void onListen(Object o, EventSink eventSink) {

}

@Override
public void onCancel(Object o) {

}
});

我如何知道将此 StreamHandler 与我在 addGeoQueryEventListener 中创建的查询监听器连接起来?

---- 编辑 ----
这是我的 registerWith 方法,所有设置都带有一个 MethodChannel:

public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "com.bram.vanbilsen.geofire.GeoFire");
final GeofirePlugin instance = new GeofirePlugin(registrar.activity(), channel);
channel.setMethodCallHandler(instance);
}

这是调用适当方法的更新代码:

if (call.method.equals("addGeoQueryEventListener")) {
String refPath = call.argument("refPath");
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref = refPath != null ? ref.child(refPath) : ref;
final GeoFire geofire = new GeoFire(ref);
List<Double> center = call.argument("center");
double radius = call.argument("radius");
GeoQuery query = geofire.queryAtLocation(new GeoLocation(center.get(0), center.get(1)), radius);
query.addGeoQueryEventListener(new GeoQueryEventListener() {
@Override
public void onKeyEntered(String key, GeoLocation location) {
HashMap<String, HashMap<String, ArrayList<Double>>> arguments = new HashMap<>();
HashMap<String, ArrayList<Double>> result = new HashMap<>();
ArrayList<Double> geoLocation = convertGeoLocation(location);
result.put(key, geoLocation);
arguments.put("result", result);
channel.invokeMethod("geoQueryEventKeyEntered", arguments);
}

@Override
public void onKeyExited(String key) {
HashMap<String, String> arguments = new HashMap<>();
arguments.put("result", key);
channel.invokeMethod("geoQueryEventKeyExited", arguments);
}

@Override
public void onKeyMoved(String key, GeoLocation location) {
HashMap<String, HashMap<String, ArrayList<Double>>> arguments = new HashMap<>();
HashMap<String, ArrayList<Double>> result = new HashMap<>();
ArrayList<Double> geoLocation = convertGeoLocation(location);
result.put(key, geoLocation);
arguments.put("result", result);
channel.invokeMethod("geoQueryEventKeyMoved", arguments);
}

@Override
public void onGeoQueryReady() {
HashMap<String, String> arguments = new HashMap<>();
arguments.put("result", "success");
channel.invokeMethod("geoQueryEventReady", arguments);
}

@Override
public void onGeoQueryError(DatabaseError error) {
HashMap<String, HashMap> arguments = new HashMap<>();
HashMap<String, String> databaseError = new HashMap<>();
databaseError.put("code", Integer.toString(error.getCode()));
databaseError.put("details", error.getMessage());
databaseError.put("message", error.getMessage());
arguments.put("result", databaseError);
channel.invokeMethod("geoQueryEventError", arguments);
}
});
} else if ( (call.method.equals("geoQueryEventKeyEntered")) || (call.method.equals("geoQueryEventKeyExited")) ||
(call.method.equals("geoQueryEventKeyMoved")) || (call.method.equals("geoQueryEventReady")) || (call.method.equals("geoQueryEventError")) ) {
result.success(call.argument("result"));
}

我现在如何在我的 Dart 代码中监听函数结果?我是否在孤独的 MethodChannel 上使用了 setMethodCallHandler?如果是这样,当我必须使用该 channel 来调用与我的监听器无关的方法时,会不会出现问题?

最佳答案

您应该通过 MethodChannel 上的方法调用来完成所有事情,在每个 GeoFire 事件上以 Java 向 Dart 方向发出方法调用,或者使用 EventChannel 来完成所有事情,基本上将 if 语句的代码移动到 StreamHandlerlisten 方法中。

使用MethodChannel:

在 Java 方面:

MethodCallChannel myChannel = new MethodCallChannel(messenger, "geofire");
myChannel.setMethodCallHandler(new MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("addGeoQueryEventListener")) {
// ... setup query using call.arguments
query.addGeoQueryEventListener(new GeoQueryEventListener() {
@Override
public void onKeyEntered(String key, GeoLocation location) {
Map<String, Object> event = // ... extract info from key,location
myChannel.invokeMethod("onKeyEntered", event);
}

@Override
public void onKeyExited(String key) {
myChannel.invokeMethod("onKeyExited", key);
}
// ... other GeoQueryEventListener handlers.
});
result.success(null);
} else {
result.notImplemented();
}
}
});

在 Dart 方面:

const myChannel = const MethodChannel('geofire');

myChannel.setMethodCallHandler((MethodCall call) {
switch (call.method) {
case 'onKeyEntered':
// ... extract event data from call.arguments
return null;
case 'onKeyExited':
// ... extract event data from call.arguments
return null;
// ... other methods
default: throw new MissingPluginException();
}
});
myChannel.invokeMethod('addGeoQueryEventListener', someArguments);

上面的代码使用相同的 channel 进行双向通信。从 Dart 调用 invokeMethod 调用 Java MethodCallHandler,而从 Java 调用 invokeMethod 调用 Dart 处理程序。

另一种选择是使用两个不同的 channel ,一个用于 Dart->Java 通信以请求设置 GeoFire 监听器,另一个用于 Java->Dart 通信以发送事件。

最佳选择可能取决于您是否对该 channel 有其他用途。我会为不同的目的使用不同的 channel ,因此单个 channel 上的所有通信都以某种方式相关。 channel 非常轻巧;他们只承载着他们名字的重量。

使用EventChannel:

在 Java 方面:

final EventChannel myChannel = new EventChannel(messenger, "geofire");
myChannel.setStreamHandler(new StreamHandler() {
private GeoQuery query;
private GeoQueryEventListener listener;

@Override
public void onListen(Object arguments, EventSink eventSink) {
query = // ... setup query using arguments
listener = new GeoQueryEventListener() {
@Override
public void onKeyEntered(String key, GeoLocation location) {
Map<String, Object> event = // ... create key entered event
eventSink.success(event);
}

@Override
public void onKeyExited(String key) {
Map<String, Object> event = // ... create key exited event
eventSink.success(event);
}
// ... other GeoQueryEventListener handlers.
}
query.addGeoQueryEventListener(listener);
}

@Override
public void onCancel(Object args) {
query.removeGeoQueryEventListener(listener);
}
});

在 Dart 方面:

const myChannel = const EventChannel('geofire');
myChannel.receiveBroadcastStream(someArguments).listen((event) {
// handle event
});

关于android - 如何将 StreamHandler 与无法访问的对象的监听器连接起来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46321507/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com