Flutter 问题集

148 阅读2分钟

1、输出非空安全插件

dart pub outdated --mode=null-safety

2、配置非空安全

// 开发工具:IDEA、VSCode、Android studio
--no-sound-null-safety
// Xcode 配置
// XCode打开项目 在Flutter下【Generated】中添加

EXTRA_FRONT_END_OPTIONS=--no-sound-null-safety

3、Android 非空安全包

flutter build apk --target-platform android-arm64 --no-sound-null-safety

4、安卓Web View插件:webview_flutter_android,设置https和http混合

// WebSettingsHostApiImpl:
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);

5、安卓采用混淆,打包后安装后无法打开

采用代码混淆后,插件无法编译。----- 根据第三方SDK,设置忽略,如问题 6

6、安卓设置混淆忽略(proguard-rules.pro)

-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.**{*;}


# Flutter
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.**  { *; }
-keep class io.flutter.util.**  { *; }
-keep class io.flutter.view.**  { *; }
-keep class io.flutter.**  { *; }
-keep class io.flutter.plugins.**  { *; }


# 极光
-keep class cn.jiguang.**{
    *;
}
-dontwarn javax.annotation.**
-dontwarn sun.misc.Unsafe
-dontwarn org.conscrypt.*
-dontwarn okio.**
-dontwarn tv.danmaku.**


###其他混淆
-keep class android.support.v4.**{
    public *;
}
-keep class android.support.v7.**{
    public *;
}


-keepclassmembers class * extends android.app.Activity { public void *(android.view.View);
}


# 友盟
-keep class com.uc.** {*;}
-keep class com.zui.** {*;}
-keep class com.miui.** {*;}
-keep class com.heytap.** {*;}
-keep class a.** {*;}
-keep class com.vivo.** {*;}


-keepclassmembers class * {
   public <init>(org.json.JSONObject);
}


-keep public class com.cry.owner.car.R$*{
public static final int *;
}


-keep class com.umeng.** {*;}


-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}


# 百度地图
-keep class org.json.** {*;}
-keep class vi.com.gdi.bgl.android.** {*;}
-keep class com.baidu.location.** {*;}
-keep class com.baidu.** {*;}
-keep class vi.com.** {*;}
-keep class com.baidu.vi.** {*;}
-keep class com.example.naveco_car_owner.** {*;}
-dontwarn com.baidu.**


# flutter_vlc_player - rtmp 拉流
-keep class org.videolan.libvlc.** { *; }

7、移除安卓SDK中未使用权限申请(AndroidManifest.xml)

<uses-permission android:name="android.permission.CALL_PHONE" tools:node="remove" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" />
<uses-permission android:name="android.permission.READ_CONTACTS" tools:node="remove" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" tools:node="remove" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" tools:node="remove" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" tools:node="remove" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" tools:node="remove" />

8、安卓APK哈希值校验

getApkSHA(mActivity?.context?.packageCodePath);

/// 获取 apk 哈希值

private fun getApkSHA(apkPath: String?) {

    try {
        val dexDigest: MessageDigest = MessageDigest.getInstance("SHA-256")
        val bytes = ByteArray(1024)
        var byteCount: Int
        val fis = FileInputStream(File(apkPath))

        while (fis.read(bytes).also { byteCount = it } > 0) {
            dexDigest.update(bytes, 0, byteCount)
        }

        val bi = BigInteger(1, dexDigest.digest())
        val sha: String = bi.toString(16)
        Log.e("getApkSHA", sha);
        invokeResult(CHANNEL_APK_SHA, sha)
        fis.close()

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

9、安卓应用包名验证

/// 获取 apk 信息
private fun getApkInfo(apkPath: String) {
    val pm: PackageManager? = mActivity?.context?.packageManager
    val pkgInfo: PackageInfo? = pm?.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES)

    if (pkgInfo != null) {
        val appInfo: ApplicationInfo = pkgInfo.applicationInfo
        appInfo.sourceDir = apkPath;
        appInfo.publicSourceDir = apkPath;
        
        val appName: String =  pm.getApplicationLabel(appInfo).toString();
        var apkName: String = appInfo.packageName;
        var version: String = pkgInfo.versionName;

        val pkgInfoMap = mapOf("PackageName" to apkName, "Version" to version, "AppName" to appName);

        Log.e("moveTaskToBack", pkgInfoMap.toString());
        invokeResult(CHANNEL_APK_INFO, apkName)
    }
}

10、引入插件

  1. 引入公共插件
dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^0.1.0
  # 新添加的依赖
  english_words: ^3.1.3
  1. 引入本地插件
dependencies:
    pkg1:
        path: ../../code/pkg1
  1. 引入Git插件
// 位于根目录
dependencies:
  pkg1:
    git:
      url: git://github.com/xxx/pkg1.git

// 位于非根目录
dependencies:
  package1:
    git:
      url: git://github.com/flutter/packages.git
      path: packages/package1