栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Flutter TextField引起的剪切板合规问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Flutter TextField引起的剪切板合规问题

背景

最近突然收到安全部门的消息,说有些页面在获取剪切板内容。我当时很确性的说,我压根没去获取剪切板内容啊。
但是他给出了具体的调用堆栈,这一看果然是真的。

at android.content.ClipboardManager.getPrimaryClip(Native Method) at 
io.flutter.plugin.platform.PlatformPlugin.getClipboardData(PlatformPlugin.java:332) at 
io.flutter.plugin.platform.PlatformPlugin.access$700(PlatformPlugin.java:28) at 
io.flutter.plugin.platform.PlatformPlugin$1.getClipboardData(PlatformPlugin.java:107) at 
io.flutter.embedding.engine.systemchannels.PlatformChannel$1.onMethodCall(PlatformChannel.java:141) at 
io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233) at 
io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85) at 
io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:818) at 
android.os.MessageQueue.nativePollonce(Native Method) at 
android.os.MessageQueue.next(MessageQueue.java:325) at 
android.os.Looper.loop(Looper.java:142) at 
android.app.ActivityThread.main(ActivityThread.java:6549) at java.lang.reflect.Method.invoke(Native 
Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:491) at 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
找出问题

1.确定是什么原因导致的
根据截图的几个页面,当然他当时截图的页面是不对的,但是这个页面的后一个页面。
我是根据断点原生代码去确定范围的。
发现出现在了地址编辑页,根据经验判断问题出现在了输入框上。
然后我在flutter项目中搜索 Clipboard.getData

为什么搜索这个也是根据上面的堆栈那确定的

io.flutter.embedding.engine.systemchannels.PlatformChannel$1.onMethodCall(PlatformChannel.java:141) at 

通过搜索发现

有这几个地方调用获取剪切板内容。
下面一个一个分析

发现editable是Edittext的Render child对象

且是剪切文字时触发的

这中操作会引起获取剪切板,但我进入页面时根本没有任何操作就出现了,只能说明这个地方会,但不是根本问题的地方。
切图上出现的问题的case有很多我就不一一分析了,我就分析真正出现的问题的地方。

ClipboardStatusNotifier这个类的update时会去获取剪切板
然后ClipboardStatusNotifier这个类的addListener会调用upData方法

为什么看它,前面已经说了是输入框导致的。Flutter中输入框就是text_field,ios样式的输入框也一样,发现它的子控件EditableText中调用了ClipboardStatusNotifier

然后EditableText的State类中也就是EditableTextState
里初始化了ClipboardStatusNotifier片 还记得上面说过,这个类的upData方法被调用时会去获取剪切板内容,然后这个类的addListener类也会触发upData方法

@override
  void initState() {
    super.initState();
    _clipboardStatus?.addListener(_onChangedClipboardStatus);

问题明了了,initState的调用时机就是 Element创建时就会被调用。
再贴下flutter获取剪切板内容的地方

@override
  void addListener(VoidCallback listener) {
    if (!hasListeners) {
      WidgetsBinding.instance!.addObserver(this);
    }
    if (value == ClipboardStatus.unknown) {
      update();
    }
    super.addListener(listener);
  }

只要

value == ClipboardStatus.unknown这个条件成立就会触发,那它成立吗,下面来看看
初始化的地方

默认值

那百分百会被调用了,这也是为什么我页面中有输入框时会被自动调用获取剪切板内容的原因了。

解决问题

问题定位到了,且出现的原因也知道了。那解决办法也就出来了。

  1. 修改系统源码,拷贝TextField类,修改关键点
  2. 重原生入手,hook Channel交互方法,当由flutter获取剪切板内容时 阻止其获取方法。
    我给出第二种解决办法吧,第二种的好处是不用修改多处Flutter代码,对双端的影响较小。
    github地址
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/324702.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号