如果您在版本 1.12 之前是通過 flutter create
建立專案,則這可能適用於您的專案
背景
為了更好地支援將 Flutter 新增到現有專案的執行環境,託管 Flutter 執行時的舊版 Android 平臺端包裝器位於 io.flutter.app.FlutterActivity
及其關聯的類現在已棄用。新的包裝器 io.flutter.embedding.android.FlutterActivity
及相關類替代了他們。
這些類能更好地支援實際使用情況,如 FlutterActivity 可能不是應用程式中的第一個也不是唯一的 Android Activity。
Motivation
您現有的 Full-Flutter 專案不會立即受到影響,並且在可預見的將來將繼續像以前一樣工作。
但是,新的 Android 包裝器還引入了一組新的 Android 外掛開發 API。 僅在新外掛 API 上開發的外掛不適用於較早的 1.12 版 Android 專案。使用 1.12 之後建立的外掛來構建 1.12 之前的 Android 專案,會產生構建時錯誤,除非該外掛開發人員明確選擇建立第二個向後相容的實現。
舊版 Android API 尚未正式支援“Add-to-app”。 如果您在 1.12 之前遵循 Wiki 中關於“Add-to-app”的實驗性說明,則應遵循下面 Add-to-app 部分 下的遷移步驟。
Full-Flutter 應用遷移
本指南假定您尚未手動為 Flutter 專案修改 Android host 專案。 如果您這樣做了,請查閱下面的“add-to-app”遷移指南。
如果您選擇遷移標準的 flutter create
專案,請遵循以下步驟:
- 刪除
android/app/src/main/java/[your/package/name]/MainActivity.java
。如果你沒有新增過程式碼,那麼可以直接刪掉[your/package/name]
整個包結構,因為裡面只有MainActivity.java
。 - 開啟
android/app/src/main/AndroidManifest.xml
. - 從 application 標籤中刪除
FlutterApplication
的引用
修改前:
<application
name="io.flutter.FlutterApplication"
>
<!-- code omitted -->
</application>
複製程式碼
修改後:
<application
>
<!-- code omitted -->
</application>
複製程式碼
- 修改
MainActivity
為FlutterActivity
.
修改前:
<activity android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
複製程式碼
修改後(只改了前 3 行):
<activity android:name="io.flutter.embedding.android.FlutterActivity"
android:theme="@android:style/Theme.Black.NoTitleBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
複製程式碼
- 更新 Splash 頁(如果需要初始行為)。
刪除所有鍵為 android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
的<meta-data>
標籤。
在 styles.xml
中新增一個啟動主題,將所需的啟動螢幕配置為背景`Drawable':
<!-- You can name this style whatever you'd like -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@drawable/[your_launch_drawable_here]</item>
</style>
複製程式碼
如果使用 Flutter create
建立 Flutter 專案,則可能已經定義了 LaunchTheme
以及一個名為 Launch_background
的可繪製物件。 您可以重新使用該配置並根據需要進行調整。
在 styles.xml
中新增一個普通主題,當 Android 程式完全初始化時,該主題會替換啟動螢幕:
<!-- You can name this style whatever you'd like -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@drawable/[your_normal_background_drawable]</item>
</style>
複製程式碼
"normal theme" 為您的 Flutter 體驗提供了背景。 通常會在第一個 Flutter 幀渲染之前的短暫時間內看到該背景。 在您的 Flutter 體驗期間,"normal theme" 還控制 Android 的狀態列和導航欄的視覺屬性。
配置 FlutterActivity
以 launch theme 啟動,然後再切換到 normal theme。 還指定您希望啟動螢幕繼續顯示,直到 Flutter 渲染其第一幀為止:
<activity android:name="io.flutter.embedding.android.FlutterActivity"
android:theme="@style/LaunchTheme"
// some code omitted
>
<!-- Specify that the launch screen should continue being displayed -->
<!-- until Flutter renders its first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background" />
<!-- Theme to apply as soon as Flutter begins rendering frames -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- some code omitted -->
</activity>
複製程式碼
- 在
<application>
下新增<meta-data>
標籤。
<meta-data
android:name="flutterEmbedding"
android:value="2" />
複製程式碼
您的應用仍應正常構建(例如通過 flutter build apk
構建),但是您現在正在使用新的 Android 類。
Add-to-app 遷移
本節詳細介紹如何使用 Flutter 實驗性嵌入構建的 add-to-app 場景,以及如何將該程式碼轉換為 Flutter 新的穩定嵌入。
和 full-Flutter 一樣的步驟
上面 Full-Flutter 應用遷移部分中的某些說明仍然適用。 請按照上述步驟操作:
3. 從 application 標籤中刪除 FlutterApplication
的引用
5. 更新 Splash 頁(如果需要初始行為)。
6. 在 <application>
下新增 <meta-data>
標籤。
特定於 add-to-app 的更改
如果你呼叫了 FlutterMain.startInitialization(...)
or FlutterMain.ensureInitializationComplete(...)
,應當刪除。Flutter 現在會在適當的時間進行初始化。
遷移 FlutterActivity 使用
Add-to-app 場景通常涉及對 FlutterActivity
子類的修改。 例如,這種情況下可能會引入新的MethodChannel
,自定義 FlutterEngine
例項,自定義啟動螢幕行為或其他要求覆蓋現有方法的行為。 因此,儘管全 Flutter 應用程式可以刪除其 MainActivity
並將其替換為標準FlutterActivity
,但您將需要保留子類,以便保留行為覆蓋。
如果您未修改 FlutterActivity
中的行為,則應刪除您的子類,並按照上一節中的描述將其替換為標準的 FlutterActivity
。
如果你需要修改 FlutterActivity
中的行為,你需要將程式碼從舊的 io.flutter.app.FlutterActivity
遷移到新的 io.flutter.embedding.android.FlutterActivity
。
From:
package [your.package.name];
import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
}
// ...some amount of custom code for your app is here.
}
複製程式碼
To:
package [your.package.name];
import io.flutter.embedding.android.FlutterActivity;
public class MainActivity extends FlutterActivity {
// 不再需要重寫 onCreate 來呼叫 GeneratedPluginRegistrant
// You do not need to override onCreate() in order to invoke
// GeneratedPluginRegistrant. Flutter now does that on your behalf.
// ...retain whatever custom code you had from before (if any).
}
複製程式碼
一些應用可能需要預熱 Flutter 體驗,現在建議在初次呈現 Flutter UI 時,所有 add-to-app 的用例都應使 Flutter 預熱,以達到最佳視覺效果。參考 Flutter guide for pre-warming a FlutterEngine (TODO: mattcarroll,還沒寫…) 更新你的程式碼來預熱 Flutter。
您的 FlutterActivity
子類現在已使用最新的、穩定的 Android embedding 了
遷移 FlutterFragment 使用
實驗性嵌入提供了一個名為 io.flutter.facade.FlutterFragment
的類,以及io.flutter.facade
包中的其他類。 整個 io.flutter.facade
軟體包已被棄用,您不應使用其中的任何類。
實驗性的 io.flutter.facade.FlutterFragment
被io.flutter.embedding.android.FlutterFragment
所取代,它被設計用於比原始的FlutterFragment
更廣泛的用例集合。
如果使用了 Flutter.createFragment(...)
例項化 io.flutter.facade.FlutterFragment
,則應刪除這樣的呼叫,並通過以下任一方法例項化新的io.flutter.embedding.android.FlutterFragment
:
FlutterFragment.createDefault()
FlutterFragment.withNewEngine()
FlutterFragment.withCachedEngine(...)
這些工廠方法的使用已在以下網站的網站指南中進行了深入討論: flutter.dev.
遷移 FlutterView 使用
已棄用的 io.flutter.facade.Flutter
類具有一個名為 createView(...)
的工廠方法,也已棄用,以及 io.flutter.facade
軟體包中的所有其他程式碼。
Flutter目前不提供在View級別使用Flutter的便捷API,因此如果可能,應避免使用 FlutterView
。 但是如果需要的話,顯示 FlutterView
在技術上是可行的。 確保使用io.flutter.embedding.android.FlutterView
而不是 io.flutter.view.FlutterView
。 您可以像其他任何Android View
一樣例項化新的 FlutterView
。 然後,按照相關Javadocs中的說明通過 FlutterView
顯示Flutter。