1.google订阅测试要把账号加到测试组。
2.SingleChildScrollView不起作用,外面包一层expanded. item中不要有Spacer().
3. canvas的大小可以由外层的SizedBox决定。
4. 用Spacer可以撑开布局。
5. EasyLoading.dismiss();不起作用,是因为在异步函数里面, 必须加上await,await EasyLoading.dismiss();
6. Flutter app 版本号:1.0.0+1, 1.0.0是version name, +1是version code. 根据经验,version code最好和version name保持一致的格式。比如 1.0.0+10000。
抽象的说是因为version code和version name逻辑上是强关联的,形式上也要强关联,不然就会出现问题。 具体的问题就是,pubyaml文件经常会出现没递交的情况, 上一次打包的人没递交,然请假了,别人打包的时候,一下子不知道version code是什么了。
7. pod install 解决版本不存在的问题.
mac上临时设置代理:
export http_proxy=“http://xn--proxy-xxxxx-ck3f
export https_proxy=“https://proxy-XXXXX:”
临时取消代理:
unset http_proxy
unset https_proxy
查看代理:
env | grep xxx
8. ios UI上显示购买成功但实际失败。
Also double-check to make sure your in-app purchases are approved and active - they go through a separate app review process and they have to be approved (you will know if they are not approved, it will say “waiting for review” or “ready to submit” or something similar.)
要先approved and active。app要先上线。
9. ios修改了版本号,但是依旧不变的时候, 用android stuido debug跑一遍就好了。
10. styledtext需要更新到7.0.0以上, 不然ios上不能显示。
11. 当canvas的内容保存成图片时。 颜色样式要成RawRGBA, 不然ios上会有蓝色蒙层。 另外, 最新版的Image4.0库, 需要加上numChannels的值, RGBA是4.
final byteData =
await img.toByteData(format: UI.ImageByteFormat.rawrgba);
12. EasyLoading.dismiss();不起作用,是因为在异步函数里面, 必须加上await,await EasyLoading.dismiss();
13. ipad 分享没反应的问题,需要再包装一个Builder,另外一定要用上sharePositionOrigin。如下:
Builder(
builder: (BuildContext context) {
return ElevatedButton(
onPressed: () => _onShare(context),
child: const Text('Share'),
);
),
// _onShare method:
final box = context.findRenderObject() as RenderBox?;
await Share.share(
text,
subject: subject,
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
);
14. google广告错误(code: 3, domain: com.google.android.gms.ads, message: Ad unit doesn't match format.) 是因为配错广告了,比如:Rewarded和Rewarded Interstitial搞错了。
15. 瀑布流列表控件, 存在内容需要网络加载时, 会存在上下拉跳跃的问题。是因为移出屏幕可视区的时候,就会被回收。再加载时,由于不知道实际内容的高度,最终加载出来的时候就会出现跳的情况。
比如,图片加载问题。 解决这个问题需要事先知道图片的宽高比,因为宽度是知晓的,根据宽高比来算出高度。
16. google store和apple store包含广告前, 都必须事先正式上架。
17. ios 配置deeplink, 用最新的URLSchma方式, 不需要用老的方式在服务器配置。
18. 相机竖屏拍摄的照片通常带有角度, 要去掉角度可以使用image4.0以上的库,
代码: final img.Image capturedImage = img.decodeImage(await File(path).readAsBytes());
final img.Image orientedImage = img.bakeOrientation(capturedImage);
19. navigation 的页面, 切换显示, 最好使用offstage, 否则会再次加载。导致莫名其妙的显示问题。
20. 一些大图加载显示慢的时候, 可以用percacheImage(), 在显示页前的那一页先加载好。
21. ios可以包含多套app icon, 在xcode里增加就好了。
22. flutter 中类似fragment之间如何通信?
23. flutter_launcher_icons 这个库,只要一张大于1024的图, 就可以一次性搞定androi/ios的各种大小图. 但是执行命令时,确认一下路径,不要搞错。
24. Text未自动换行。限制高度,和行数。
25. Get.dialog可以在任何地方打开一个自定义的对话框。关闭是goBack(). 可以通过Get.isDialogOpen来判断对话框是否打开, 可以在deactive()或者onclosed里面关闭。
26. ClipRRect设置图片圆角没有效果。 是因为外层需要指定宽高。
27. ios开发。 NSURL initFileURLWithPath:]: nil string parameter, 可能是没有上传资源文件, 通常是图片。异常的意思是找不到文件。
28. ExpandablePageView中内容总是被撑满, 用wrap可以让子组件按照自身的大小。
29. initState 只能执行同步方法。所以一些需要异步加载的资源就无法顺利加载。 解决方法就是:
bool hasInit = false;
@override
void initState() {
super.initState();
hasInit = false;
Future.delayed(Duration.zero, () async {
//do load init data.
hasInit = true;
setState(() {});
});
}
@override
Widget build(BuildContext context) {
if (!hasInit) {
return Container();
}
// return real ui.
}
30. 一个widget触发事件,事件里触发别的widget的事件。怎么处理。 组件间如何通信问题。 使用streamController.
late Stream<Map> _stream;
Stream<Map> get stream => _stream;
_streamController = StreamController<Map>();
_stream = _streamController.stream.asBroadcastStream();
31. 判断文件是否存在。 当android12以上,返回Content://这种mediaostore uri 的时候,先转换成file path, 再用file.exist判断是否存在。
static Future<bool> exist(String pathOrUri) async{
String? filePath = pathOrUri;
if(Platform.isAndroid){
if(pathOrUri.startsWith("content://")){
filePath = await LecleFlutterAbsolutePath.getAbsolutePath(uri:pathOrUri); //第三方插件,用于转换成绝对路径。
}
}
if(filePath!=null && filePath.isNotEmpty) {
return File(filePath!).exists();
}
return false;
}
32. ios 删除图片。不是马上删除的,会放到垃圾箱, 只有当垃圾箱中也删除的时候,File().exists()才会返回false.
33, ClipPath通过重写Clipper就可以裁剪,不同形状的图形。
34, WidgetsBindingObserver可以在app层面监听app的生命周期, 还有多语言的切换。
35,Locale是由lanugageCode, countryCode, ScriptCode组成的, 而Getx的国际化是对lanugageCode_countryCode建立的索引。所以存在一定的问题
36, 静态数组里不要把函数作为成员, 比如不能把多语言cccc.tr这种作为数组成员。 另外,静态数组对热更新无效。
37,flutter build apk --release --flavor flavoronline -t lib/main_android_online.dart
38. Exception: Unsupported Android Plugin version: 4.2.2., 是因为使用了productFlavor, 要在相应的Edit Configuration里添加渠道。
39. spread operator (...) 类似于kotlin的×号,展开数组合作map的item.
40. ios打包时,遇到证书账号的问题, 在确实有的情况下, 还报错, 可能是网络问题, 重启一下电脑就好了。
41.ios向系统分享
42.FlutterError.onError = (FlutterErrorDetails details) {
Zone.current.handleUncaughtError(details.exception, details.stack);
};
43. flutter 提示Unsupported Android Plugin version: 4.2.2, 这是由于安卓添加了productFlavors来设置多渠道打包, 所以在调试main.dart的tab页也要加上渠道Flavors。
44. windows 校验apk文件的md5码。
cmd
Certutil -hashfile filename MD5
Certutil -hashfile filename SHA1
Certutil -hashfile filename SHA256
45. RxDart, 当值更新的时候,如果前一个值和后一个值一样的时候,就不会触发事件, 如果要触发比需再调一下refresh.
46. Future<bool> isReady() async{
return false;
} 返回值是Future, 函数体必须是async.
47. 必须设置NDK 把x86排除掉, 不然会增加apk的大小。大概6M. Flutter app size起跳大于20M.
48. 在manifest上一定要package name, 这和纯android工程不一样.
D:\Development\aigc-mobile\android\app\src\debug\AndroidManifest.xml Error:
Attribute activity#com.nero.aigc.MainActivity@name value=(.MainActivity) from (unknown)
is also present at AndroidManifest.xml:26:9-37 value=(com.xxx.aigc.MainActivity).
Suggestion: add 'tools:replace="android:name"' to <activity> element at AndroidManifest.xml:25:5-44:16 to override.
49. 不可或缺 lintOptions {
checkReleaseBuilds false
abortOnError false
}
50. Fail to transform .jarer'n'j
51. 解决软键盘遮挡住底部按钮问题。 resizeToAvoidBottomInset = false
52. 在google广告播放完毕的回调中, 不能去调用插件方法访问原生。
53. 不要写错事件赋值。 onTap:(){ controller.pickImage(context);}, 不要直接写成onTap:controller.pickImage(context)。 会抛出异常:setState() or markNeedsBuild() called during build.
54. TextField输入框光标焦点的释放。不释放焦点,打开其他页面再回来,会弹出键盘。插件:flutter_keyboard_visiblty. 对TextField设置forceNode, 当键盘不可见时,调用forceNode.unforce().
55. ConstrainedBox和AutoSizeText可以解决多语言过长的问题。
56.flutter键盘溢出问题, 把Scaffold的 resizeToAvoidBottomInset 属性设置为false.
57. EasyLoading.show(). 如何去掉背景小框?
EasyLoading.instance..loadingStyle = EasyLoadingStyle.custom
..backgroundColor = Colors.transparent
..boxShadow = <BoxShadow>[]
..textColor = Colors.white //必须要设, 因为EasyLoadingStyle.custom下不能为空。
..indicatorColor = Colors.transparent;//必须要设, 因为EasyLoadingStyle.custom下不能为空
58.android studio编译错误, tag mismatch!. 是因为gradle版本不匹配。 在下载gradle版本的时候,下载出错了。 公司网络问题。 解决方式就是自己用浏览器下载,完后考到相应目录。
59. AGP Upgrade Assistant命令可以解决gradle的更新, 以及版本不匹配的问题。
60. Google 订阅(sub类型)和永久购买(inapp类型), 查询details时, 不能在一个数组。购买时,sub类型需要offerToken, inapp类型不需要。
61.继承FullLifeCycleController, 而不是GetXController, 就可以获得全生命周期了。
62.> Could not resolve all files for configuration ':firebase_crashlytics:debugCompileClasspath'.
> Failed to transform firebase-encoders-json-18.0.1.aar
公司网络问题。注释掉国内阿里的镜像。
63.网络不好时,下载不完全。下面的命令重新下。
flutter pub cache clean
flutter pub get
64. 最好是通过flutter pub add xxx 来添加第三方插件,不然有可能导致和版本flutter & android stuido不匹配。
65.在gradle.properties中添加: org.gradle.jvmargs=-Xmx1536M \
--add-exports=java.base/sun.nio.ch=ALL-UNNAMED \
--add-opens=java.base/java.lang=ALL-UNNAMED \
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED \
--add-opens=java.base/java.io=ALL-UNNAMED \
--add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED
可以解决java版本过高(17), 导致的什么String类不存在的问题。
Unable to make field private final java.lang.String java.io.File.path accessible: module java.base does not "opens java.io" to unnamed module
66. 由于是额外安装更新的android studio, 导致flutter daemon terminated. 更新一下路径:
flutter config --android-studio-dir="C:\Program Files\Android\Android Studio1"
然后重启一下电脑。
67. Error: ADB exited with exit code 1
手机空间不够了,删除一些旧app.
68. Dio 5.0.0, ImplyContentTypeInterceptor有个bug, 判定List<Map>才是json,这样就忽略了List<?>的其它类型。
69. Apple作为第三方登录时,出现下面的错误,是因为没有添加权限,在 Signing & Capabilities添加 "Sign in with Apple" 。
在apple开发者中心点击Certificates, Identifiers & Profiles下的Identifiers,勾选Sign in with Apple
在xcode中依次点击:左侧根目录Runner--》TARGETS下的Runner--》Signing & Capabilities--》添加Sign in with Apple
[core] Authorization failed: Error Domain=AKAuthenticationError Code=-7026 "(null)" UserInfo={AKClientBundleID=com.nero.aigc.muse.ai.art}
Sign in with Apple errored: Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1000 "(null)"
70. Apple作为第三方登录时, 登入后出现user name和email为null的情况, 是因为apple安全策略,只有在第一次登录的时候,才能取到信息。如果想继续测试,解决方法是:
在设置中搜索“密码与安全性”, 在“通过Apple登录”中删除相应的app。如果是android第一次都取不出来。 其实不用管,服务端会用返回的token去apple拿全用户信息。
71.在firebase配置apple oauth时,如果是android端登录,就不要配置服务ID和oauth流程。注意service id和key都要新创建。
参考:https://frontend.devrank.cn/traffic-information/7301721066840475674
72. 关于第三方登录问题。 有些第三方有普通登录和企业登录之分, 如果只是获取用户的profile, 就用普通登录。 而需要获取第三方额外的信息就用企业登录。两者不要搞混!
在facebook上, 企业登录也可以获取用户profile, 但是必须和额外的权限功能搭配使用, 而app又不需要,强行选一个的话,就会在用户登录验证的时候出现询问额外那个功能的权限框。这是完全不必要的。所以
该是普通登录就普通登录, 该是企业版登录就企业版登录。
73. jfif格式因为是无损压缩,然后jepg也能实现编解码。一开始以为无法显示是格式原因。后来发现是facebook没翻墙。
74. facebook上需要的key hash. 是对SHA1做BASE64的字符串。 先用jadx取出SHA1, 然后再convert. https://tomeko.net/online_tools/hex_to_base64.php. 原有的命令不好使。不知道哪里的问题。
keytool -exportcert -alias xxx -keystore "D:\Development\xxx\android\keystore\release.keystore" | "C:\Users\xxx\Downloads\openssl\bin\openssl" sha1 -binary | "C:\Users\xxx\Downloads\openssl\bin\openssl" base64
75. 内部的可滚动组件(body的)不能设置 controller 和 primary,这是因为 NestedScrollView 的协调器中已经指定了它的 controller,如果重新设定则协调器将会失效。
76. No matching client found for package name. 如果是google service插件抛出来的。那么就是googleservice.json里面的包名还没有改。
77. flutter的工程名限制了中线-, 所以git上的名字也不要用中线,用下划线替代。
78. 在需要不断刷新的时候,用drawPath替换DrawLine性能效果好很多。
79. ShaderMask可以给任何widget加上渐变色。比如文字。
80.Rect rect = Offset.zero & size Offset类重载了&, 这就是Rect(0,0,w,h).
81.构造函数中可以用assert指定格式范围, 如果不满足,编译器就会报错。比如
const RawMagnifier({
super.key,
this.child,
this.decoration = const MagnifierDecoration(),
this.focalPointOffset = Offset.zero,
this.magnificationScale = 1,
required this.size,
}) : assert(magnificationScale != 0,
'Magnification scale of 0 results in undefined behavior.');
82. RawMagnifier可以实现放大镜效果。
83. Flutter 错误RenderBox was not laid out:
在Flutter 的Column或者Row 可动态改变子组件,其中子组件大小,位置可能有变化,并且可能溢出就会抛出这个错误。
具体的解决办法就是 在该组件外嵌套一个SizeBox或者Container即可…
84. SafeArea是用于适配各种手机屏幕,刘海,挖空,等导致的遮挡。
85. automaticallyImplyLeading 可以控制appbar上的leading是否显示。
86. canvas paint并且blend mode是clear,如果擦除后出现是黑色,而不是透明色。 需要在外面套一层savelayer, 也就是说需要在新图层处理好,再合并回去。
87. canvas paint, 当导出canvas内容时,原图较大时, 基于原图上画的元素会比较小。这时canvas需要缩小一下。
canvas.scale(
size.width / canvasSize.width, size.height / canvasSize.height);
反之亦然。
88.Xcode升级到15.0后,报错:DT_TOOLCHAIN_DIR cannot be used to evaluate LIBRARY_SEARCH_PATHS, use TOOLCHAIN_DIR instead.
解决办法:全局搜索DT_TOOLCHAIN_DIR,一键替换成TOOLCHAIN_DIR。
89. app市场的评价框不会每次都跳出来,就跳一次,再也不会跳了,而且无法知道是否已经跳过。
90. 如果遇到两个第三方SDK都引用了同一个其他的第三方SDK,但是那个SDK 版本不一样。解决的方法依旧是找到合适的版本号。
比如:
Facebook_event: Any
share: Any
这样编译一次后,在pod.lock中就会适配好合适的版本。然后把版本号写到pubspec.yaml.
这样就好了。 但是如果想要使用最新版本的SDK, 那就没办法了,只能等第三方SDK的开发者更新版本。
这是flutter很不好的地方。
91. IOS订阅在setting页的App Store选项,管理。但是新的版本取消无法打开, 只能用老版本来取消。
92.在后台查看GA 统计时,有时会找不到事件参数统计,请在Analytics Dashboard --> 最右边“参数名称” 选择相应的参数。
93. Row和Colum虽然不能在内部设置宽高,但是在内部一样可以, 用sizedBox占位就可以了。
94. Instgram分享, ios上需要通过文件id, 但是无法根据文件路径取得文件id, 所以需要从保存文件的插件获取的。
95. 今天遇到testflight上的app启动屏空白, 但是本地不管是debug还是release都没问题。 后来发现是启动屏有抛出异常导致的。 由于flutter不会崩溃,只会停止运行,所以余下的代码都不执行了。
一定要检查好日志中有没有抛出异常,并且改正。要不然到了市场上尴尬了。
96.ios, 明明已经正式发布到应用市场上了。但是评价框不会跳出来。是因为应用市场上还不能搜到。
97. 接上面一个问题。搜索不到是因为应用市场还在生成关键词。
98.你可能会碰到这样的crash:
* thread #9, name = 'io.flutter.1.ui', stop reason = EXC_BAD_ACCESS (code=1, address=0x105ea4000)
frame #0: 0x0000000107feed54 Flutter`flutter::DisplayListBuilder::Restore() + 284
Flutter`flutter::DisplayListBuilder::Restore:
-> 0x107feed54 <+284>: ldrsb w8, [x24]
0x107feed58 <+288>: sub w8, w8, #0x17
0x107feed5c <+292>: cmp w8, #0x1
0x107feed60 <+296>: b.hi 0x107fef1e4 ; <+1452>
Target 0: (Runner)android
stopped.
这是flutter SDK导致的问题。3.22.0开始引入的问题, 写这篇文章时最新是3.22.2。解决这个问题就是退回到上一个版本, 3.19.6.
99. 在iPhone setting里设置权限范围,iPhone会重启App. 就像切换语言一样。
100.xcode编译不过。Cycle inside Runner; building could produce unreliable results.Cycle details:..., 解决方案:在xcode中找到Runner中第一个Target的Build Phases选项,将Embed App Extensions拖到Run Script下面即可。
101. bottom sheet 弹出来时,提示Overflow。要解决这个问题,只要给所在页面最外层套一个SingleChildScrollView就好了。
102. android编译出错。To disable the shrinker, pass the `--no-shrink` flag to this command.android 把最小支持SDK设成24.
103. 在ios上, debug和release都是好的,但是放到testflight上,就缺少功能,大概是因为打包优化的问题,具体细节也不清楚。这次碰到是第三方的onnxruntime库没有打包进去。最后在github的issue列表里找到了解决方式。
在xcode,build setting, depolyment页,strip linked product 设成NO.
104. 动画结束有两种状态,顺着结束是AnimationStatus.completed, 倒着结束是AnimationStatus.dismissed。
105, 如果动画依赖属性的值,在运行时才能确定, 那么这个值一定是可空值, 所以先给null没有关系,等加载完成后,再赋值给依赖属性,然后刷新一下就好了。比如,text的width/height.