Flutter Android 1.12 遷移指南

翻譯自 github.com/flutter/flu…java

若是您在版本 1.12 以前是經過 flutter create 建立項目,則這可能適用於您的項目android

背景

爲了更好地支持將 Flutter 添加到現有項目的執行環境,託管 Flutter 運行時的舊版 Android 平臺端包裝器位於 io.flutter.app.FlutterActivity 及其關聯的類如今已棄用。新的包裝器 io.flutter.embedding.android.FlutterActivity 及相關類替代了他們。git

這些類能更好地支持實際使用狀況,如 FlutterActivity 可能不是應用程序中的第一個也不是惟一的 Android Activity。github

Motivation

您現有的 Full-Flutter 項目不會當即受到影響,而且在可預見的未來將繼續像之前同樣工做。shell

可是,新的 Android 包裝器還引入了一組新的 Android 插件開發 API。 僅在新插件 API 上開發的插件不適用於較早的 1.12 版 Android 項目。使用 1.12 以後建立的插件來構建 1.12 以前的 Android 項目,會產生構建時錯誤,除非該插件開發人員明確選擇建立第二個向後兼容的實現。app

舊版 Android API 還沒有正式支持「Add-to-app」。 若是您在 1.12 以前遵循 Wiki 中關於「Add-to-app」的實驗性說明,則應遵循下面 Add-to-app 部分 下的遷移步驟。ide

Full-Flutter 應用遷移

本指南假定您還沒有手動爲 Flutter 項目修改 Android host 項目。 若是您這樣作了,請查閱下面的「add-to-app」遷移指南。網站

若是您選擇遷移標準的 flutter create 項目,請遵循如下步驟:ui

  1. 刪除 android/app/src/main/java/[your/package/name]/MainActivity.java。若是你沒有添加過代碼,那麼能夠直接刪掉 [your/package/name]整個包結構,由於裏面只有MainActivity.java
  2. 打開 android/app/src/main/AndroidManifest.xml.
  3. 從 application 標籤中刪除 FlutterApplication 的引用

修改前:this

<application name="io.flutter.FlutterApplication" >
  <!-- code omitted -->
</application>
複製代碼

修改後:

<application >
  <!-- code omitted -->
</application>
複製代碼
  1. 修改 MainActivityFlutterActivity.

修改前:

<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>
複製代碼
  1. 更新 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>
複製代碼
  1. <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.FlutterFragmentio.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。

相關文章
相關標籤/搜索