RxReader / tencent_kit

Flutter版QQ登录/分享
MIT License
235 stars 63 forks source link

Flutter 插件升级v2后 收到两次回调 #24

Closed AlexV525 closed 4 years ago

AlexV525 commented 4 years ago

调用任何行为,均回调两次。Demo未出现问题,但我需要作为单例或者从provider提供,烦请指教。 部分代码: 封装的Provider:

class TencentKitProvider extends ChangeNotifier {
  Tencent _tencent;
  Tencent get tencent => _tencent;

  StreamSubscription<TencentLoginResp> tencentLoginResponses;

  TencentLoginResp tencentLoginResponse;

  ObserverList<Function> tencentLoginListeners = ObserverList<Function>();

  void initClient() {
    print("initClient");
    _tencent = Tencent()..registerApp(appId: '222222');

    tencentLoginResponses = _tencent.loginResp().listen((data) {
      print("triggered observers");
      for (final observer in tencentLoginListeners) observer(data);
    });
  }

  void addDefaultListeners() {
    tencentLoginListeners.add(tencentListenLogin);
  }

  void tencentListenLogin(TencentLoginResp resp) {
    tencentLoginResponse = resp;
    String content = 'OpenId: ${resp.openid} AccessToken: ${resp.accessToken}';
    debugPrint('QQ登录 $content');
  }

  void tencentLogin() {
    tencent.login(scope: [TencentScope.GET_SIMPLE_USERINFO]);
  }
}

结果:

I/flutter (22788): initClient
I/flutter (22788): triggered observers
I/flutter (22788): QQ登录 OpenId: xxx AccessToken: xxx
I/flutter (22788): triggered observers
I/flutter (22788): QQ登录 OpenId: xxx AccessToken: xxx
AlexV525 commented 4 years ago

仅一次注册,能两次回调,人晕了...写了个demo又没出现这个问题 老哥有QQ可以进一步沟通吗?通过邮箱查找不到 😃

AlexV525 commented 4 years ago

方法log后发现在handler位置返回了两次 image

SpanishOnion commented 4 years ago

遇到相同的问题,fake_weibo也有此问题,微信没发现此问题。

Kingtous commented 4 years ago

遇到相同的问题

droplet-js commented 4 years ago
  1. flutter --version
  2. example 有没有重现?没有重现的话,请提供Demo
AlexV525 commented 4 years ago
  1. flutter --version

Flutter 1.12.13+hotfix.5 • channel stable • https://github.com/flutter/flutter.git Framework • revision f4283abcb7 (3 weeks ago) • 2019-12-19 09:28:48 +0800 Engine • revision 2994f7e1e6 Tools • Dart 2.7.0

  1. example 有没有重现?没有重现的话,请提供Demo

demo晚些提供。

AlexV525 commented 4 years ago

根据目前的改写,没有发现何原因导致,但各项注册行为(包括registerApp, listen)都只调用了一次。

与@SpanishOnion 共同排查了一会儿,两个人各自的项目,example没问题,项目代码拿到example里没问题。反过来example代码拿到项目里有问题,项目代码也有问题。只在handler位置回调两次。

项目共同点:同时使用tencent和wechat。

droplet-js commented 4 years ago

不好排查啊,没有实际环境。冷启是否有问题,我担心 hot reload 引发 Android/iOS 层对象创建两遍

AlexV525 commented 4 years ago

确实不好排查,冷启动热重载热重启都是一样的行为...现在只能自己节流

Kingtous commented 4 years ago

同,项目中同时导入了wechat、weibo和qq,都是这个fake系列的...

Kingtous commented 4 years ago

更换为tencent_kit 1.0.4问题解决

droplet-js commented 4 years ago

😱 虽然不知道是啥原因 … 不过,tencent_kit升级 1.0.4 已经很久了 … 我觉得我可能得加一下issue模板 …

Kingtous commented 4 years ago

😱 虽然不知道是啥原因 … 不过,tencent_kit升级 1.0.4 已经很久了 … 我觉得我可能得加一下issue模板 …

我猜是StreamSubscription导致的吧好像?

我的一个业务是先登录拿到token后获取用户信息。

之前的fake_tencent(我用的0.3.4)要登录的话要一个StreamSubscription\<TencentLoginResp>,获取用户信息的时候又要一个StreamSubscription\<TencentUserInfoResp>方法。而在tencent_kit新版中getUserInfo无需StreamSubscription\<TencentUserInfoResp>而是直接await.

作者的fake_wechat一直是tencent_kit现在的逻辑,只有一个StreamSubscription,所以没有导致回调两次(我的猜测,没有细看源码)

droplet-js commented 4 years ago

对的,原来是调用sdk获取用户信息,新版本我嫌弃调sdk麻烦,找到相关API,然后走API了

droplet-js commented 4 years ago

这个锅得是腾讯QQ sdk背了…

SpanishOnion commented 4 years ago

一直用的 1.0.4,没用过其他版本,一直存在这个BUG。

droplet-js commented 4 years ago

确认一下是否创建tencent对象两遍?

SpanishOnion commented 4 years ago

全局变量,单例模式,只创建一次,StreamSubscription能连续收到两次相同回调。

droplet-js commented 4 years ago

listen结束,是否取消sub?

SpanishOnion commented 4 years ago

全局先cancel,再listen,不存在重复的地方

droplet-js commented 4 years ago

等会儿我试试新Demo,在二级页面分享登录

SpanishOnion commented 4 years ago

我微博,微信,QQ,都用的是一模一样的方式,放在一个全局类里面管理,如果一个会重复回调,其他两个也会重复,唯独QQ有重复回调,其他两个没有。

Kingtous commented 4 years ago

我是全局同时先注册微信、QQ、微博,注册的对象放全局类里面。然后在登录页面listen三者相应的方法,dispose里面cancel。

现在微信、QQ都回调一次,微博没试

SpanishOnion commented 4 years ago

我现在先使用变量控制每次只处理一个回调,因为是相同的token,没什么太大问题,当然这个BUG解决了肯定更好,登录的时候QQ客户端的通知提醒会提醒2次

SpanishOnion commented 4 years ago

我怀疑是插件连续调用了2次QQ SDK的登录Api

AlexV525 commented 4 years ago

第二条评论的时候有说明,所有的方法我都打了log,只有handler出现了两次。一直用的1.0.4。

droplet-js commented 4 years ago

你们手机上都装了啥?TIM、QQ、QQ急速轻聊版,这三个都装了哪些?

SpanishOnion commented 4 years ago

只装了QQ

droplet-js commented 4 years ago

版本?

SpanishOnion commented 4 years ago

安卓的最新版本,我觉得和版本没关系,之前iphone也测试了,iphone也是最新版手Q

droplet-js commented 4 years ago

@AlexVincent525 我需要重现现场,你是怎么设置TencentKitProvider的?

Kingtous commented 4 years ago

你们手机上都装了啥?TIM、QQ、QQ急速轻聊版,这三个都装了哪些?

TIM、QQ

droplet-js commented 4 years ago

@AlexVincent525 你貌似漏了 dispose

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<TencentKitProvider>(
      create: (BuildContext context) => TencentKitProvider(),
      child: MaterialApp(
        home: Home(),
      ),
    );
  }
}
import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:tencent_kit/tencent_kit.dart';

class TencentKitProvider with ChangeNotifier {
  Tencent _tencent;
  Tencent get tencent => _tencent;

  StreamSubscription<TencentLoginResp> tencentLoginResponses;

  TencentLoginResp tencentLoginResponse;

  ObserverList<Function> tencentLoginListeners = ObserverList<Function>();

  void initClient() {
    print("initClient");
    _tencent = Tencent()..registerApp(appId: '222222');

    tencentLoginResponses = _tencent.loginResp().listen((data) {
      print("triggered observers");
      for (final observer in tencentLoginListeners) observer(data);
    });
  }

  void addDefaultListeners() {
    tencentLoginListeners.add(tencentListenLogin);
  }

  void tencentListenLogin(TencentLoginResp resp) {
    tencentLoginResponse = resp;
    String content = 'OpenId: ${resp.openid} AccessToken: ${resp.accessToken}';
    debugPrint('QQ登录 $content');
  }

  void tencentLogin() {
    tencent.login(scope: [TencentScope.GET_SIMPLE_USERINFO]);
  }

  @override
  void dispose() {
    tencentLoginResponses?.cancel();
    super.dispose();
  }
}
AlexV525 commented 4 years ago

@AlexVincent525 你貌似漏了 dispose

dispose cancel不会漏的,它只是没有在第一条内容的代码里写上。并且我的provider为顶层,排查过注册状态。

droplet-js commented 4 years ago

-_-!!! 没辙,就是无法重现案发现场 ... 远程调试一波?不过Mac无法远程调试 ...

AlexV525 commented 4 years ago

-_-!!! 没辙,就是无法重现案发现场 ... 远程调试一波?不过Mac无法远程调试 ...

上班时间有没有空?可以teamviewer

droplet-js commented 4 years ago

哈哈,只有周一到周四的晚上时间才有空 。。。

AlexV525 commented 4 years ago

下周三晚可否?预定一波,或者你可以来我们qq群,直接文字先交流一手

droplet-js commented 4 years ago

你能否清掉APP里的核心代码,保留入口和登录页面,这样的Demo发我?

AlexV525 commented 4 years ago

很难,明天尝试下

hlj2722 commented 4 years ago

Flutter (Channel stable, v1.12.13+hotfix.5, on Microsoft Windows [Version 10.0.18363.535], locale zh-CN) 我也遇到相同的问题,使用QQ登录 时调用了两次,用的是作者的demo也会出现这个情况

droplet-js commented 4 years ago

奇怪了 … 能告诉我是啥手机,系统版本号吗?

AlexV525 commented 4 years ago

@v7lin demo已弄好,怎么发你?

droplet-js commented 4 years ago

@AlexVincent525 v7lin@qq.com 邮箱附件吧

AlexV525 commented 4 years ago

@AlexVincent525 邮箱附件吧

已发送

AlexV525 commented 4 years ago

对了,我装的是QQ和微信。其他没有

hlj2722 commented 4 years ago

[√] Flutter (Channel stable, v1.12.13+hotfix.5, on Microsoft Windows [Version 10.0.18363.535], locale zh-CN) [!] Android toolchain - develop for Android devices (Android SDK version 29.0.2) X Android license status unknown. Try re-installing or updating your Android SDK Manager. See https://developer.android.com/studio/#downloads or visit https://flutter.dev/setup/#android-setup for detailed instructions. [√] Android Studio (version 3.5) 手机是 redmi note3

droplet-js commented 4 years ago

@AlexVincent525 邮箱附件吧

已发送

-_-!!! 没有收到啊

hlj2722 commented 4 years ago

把作者的代码直接克隆下来运行只收到一次回调,但是如果创建一个新项目,再把作者的栗子拿来运行就会出现两次回调

AlexV525 commented 4 years ago

-_-!!! 没有收到啊

v7lin@qq.com? image