0%

安卓(李某测试)拨打 苹果(李朴2),进入对话界面,

弹出键盘,弹出报错,在chat_room.dart文件中

1
2
3
4
5
6
7
8
9
10
11
[VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: 'package:flutter/src/widgets/scroll_controller.dart': Failed assertion: line 112 pos 12: '_positions.isNotEmpty': ScrollController not attached to any scroll views.
#0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
#1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
#2 ScrollController.position (package:flutter/src/widgets/scroll_controller.dart:112:12)
#3 _ChatRoomState.didChangeMetrics (package:polars_app/pages/chat/chat_room.dart:708:27)
#4 WidgetsBinding.handleMetricsChanged (package:flutter/src/widgets/binding.dart:571:16)
#5 _rootRun (dart:async/zone.dart:1190:13)
#6 _CustomZone.run (dart:async/zone.dart:1093:19)
#7 _CustomZone.runGuarded (dart:async/zone.dart:997:7)
#8 _invoke (dart:ui/hooks.dart:251:10)
#9 _updateWindowMetrics (dart:ui/hooks.dart:53:3)

解决:在访问maxScrollExtent属性前一定要判断_scrollController.hasClients

1
2
3
if (_scrollController.hasClients) {
_scrollController.position.maxScrollExtent;
}

问题描述:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//33003	调用接口时传入的参数不正确
[RC-Flutter-IM] iOS error sendMessage 33003

[VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The method '+' was called on null.
Receiver: null
Tried calling: +(":该消息内容为空,可能该消息没有在原生 SDK 中注册")
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 MessageFactory.map2Message (package:rongcloud_im_plugin/src/util/message_factory.dart:120:40)
#2 MessageFactory.string2Message (package:rongcloud_im_plugin/src/util/message_factory.dart:27:12)
#3 RongIMClient.sendMessageWithCallBack (package:rongcloud_im_plugin/src/rong_im_client.dart:187:43)
<asynchronous suspension>
#4 RongIMClient.sendMessageCarriesPush (package:rongcloud_im_plugin/src/rong_im_client.dart:116:12)
#5 RongIMClient.sendMessage (package:rongcloud_im_plugin/src/rong_im_client.dart:92:12)
#6 _ChatRoomState._sendMessage (package:polars_app/pages/chat/chat_room.dart:2765:32)
#7 _ChatRoomState._sendMessageClick (package:polars_app/pages/chat/chat_room.dart:2144:9)
#8 _ChatRoomState._buildTextComposer.<anonymous closure>.<anonymous closure> (package:polars_app/pages/chat/chat_room.dart:2097:29)
#9 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:993:19)
#10 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:1111:38)
#11 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:183:24)
#12 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:598:11)
#13 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:287:5)
#14 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:259:7)
#15 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:157:27)
#16 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:362:20)
#17 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:338:22)
#18 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:267:11)
#19 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:295:7)
#20 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:240:7)
#21 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:213:7)
#22 _rootRunUnary (dart:async/zone.dart:1206:13)
#23 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
#24 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
#25 _invoke1 (dart:ui/hooks.dart:265:10)
#26 _dispatchPointerDataPacket (dart:ui/hooks.dart:174:5)

分析:

1
2
3
4
5
6
//走到这串代码
msg = await RongIMClient.send
//launch和login调用登录代码
RyManager.instance.connect();
//方法内部调用 获取到的token为空
RongIMClient.connect(token)

无法连接融云,暂停;

继续调试

李朴2 userID:1174605640773193730

李某测试 userID:1107918162780569602

李某测试 (userID:1107918162780569602) android

打给

李朴2 (userID:1174605640773193730) iOS,锁屏超过一分钟

at 11:56

14:00 等待融云官方回复

app_helper——–>go web page ——->web view

  • 安装

    1
    brew install jenkins-lts
  • 启动

    1
    brew services start jenkins-lts
  • 停止

    1
    brew services stop jenkins-lts
  • 重启

    1
    brew services restart jenkins-lts
  • 更新

    1
    brew upgrade jenkins-lts

局域网访问配置

homebrew.mxcl.jenkins.plist里面httpListenAddress127.0.0.1更改为0.0.0.0

两个地方

  • ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist
  • /usr/local/Cellar/jenkins/版本号/homebrew.mxcl.jenkins.plist

参考:https://www.jianshu.com/p/10041e79ac6f

链表了解吗

  • Linked list is a sequence of links which contains items

  • Link - Each link of a linked list can store a data called an element

  • Next - Each link of a linked list contains a link to the next link called Next

  • LinkedList - A Linked List contains the connection link to the first link called First

  • Linked list can be visualized as a chain of nodes,where every node points to hte next node

    ![image](Linked List

    • Simple linked list -item navigation is forward only
    • doubly linked list - items can be navigated forward and backward
    • circular linked list - last item contains link of the first element as next and the first element has a link to the last element as previous.

双向链表是什么

同上,节点有前后指针

跟数组的区别

  • 数组在编译时已经分配好连续内存
  • 链表在运行时添加数据时分配内存
  • 数组在栈,链表在堆

数组为什么快

  • 数组查找快,因为可以根据索引直接获得,复杂度O(1),链表复杂度O(N)
  • 数组插入和删除慢,因为空间连续,插入删除后需要整理内存大小,链表插入删除快,只要改变指针指向即可

参考:1. https://www.tutorialspoint.com/data_structures_algorithms/linked_list_algorithms.htm

2.https://www.studytonight.com/data-structures/linked-list-vs-array

创建分类功能

1
hexo new page categories

打开index文件

1
/source/categories/index.md

文件添加字段

1
2
3
title: categories
date: 2021-01-05 12:19:59
type: "categories"

写文章的时候加上分类标签

1
2
3
4
5
title: mac android studio flutter 打包 apk
date: 2020-11-16 20:16:07
categories:
- unix
tags:

添加标签同理

完。

参考:https://www.cnblogs.com/hankleo/p/11606224.html

目的:实现客户端与服务端的实时通讯,基于TCP协议

与keep-alive区别:keep-alive机制会连接一小段时间,最终会断开,ws协议不会断开

原理:通过一条特殊的http协议请求进行握手后,服务端支持ws协议,则进行协议升级,利用http创建的tcp连接,实现长连接。

步骤分解:

  • 连接服务器

    1
    final channel = IOWebSocketChannel.connect('ws://echo.websocket.org');
  • 关闭连接

    1
    channel.sink.close();
  • 监听服务器

    • StreamBuilder是一个组件,收到一个stream就刷新界面
    1
    2
    3
    4
    5
    6
    new StreamBuilder(
    stream: widget.channel.stream,
    builder: (context, snapshot) {
    return new Text(snapshot.hasData ? '${snapshot.data}' : '');
    },
    );
  • 发送消息

    1
    channel.sink.add('Hello!');

完整demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import 'package:flutter/material.dart';
import 'package:web_socket_channel/io.dart';

class WebSocketRoute extends StatefulWidget {
@override
_WebSocketRouteState createState() => new _WebSocketRouteState();
}

class _WebSocketRouteState extends State<WebSocketRoute> {
TextEditingController _controller = new TextEditingController();
IOWebSocketChannel channel;
String _text = "";


@override
void initState() {
//创建websocket连接
channel = new IOWebSocketChannel.connect('ws://echo.websocket.org');
}

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("WebSocket(内容回显)"),
),
body: new Padding(
padding: const EdgeInsets.all(20.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Form(
child: new TextFormField(
controller: _controller,
decoration: new InputDecoration(labelText: 'Send a message'),
),
),
new StreamBuilder(
stream: channel.stream,
builder: (context, snapshot) {
//网络不通会走到这
if (snapshot.hasError) {
_text = "网络不通...";
} else if (snapshot.hasData) {
_text = "echo: "+snapshot.data;
}
return new Padding(
padding: const EdgeInsets.symmetric(vertical: 24.0),
child: new Text(_text),
);
},
)
],
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _sendMessage,
tooltip: 'Send message',
child: new Icon(Icons.send),
),
);
}

void _sendMessage() {
if (_controller.text.isNotEmpty) {
channel.sink.add(_controller.text);
}
}

@override
void dispose() {
channel.sink.close();
super.dispose();
}
}

数据类型:发送的过程中数据以frame形式存在,每一个frame都由opcode字段指定类型,客户端在收到消息时已经知道类型,会自动转换,streamBuilder.snapshot.data如果是文本,类型是string,二进制数据,类型是List,还有其他类型

参考:https://book.flutterchina.club/chapter11/websocket.html