[wiki migration] Leftover wiki pages and links (#148989)

This is waiting on 
- https://github.com/flutter/flutter/pull/148777
- https://github.com/flutter/flutter/pull/148790

After this PR lands, there will likely be 1-2 more clean up PRs, after which the migration will be done!

---

This moves the remaining wiki pages as planned in [flutter.dev/go/migrate-flutter-wiki-spreadsheet](https://docs.google.com/spreadsheets/d/1x65189ZBdNiLRygpUYoU08pwvXD4M-Z157c6pm8deGI/edit?usp=sharing) 

It also adds the team labels to the label bot for future PRs.

Changes to the content were only updating cross links, or links to refer to the main branch rather than master.
Remaining links to the wiki will be updated once all other pages have finished moving, they still work in the meantime.

Part of https://github.com/flutter/flutter/issues/145009
This commit is contained in:
Kate Lovett
2024-05-28 10:12:10 -05:00
committed by GitHub
parent a1a33e63b9
commit 1fbcbb73a0
94 changed files with 271 additions and 770 deletions

View File

@@ -0,0 +1,394 @@
Hybrid composition refers to the ability of composing native views alongside Flutter widgets. For example, displaying the native Webview inside a Flutter app.
## Android
*Requires API level 19*
_See also: [Texture Layer Hybrid Composition](./android/Texture-Layer-Hybrid-Composition.md)_
Starting from Flutter 1.20.0, hybrid composition can be used on Android. This new feature fixes most of the [issues with the preview platform view approach](./android/Virtual-Display.md#associated-problems-and-workarounds) (Virtual Display); in particular, accessibility and keyboard related issues. See also [Android Platform Views](./android/Android-Platform-Views.md) for an overview of modes.
To see all known issues specific to this mode, search for the [`hc-only` label](https://github.com/flutter/flutter/labels/hc-only).
### Dart side
To start using this feature, you would need to create a `Widget`, and add the following `build` implementation:
`native_view_example.dart`
1. Add imports:
```dart
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
```
2. Implement `build` method:
```dart
Widget build(BuildContext context) {
// This is used in the platform side to register the view.
final String viewType = 'hybrid-view-type';
// Pass parameters to the platform side.
final Map<String, dynamic> creationParams = <String, dynamic>{};
return PlatformViewLink(
viewType: viewType,
surfaceFactory:
(BuildContext context, PlatformViewController controller) {
return AndroidViewSurface(
controller: controller,
gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
);
},
onCreatePlatformView: (PlatformViewCreationParams params) {
return PlatformViewsService.initSurfaceAndroidView(
id: params.id,
viewType: viewType,
layoutDirection: TextDirection.ltr,
creationParams: creationParams,
creationParamsCodec: StandardMessageCodec(),
)
..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
..create();
},
);
}
```
For more documentation see: [PlatformViewLink](https://api.flutter.dev/flutter/widgets/PlatformViewLink-class.html), [AndroidViewSurface](https://api.flutter.dev/flutter/widgets/AndroidViewSurface-class.html), [PlatformViewsService](https://api.flutter.dev/flutter/services/PlatformViewsService-class.html).
### Platform side
Finally, on the platform side, you use the standard `io.flutter.plugin.platform` package in Java or Kotlin:
`NativeView.java`
```java
package dev.flutter.example;
import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.flutter.plugin.platform.PlatformView;
class NativeView implements PlatformView {
@NonNull private final TextView textView;
NativeView(@NonNull Context context, int id, @Nullable Map<String, Object> creationParams) {
textView = new TextView(context);
textView.setTextSize(72);
textView.setBackgroundColor(Color.rgb(255, 255, 255));
textView.setText("Rendered on a native Android view (id: " + id + ")");
}
@NonNull
@Override
public View getView() {
return textView;
}
@Override
public void dispose() {}
}
```
`NativeViewFactory.java`
```java
package dev.flutter.example;
import android.content.Context;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.annotation.NonNull;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;
import java.util.Map;
class NativeViewFactory extends PlatformViewFactory {
@NonNull private final BinaryMessenger messenger;
@NonNull private final View containerView;
NativeViewFactory(@NonNull BinaryMessenger messenger, @NonNull View containerView) {
super(StandardMessageCodec.INSTANCE);
this.messenger = messenger;
this.containerView = containerView;
}
@NonNull
@Override
public PlatformView create(@NonNull Context context, int id, @Nullable Object args) {
final Map<String, Object> creationParams = (Map<String, Object>) args;
return new NativeView(context, id, creationParams);
}
}
```
Register the platform view. This can be done in an app or a plugin.
For app registration, modify the main activity (e.g. `MainActivity.java`):
```java
package dev.flutter.example;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
public class MainActivity extends FlutterActivity {
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
flutterEngine
.getPlatformViewsController()
.getRegistry()
.registerViewFactory("<platform-view-type>", new NativeViewFactory());
}
}
```
For plugin registration, modify the main plugin file (e.g. `PlatformViewPlugin.java`):
```java
package dev.flutter.plugin.example;
import androidx.annotation.NonNull;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.BinaryMessenger;
public class PlatformViewPlugin implements FlutterPlugin {
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
binding
.getFlutterEngine()
.getPlatformViewsController()
.getRegistry()
.registerViewFactory("<platform-view-type>", new NativeViewFactory());
}
}
```
For more documentation, see [PlatformViewRegistry](https://api.flutter.dev/javadoc/io/flutter/plugin/platform/PlatformViewRegistry.html), [PlatformViewFactory](https://api.flutter.dev/javadoc/io/flutter/plugin/platform/PlatformViewFactory.html), and [PlatformView](https://api.flutter.dev/javadoc/io/flutter/plugin/platform/PlatformView.html).
Finally, indicate the minimum API Level required for the application to run in `build.gradle`.
```groovy
android {
defaultConfig {
minSdkVersion 19
}
}
```
## iOS
In Flutter 1.22, platform views are enabled by default. This means
that it's no longer required to add the
`io.flutter.embedded_views_preview` flag to `Info.plist`.
To create a platform view on iOS, follow these steps:
### On the Dart side
On the Dart side, create a `Widget`
and add the following build implementation,
as shown in the following steps.
In your Dart file, for example `native_view_example.dart`,
do the following:
1. Add the following imports:
<!-- skip -->
```dart
import 'package:flutter/widget.dart';
```
2. Implement a `build()` method:
<!-- skip -->
```dart
Widget build(BuildContext context) {
// This is used in the platform side to register the view.
final String viewType = '<platform-view-type>';
// Pass parameters to the platform side.
final Map<String, dynamic> creationParams = <String, dynamic>{};
return UiKitView(
viewType: viewType,
layoutDirection: TextDirection.ltr,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
);
}
```
For more information, see the API docs for:
[`UIKitView`](https://api.flutter.dev/flutter/widgets/UiKitView-class.html).
### On the platform side
In your native code, implement the following:
`FLNativeView.h`
```objc
#import <Flutter/Flutter.h>
@interface FLNativeViewFactory : NSObject <FlutterPlatformViewFactory>
- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
@end
@interface FLNativeView : NSObject <FlutterPlatformView>
- (instancetype)initWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger;
- (UIView*)view;
@end
```
Implement the factory and the platform view in `FLNativeView.m`
```objc
#import "FLNativeView.h"
@implementation FLNativeViewFactory {
NSObject<FlutterBinaryMessenger>* _messenger;
}
- (instancetype)initWithMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
self = [super init];
if (self) {
_messenger = messenger;
}
return self;
}
- (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args {
return [[FLNativeView alloc] initWithFrame:frame
viewIdentifier:viewId
arguments:args
binaryMessenger:_messenger];
}
@end
@implementation FLNativeView {
UIView *_view;
}
- (instancetype)initWithFrame:(CGRect)frame
viewIdentifier:(int64_t)viewId
arguments:(id _Nullable)args
binaryMessenger:(NSObject<FlutterBinaryMessenger>*)messenger {
if (self = [super init]) {
_view = [[UIView alloc] init];
}
return self;
}
- (UIView*)view {
return _view;
}
@end
```
Finally, register the platform view. This can be done in an app or a plugin.
For app registration, modify the App's `AppDelegate.m`:
```objc
#import "AppDelegate.h"
#import "FLNativeView.h"
#import "GeneratedPluginRegistrant.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
NSObject<FlutterPluginRegistrar>* registrar =
[self registrarForPlugin:@"plugin-name"];
FLNativeViewFactory* factory =
[[FLNativeViewFactory alloc] initWithMessenger:registrar.messenger];
[[self registrarForPlugin:@"<plugin-name>"] registerViewFactory:factory
withId:@"<platform-view-type>"];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
```
For plugin registration, modify the main plugin file (e.g. `FLPlugin.m`):
```objc
#import "FLPlugin.h"
#import "FLNativeView.h"
@implementation FLPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FLNativeViewFactory* factory =
[[FLNativeViewFactory alloc] initWithMessenger:registrar.messenger];
[registrar registerViewFactory:factory withId:@"<platform-view-type>"];
}
@end
```
For more information, see the API docs for:
* [`FlutterPlatformViewFactory`](https://api.flutter.dev/objcdoc/Protocols/FlutterPlatformViewFactory.html)
* [`FlutterPlatformView`](https://api.flutter.dev/objcdoc/Protocols/FlutterPlatformView.html)
* [`PlatformView`](https://api.flutter.dev/javadoc/io/flutter/plugin/platform/PlatformView.html)
By default, the `UIKitView` widget appends the native `UIView` to the view hierarchy. For more documentation, see [UIKitView](https://api.flutter.dev/flutter/widgets/UiKitView-class.html).
## Performance
Platform views in Flutter come with performance trade-offs.
For example, in a typical Flutter app, the Flutter UI is composed
on a dedicated raster thread. This allows Flutter apps to be fast,
as the main platform thread is rarely blocked.
While a platform view is rendered with Hybrid Composition, the Flutter UI is composed from
the platform thread, which competes with other tasks like
handling OS or plugin messages, etc.
Prior to Android 10, Hybrid Composition copies each Flutter frame
out of the graphic memory into main memory and then copied back to
a GPU texture. As this copy happens per frame, the performance of
the entire Flutter UI may be impacted.
On the other hand, Virtual Display makes each pixel of the native view
flow through additional intermediate graphic buffers, which cost graphic
memory and drawing performance.
For complex cases, there are some techniques that can be used to mitigate
these issues.
For example, you could use a placeholder texture while an animation is
happening in Dart. In other words, if an animation is slow while a
platform view is rendered, then consider taking a screenshot of the
native view and rendering it as a texture.
For more information, see:
* [`TextureLayer`](https://api.flutter.dev/flutter/rendering/TextureLayer-class.html)
* [`TextureRegistry`](https://api.flutter.dev/javadoc/io/flutter/view/TextureRegistry.html)
* [`FlutterTextureRegistry`](https://api.flutter.dev/objcdoc/Protocols/FlutterTextureRegistry.html)

View File

@@ -30,7 +30,7 @@ within their Flutter UI.
There are currently three different implementations of Android platform views:
- [Virtual Display](Virtual_Display.md) (VD)
- [Hybrid Composition](https://github.com/flutter/flutter/wiki/Hybrid-Composition) (HC)
- [Hybrid Composition](../Hybrid-Composition.md) (HC)
- [Texture Layer Hybrid Composition](Texture-Layer-Hybrid-Composition.md) (TLHC)
Each has a different set of limitations and tradeoffs, as discussed below. The pages linked above give details about each implementation.

View File

@@ -0,0 +1,73 @@
Support a new android API level flutter
go/flutter-android-new-api-level
## Objective
Provide a list of areas to consider and examples of former work for how to update flutter to support a new version of the android API. This happens every fall and flutter developers expect to build against the latest versions quickly after they are available.
### Overview
#### New Android features
New android features can require a broad spectrum of work. Some will require nothing from flutter. Some will require a lot of work, such as the support for “back preview”. The android team generally needs to be aware and schedule work ahead of time.
#### Update Gradle/AGP support
Sometimes newer versions of gradle are required to build without warning against a new version of android api. The warning looks like
```
WARNING:We recommend using a newer Android Gradle plugin to use compileSdkPreview = "somenamedversion"
This Android Gradle plugin (X.X.X) was tested up to compileSdk = XX
```
Bump the gradle version used in the engine.
#### Update Robolectric
Robolectric is a dependency that allows us to write unit tests that run on a local development machine against the android api surface without being on an android device.
Update what version of Robolectric we use in framework, engine and packages.
Example packages: https://github.com/flutter/packages/pull/4018
Example engine: https://github.com/flutter/engine/pull/42965
#### Update CI
Update emulator and/or physical device testing to use the new android api version for framework, engine and packages.
Firebase test lab emulators and physical devices need support from the firebase team
Run command `gcloud firebase test android models list` [documentation](https://firebase.google.com/docs/test-lab/android/available-testing-devices) to see available devices.
Flutter managed Emulators (engine) require a new AVD image to one that supports the new api: https://flutter-review.googlesource.com/c/recipes/+/45049
Example Framework: https://flutter-review.googlesource.com/c/recipes/+/45048
Example Engine: https://github.com/flutter/engine/pull/42492
Packages
Modify https://github.com/flutter/packages/blob/main/.cirrus.yml “firebase_test_lab_script”
Specifically the value for “--device” `./script/tool_runner.sh firebase-test-lab --device model=redfin,version=30 --exclude=script/configs/exclude_integration_android.yaml`
https://github.com/flutter/packages/pull/4430
#### Update documentation
Update documentation page to indicate the new api is tested
https://docs.flutter.dev/reference/supported-platforms
#### Modify defaults
In flutter/flutter:
Update default compile sdk version and target sdk version to the new api value
[Code here](../../../packages/flutter_tools/gradle/src/main/groovy/flutter.groovy)
Follow comments in that file to update other locations that are assumed to be the same.
Example bumping min sdk which is similar but different: https://github.com/flutter/flutter/pull/125515
In flutter/buildroot:
Upload new android sdk version to CIPD (steps at end of document)
Update default android sdk version
https://github.com/flutter/buildroot/blob/7984a08044b94bfb4c466ac881c6b56fdfe9148b/build/config/android/config.gni#L19
In flutter/engine:
Update android SDK in DEPS file
https://github.com/flutter/engine/blob/9289cb6a36aa86990e3ffe0f20324dafa38e7c11/DEPS#L731
Update buildroot version in DEPS file to consume the changes in the flutter/buildroot steps above
https://github.com/flutter/engine/blob/9289cb6a36aa86990e3ffe0f20324dafa38e7c11/DEPS#L260
In flutter/packages
Set examples to build with the new api.
#### Test “Integration Test” package
Integration test is a package shipped in the flutter tool for running integration tests on flutter apps. Ensure that the integration test package has an example that targets the new api level on the most recent published stable version of the flutter tool.
#### Related documents
[Emulators for Flutter Android Testing (PUBLICLY SHARED)](https://docs.google.com/document/d/10wYUcLcSTF4Epg2EUGoBqOkkOe4zxKHvYKjXFZAOgGs/edit?resourcekey=0-pltjPvEtVezXDADMbUwFHQ)
### Additional notes
#### Upload new SDK version to CIPD and consume in buildroot
Make a fork of the [buildroot](https://github.com/flutter/buildroot) if you havent yet.
Get CIPD temporary write access, if you dont have it:
Make a github issue describing that there is a new android release that needs to be uploaded to CIPD
Go to [go/flutter-luci-cipd#requesting-writeread-access-to-cipd-packages](http://goto.google.com/flutter-luci-cipd#requesting-writeread-access-to-cipd-packages) and click request access on the hyperlinked page
Fill out the justification with b/12345 - <your GitHub issue> (the form requires a buganizer link, and the addition of b/12345 satisfies this).
Reach out to someone on the infra team to get your request approved
Run the [create_cipd_packages.sh script](https://github.com/flutter/engine/blob/a2adaa39a2c35d1ab23394d550c9a7e50fe41fe9/tools/android_sdk/create_cipd_packages.sh) with your desired version tag (note that there is a .ci.yaml validation step that requires this version tag to be a combination of lowercase letters and numbers). The script pulls the version that will be uploaded from the packages.txt file in the same subdirectory.
The remaining steps are to consume the changes in the buildroot, and then consume those buildroot changes in the engine.

View File

@@ -1,4 +1,4 @@
_See also: [Hybrid Composition|Hybrid Composition#Android](https://github.com/flutter/flutter/wiki/Hybrid-Composition)_
_See also: [Hybrid Composition|Hybrid Composition#Android](../Hybrid-Composition.md)_
# Background

View File

@@ -0,0 +1,136 @@
(This wiki page applies to people migrating code written before December 2017. It is unlikely to still be relevant.)
## Introduction
Prior to [#13492](https://github.com/flutter/flutter/pull/13492) (merged on 2017-12-13), Flutter tooling created projects whose Android part used Gradle 3.3 and the Android Studio Gradle plugin version 2.3.3.
After #13492, Flutter tooling creates projects based on Gradle 4.1 and the Android Studio Gradle plugin version 3.0.1.
This page describes how you can manually upgrade your Flutter projects from the old mode to the new one. This may be needed to consume new-mode Flutter plugins.
Where in doubt, please consult https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html.
## Upgrading a Flutter app project
1. In `android/gradle/wrapper/gradle-wrapper.properties`, replace `3.3` with `4.1` in the last line.
1. In `android/build.gradle`, replace
```gradle
repositories {
jcenter()
maven {
url "https://maven.google.com"
}
}
```
by
```gradle
repositories {
google()
jcenter()
}
```
twice.
Also replace
```gradle
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
}
```
by
```gradle
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
}
```
Finally, replace
```gradle
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
project.evaluationDependsOn(':app')
}
```
by
```gradle
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
```
This change prevents a "Gradle build failed to produce an Android package" error message when your app
depends on plugins whose name comes before "app" in lexicographic order.
1. In `android/app/build.gradle`, replace version `25` by `27` and `25.0.3` by `27.0.3` (three places total).
If you are using a version of Flutter from before [#13558](https://github.com/flutter/flutter/pull/13558),
add the following to the `android`,`buildTypes` section:
```yaml
profile {
matchingFallbacks = ['debug', 'release']
}
```
Replace configurations named `compile` by `api` (or `implementation`) and `provided` by
`compileOnly` in the `dependencies` section. You may also want to update dependencies with newer
versions as applicable. In the default project templates generated by Flutter tooling we have replaced
```gradle
dependencies {
androidTestCompile 'com.android.support:support-annotations:25.4.0'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'
}
```
by
```gradle
dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
```
loosely following the lead of Android Studio.
## Upgrading a Flutter plugin project
1. Upgrade the `example/` Flutter app project as indicated above.
1. Remove the Gradle wrapper files and folder (`gradlew`, `gradlew.bat`, `gradle/`) from the top-level
`android` folder, if present. The Gradle wrapper is used by the `example` app only, and it should
already contain these files.
1. In `android/build.gradle`, replace
```gradle
repositories {
jcenter()
maven {
url "https://maven.google.com"
}
}
```
by
```gradle
repositories {
google()
jcenter()
}
```
twice.
Also replace
```gradle
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
}
```
by
```gradle
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
}
```
Replace version `25` by `27` and `25.0.3` by `27.0.3`.
Lastly, replace configurations named `compile` by `api` (or `implementation`) and `provided` by `compileOnly`
in any custom `dependencies` section.

View File

@@ -0,0 +1,97 @@
(This wiki page applies to people migrating code written before February 2017. It is unlikely to still be relevant. The `flutter` tool directs people to this page when a non-Gradle project is detected.)
## Introduction
Prior to [Pull Request 7902](https://github.com/flutter/flutter/pull/7902) -- which was merged to master on February 6th 2017 -- we used a custom build process when building for Android. We now build for Android using the same standard 'gradle-based' build process that Android Studio project uses. This makes it easier to edit the native Android code; after the upgrade you can open the `android` folder in Android Studio, and it will know how to build the project, and will allow you to add java code.
If you have a project that was created prior to this date, please follow these steps to switch to building with gradle. This is required as we will be removing the custom build support shortly.
*Note*: These steps apply to projects created with `flutter create` prior to February 6th 2017. If your project was based on a copy of `/examples/hello_services/`, then you just need to synchronize the contents of [`/android/build.gradle`](../../../packages/flutter_tools/templates/create/android.tmpl/build.gradle) and [`/android/app/build.gradle`](../../../packages/flutter_tools/templates/create/android.tmpl/app/build.gradle).
## Upgrading an existing project
The steps below use `<existing-app-dir>` as a placeholder for the directory containing your existing app, e.g. `~/dev/flutter/awesomeapp`.
### Step 0: Ensure flutter is up to date
Make sure you flutter SDK is up to date. You need a recent (March 1st, 2017 later) SDK from the master branch of https://github.com/flutter/flutter.
You can upgrade by running `flutter upgrade` in a terminal.
### Step 1: Create a new project with the new template
```
flutter create <appname>
mv <appname>/lib <appname>/lib.template
```
### Step 2: Merge over your Flutter UI code
Main Dart UI code:
```
cp -r <existing-app-dir>/lib <appname>/
```
If `<existing-app-dir>/assets` exists:
```
cp -r <existing-app-dir>/assets <appname>/
```
### Step 3: Synchronize AndroidManifest.xml
**Note:** This step is only required if you made any changes to<br>`<existing-app-dir>android/AndroidManifest.xml`
If that is the case, apply those changes to the new manifest,<br> `<appname>/android/app/src/main/AndroidManifest.xml`
### Step 4: Synchronize pubspec.yaml
**Note:** This step is only required if you made any changes to<br>`<existing-app-dir>/pubspec.yaml`
If that is the case, apply those changes to the new manifest,<br>`<appname>/pubspec.yaml`
### Step 5: Move icon resources, and other resources as applicable
**Note:** This step is only required if your app has custom launcher icons.
```
cp -r <existing-app-dir>/android/res <appname>android/app/src/main/
```
Repeat this for any other resources you may have.
### Step 6: Move over iOS code if applicable
**Note:** This step is only required if your app has any custom iOS code.
```
mv <appname>/ios <appname>/ios.template
cp -r <existing-app-dir>/ios/ <appname>
```
### Step 7: Validate you can build, and clean-up
When you are done, the structure of your `android` folder should match that of a new flutter project created with `flutter create` using a recent framework.
Validate that you can build for both Android and iOS. *Note*: The first build will take a little longer (as it will download and then cache a few gradle files).
```
cd <appname>
flutter build apk
flutter build ios
```
Finally, once you are sure everything is working as intended, consider removing the `.template` folders.
## Working with the project after upgrading
You can still build with `flutter build apk` and run with `flutter run`.
In addition, you can edit and build from Android Studio:
1. Start Android Studio
1. Invoke File > Open...
1. Select the `android` folder inside your <newapp> folder, and press OK
1. Press the Run button, or use the Run > Run menu item to build and run the app
1. Edit java code by locating the .java file in the file tree on the right hand side.

View File

@@ -0,0 +1,32 @@
Flutter includes support for developing on macOS devices with [Apple Silicon (M1) hardware](https://www.apple.com/mac/m1/). This wiki page documents ongoing work relating to the Flutter toolchain providing native support for this processor architecture.
We recommend using Flutter 2.5 or later on Apple Silicon machines. You must also have the [Rosetta 2 translation environment](https://developer.apple.com/documentation/apple_silicon/about_the_rosetta_translation_environment) available, which you can install manually by running:
```sh
$ sudo softwareupdate --install-rosetta --agree-to-license
```
If you see CocoaPods crashes related to `ffi`, try reinstalling the Ruby gem with the `--enable-libffi-alloc` flag:
```
sudo gem uninstall ffi && sudo gem install ffi -- --enable-libffi-alloc
```
## Using macOS on Apple Silicon to develop Flutter apps (host)
You can use Apple Silicon-based Mac devices as a developer workstation (host) for building Flutter apps. While some tools still use Rosetta, Apple Silicon-based Macs are fully supported as a host.
As we build more Apple Silicon support into the tooling, and depending on your tolerance for risk, [you may want to experiment with the `beta` channel](https://flutter.dev/docs/development/tools/sdk/upgrading#switching-flutter-channels). (This was previously also available on the dev channel, but [it has been retired](https://medium.com/flutter/whats-new-in-flutter-2-8-d085b763d181#34c4).)
[Issue 60118](https://github.com/flutter/flutter/issues/60118) tracks the full set of work to support this feature.
## Developing Flutter apps for macOS running on Apple Silicon (target)
Flutter has [support for building macOS apps](https://flutter.dev/desktop), with beta snapshots available in the `stable` channel and ongoing development taking place.
Compiled Intel macOS binaries work on Apple Silicon without change thanks to the [Rosetta 2 translation environment](https://developer.apple.com/documentation/apple_silicon/about_the_rosetta_translation_environment), which converts x86_64 instructions to ARM64 equivalents.
We also plan to offer support for compilation directly to ARM64, as well as universal binaries that combine x86_64 and ARM64 assets. [Issue 60113](https://github.com/flutter/flutter/issues/60113) is the umbrella bug tracking this work.
## Filing Issues
If you experience a problem relating to using Flutter on Apple Silicon hardware, please [file an issue on GitHub](https://github.com/flutter/flutter/issues/new?template=1_activation.yml) with specific repro steps and information about your hardware and software configuration (paste the results of `flutter doctor -v`). Thank you!

View File

@@ -0,0 +1,14 @@
## Microsoft Active Accessibility
Microsoft Active Accessibility (MSAA) is an older interface used for accessibility. It can interact with screen readers such as Windows Narrator or NVDA, and has a more limited set of available functionality compared to newer interfaces.
The base of MSAA is the `IAccessible` interface, which all a11y-providing classes extend. MSAA methods are prefixed with `acc_`. In the Flutter engine, `AXPlatformNodeWin` extends `IAccessible`. Any `IAccessible` objects used are COM interfaces, and should be initialized and reference counted accordingly.
When a program such a screen reader queries an application for an a11y object, it sends a `WM_GETOBJECT` window message, to which the window will respond with the result of passing the `IAccessible` of its root to the function `LresultFromObject`.
## UI Automation
UI Automation is one framework for Windows that is used for accessibility, for example, by screen readers such as Windows Narrator or NVDA. The interface class `IRawElementProviderFragment` must be implemented by any object representing a UIA fragment, i.e. an accessibility item that exists on the screen, such as a text label, a pane, a button, etc.. For the Flutter engine, the class `AXPlatformNodeWin` extends `IRawElementProviderFragment` in order to serve this purpose. Abstract methods in `IRawElementProviderFragment` provide functionality including retrieving the bounds of the fragment on screen, testing if an on-screen point is within the fragment, and retrieving properties of the fragment such as name and role. Each of the methods of `IRawElementProviderFragment` implemented by `AXPlatformNodeWin` are listed in `ax_platform_node_win.h`. Additionally, `IRawElementProviderFragment` contains a method that returns the fragment root of the fragment.
The fragment root represents the root of a fragment tree, and extends the class `IRawElementProviderFragmentRoot`. Generally, and in the case of Flutter, these correspond 1-1 to a window. We extend this class in `AXFragmentRootPlatformNodeWin` in ax_fragment_root_win.cc. This class contains methods to retrieve the fragment at a given point, and the current focus of the tree.
The Window classs `OnGetObject` handles WM_GETOBJECT window messages, which a screen reader will dispatch to access the UIA fragment tree. When the `lparam` parameter of the message is equal to the constant `UiaRootObjectId`, the request is asking for the UIA root, and a reference is created out of the windows fragment root with `UiaReturnRawElementProvider`, which is then returned to the message sender.
Patterns are optional interfaces which UIA elements can provide for additional functionality. For example, providing the `ITextProvider` allows a fragment to be treated as formatted text, and `IToggleProvider` indicates that a fragment can be toggled (e.g. a checkbox) and provides its current toggle state (i.e. on, off, mixed). The UIA method `GetPatternProvider` is used to return an instance of a requested interface type, or none if it is not provided. Provided patterns may or may not be the same as the fragment itself. For example, in `AXPlatformNodeWin`, when `IToggleProvider` is requested, a casted pointer to the node is returned, as `AXPlatformNodeWin` extends `IToggleProvider`. By contrast, when an `ITextProvider` is requested, a separate object is returned, rather than `AXPlatformNodeWin` being a subclass of `ITextProvider`. In this case, this is necessary, as other inherited methods of `AXPlatformNodeWin` share a name but different signature to those in `ITextProvider`, so it cannot extend both.
Whether or not the engine makes use of UI Automation is controlled in the `Window` class, in `Window::OnGetObject`. When a UIA message is received, a UIA response is only issued if the engine was built with the `FLUTTER_ENGINE_USE_UIA` macro defined.