Flutter 从入门到放弃(Mac)

2021-04-25  本文已影响0人  小青蛙的花

Read Me

  1. Mac环境安装很方便,跟着flutter网站走一般不会迷路,这里就不赘絮了。主要记录一些问题和开发中需要注意的地方
  2. 之前是iOS开发,有些基础,所以Android的问题会相对多一些,也容易犯一些简单的错误,主要还是记录给自己看,能帮到一些跟我一样没基础的人最好了
  3. 文章暂定分为五个部分:Read Me,常用指令,Android问题,iOS问题,Flutter问题。每个问题主要分三部分:问题描述,问题原因,解决办法
  4. 持续更新,发现长时间没有更新大概就是放弃的时候了吧

这里记录一些常用的指令

//诊断flutter运行需要环境
flutter docter
//清除缓存
flutter clean
//打包Android APK,这里加上--no-tree-shake-icons是加载资源时报错,下面有提到
flutter build apk --no-tree-shake-icons

Android

1.第一次失败的运行

问题描述:
➜  happy git:(dev) ✗ flutter run                              
Using hardware rendering with device sdk gphone x86 arm. If you notice graphics artifacts, consider enabling software rendering with "--enable-software-rendering".
Launching lib/main.dart on sdk gphone x86 arm in debug mode...
/happy/android/app/src/debug/AndroidManifest.xml:4:9-43 Error:
        Attribute application@label value=(medical_management) from AndroidManifest.xml:4:9-43
        is also present at [com.tencent.imsdk:imsdk-smart:5.2.210] AndroidManifest.xml:18:9-41 value=(@string/app_name).
        Suggestion: add 'tools:replace="android:label"' to <application> element at AndroidManifest.xml:3:4-40:19 to override.
                                                                        
FAILURE: Build failed with an exception.                                
                                                                        
* What went wrong:                                                      
Execution failed for task ':app:processDebugMainManifest'.              
> Manifest merger failed : Attribute application@label value=(medical_management) from AndroidManifest.xml:4:9-43
        is also present at [com.tencent.imsdk:imsdk-smart:5.2.210] AndroidManifest.xml:18:9-41 value=(@string/app_name).
        Suggestion: add 'tools:replace="android:label"' to <application> element at AndroidManifest.xml:3:4-40:19 to override.
                                                                        
* Try:                                                                  
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
                                                                        
* Get more help at https://help.gradle.org                              
                                                                        
BUILD FAILED in 22s   
问题原因:

据百度描述这个问题是项目application的label属性冲突导致,这是一个编译的常见错误,主要是AS的Gradle插件默认会启用Manifest Merger Tool,若Library项目中也定义了与主项目相同的属性(例如默认生成的android:icon和android:theme),则此时会合并失败,并报上面的错误。至于这是个什么属性,我也不是太了解,以后需要加强Android知识的学习、

解决办法:

在项目的Manifest.xml文件里的application中加入

xmlns:tools="http://schemas.android.com/tools"
tools:replace="label"

亲测有效~

2. 第一次打包报错
①问题描述:
➜  VIP-DOCTOR-NURSE-APP git:(dev) ✗ flutter build apk

Building without sound null safety
For more information see https://dart.dev/null-safety/unsound-null-safety

注: 某些输入文件使用或覆盖了已过时的 API。                              
注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。                  
注: 某些输入文件使用了未经检查或不安全的操作。                          
注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。                    
This application cannot tree shake icons fonts. It has non-constant instances of IconData at the following locations:
问题原因:

百度发现是版本问题 flutter 升级最新版本 使用 treeview 打包报错

1.打包时加上 --no-tree-shake-icons
2.将flutter sdk 版本退回到稳定版本 (生产建议用 稳定版 ,。。。。。。)

②Keystore was tampered with, or password was incorrect
FAILURE: Build failed with an exception.                                
                                                                      
* What went wrong:                                                      
Execution failed for task ':app:packageRelease'.                        
> A failure occurred while executing com.android.build.gradle.tasks.PackageAndroidArtifact$IncrementalSplitterRunnable
 > com.android.ide.common.signing.KeytoolException: Failed to read key sign from store "/Users/ytwd/项目/VIP-DOCTOR-NURSE-APP/android/app/sign.jks": Keystore was tampered with, or password was incorrect
                                                                      
* Try:                                                                  
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

问题原因:

生成sign.jks的时候秘钥混淆了,注意这里有两个pass


20200327173214447.png
解决办法:

key.properties 这个文件填写正确的信息即可

storePassword=123456
keyPassword=123456
keyAlias=sign
storeFile=sign.jks

# storeFile 签名文字
# keyAlias  文件的别名
# storepass 123456   这个是在创建签名的时候输入的  秘钥库秘钥
# keyPassword 123456    为设置的秘钥串
暂时出现上面两个问题,有问题继续更新,到这里就打包成功了
➜  VIP-DOCTOR-NURSE-APP git:(dev) ✗ flutter build apk --no-tree-shake-icons

Building without sound null safety
For more information see https://dart.dev/null-safety/unsound-null-safety

Running Gradle task 'assembleRelease'...                                
Running Gradle task 'assembleRelease'... Done                       9.8s
✓ Built build/app/outputs/flutter-apk/app-release.apk (30.4MB).

Flutter

1. Expanded 布局最常见问题
问题描述:
The following assertion was thrown while applying parent data.:
Incorrect use of ParentDataWidget.

The ParentDataWidget Expanded(flex: 1) wants to apply ParentData of type FlexParentData to a RenderObject, which has been set up to accept ParentData of incompatible type StackParentData.

Usually, this means that the Expanded widget has the wrong ancestor RenderObjectWidget. Typically, Expanded widgets are placed directly inside Flex widgets.
The offending Expanded is currently placed inside a Stack widget.

The ownership chain for the RenderObject that received the incompatible parent data was:
  Padding ← Container ← Expanded ← Stack ← Column ← Padding ← Container ← Expanded ← Row ← Padding ← ⋯
When the exception was thrown, this was the stack
#0      RenderObjectElement._updateParentData.<anonymous closure>
package:flutter/…/widgets/framework.dart:5626
#1      RenderObjectElement._updateParentData
package:flutter/…/widgets/framework.dart:5642
#2      RenderObjectElement.attachRenderObject
package:flutter/…/widgets/framework.dart:5664
#3      RenderObjectElement.mount
package:flutter/…/widgets/framework.dart:5357
#4      SingleChildRenderObjectElement.mount
package:flutter/…/widgets/framework.dart:5973
问题原因:

错误信息已经给的比较清楚的,就是Expanded组件父试图错误
看错误代码

new Expanded(
                          child: new Container(
                              padding: EdgeInsets.only(right: 38.0),
                              child: new Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: <Widget>[
                                  new Stack(
                                    children: <Widget>[
                                      new Expanded(
                                          child: new Container(
                                              padding:
                                                  EdgeInsets.only(left: 15.0),
                                              child: new Column(
                                                crossAxisAlignment:
                                                    CrossAxisAlignment.start,
                                                children: <Widget>[
                                                  new Stack(
                                                    children: <Widget>[
                                                      _rowMessgeView(message),
                                                    ],
                                                  )
                                                ],
                                              ))),
                                    ],
                                  )
                                ],
                              ))),
解决办法:

只要记住一点Expanded的上级控件一定是Column或者Row就好了

2. Flutter更新showDialog中的内容
问题描述:

在用showDialog的时候应该都遇到过这个问题,使用showDialog后,通过setState()无法更新当前dialog

问题原因:

因为dialog其实是另一个页面,准确地来说是另一个路由,因为dialog的关闭也是通过navigator来pop的,所以它的地位跟你当前主页面一样。这个概念一定要明确,因为无论在Android或iOS中,daliog都是依附于当前主页面的一个控件,但是在Flutter中不同,它是一个新的路由。所以使用当前主页面的setState()来更新,当然没法达到你要的效果。

解决办法:

所以我们有两种方法来解决这个问题,一种是使用StatefulBuilder,另一种是使用自定义的StatefulWidget。
这里只用StatefulBuilder,代码如下:


showDialog(
    context: context,
    builder: (context) {
        String label = 'test';
        return StatefulBuilder(
            builder: (context, state) {
                print('label = $label');
                return GestureDetector(
                    child: Text(label),
                    onTap: () {
                        label = 'test8';
                        print('onTap:label = $label');
                        // 注意不是调用老页面的setState,而是要调用builder中的setState。
                        //在这里为了区分,在构建builder的时候将setState方法命名为了state。
                        state(() {});  
                    },
                );
            },
         );
    });

//这里直接调用state(() {}) 代替setState(() {})
上一篇下一篇

猜你喜欢

热点阅读