[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:
394
docs/platforms/Hybrid-Composition.md
Normal file
394
docs/platforms/Hybrid-Composition.md
Normal 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)
|
||||
@@ -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.
|
||||
|
||||
73
docs/platforms/android/New-Android-version.md
Normal file
73
docs/platforms/android/New-Android-version.md
Normal 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 haven’t yet.
|
||||
Get CIPD temporary write access, if you don’t 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.
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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!
|
||||
14
docs/platforms/desktop/windows/Accessibility-on-Windows.md
Normal file
14
docs/platforms/desktop/windows/Accessibility-on-Windows.md
Normal 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 class’s `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 window’s 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.
|
||||
Reference in New Issue
Block a user