Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding plugin migration page. #3249

Merged
merged 1 commit into from
Nov 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/_data/sidenav.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@
permalink: /docs/development/packages-and-plugins/developing-packages
- title: Background processes
permalink: /docs/development/packages-and-plugins/background-processes
- title: Plugin migration
permalink: /docs/development/packages-and-plugins/plugin-api-migration
- title: Package site
permalink: https://pub.dev/flutter
- title: Add Flutter to existing app
Expand Down
73 changes: 42 additions & 31 deletions src/docs/development/packages-and-plugins/androidx-compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@ description: How to fix AndroidX incompatibilities that have been detected by th
---

{{site.alert.note}}
You might be directed to this page if the framework detects a problem in your
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought I left some comments here yesterday but I can't find it anymore. It might not have gone through.

I unfortunately have to revert the non-add-to-app changes in this add-to-app branch. Keeping 2 branches is difficult but feasible for purely additive changes. But for changes on existing files like this, it's hard to merge since the base text already changed on master (specifically for this file, it already moved on master). I tried to manually downport some of the non-add-to-app changes back to master but since the base text was so different, I think it's going to be easier to just re-create these changes directly on an up-to-date master.

TL;DR the new plugin-api-migration.md and sidenav.yml will be mergeable to master but the rest will be difficult.

Flutter app involving AndroidX incompatibilities.
You might be directed to this page if the framework detects a
problem in your Flutter app involving AndroidX incompatibilities.
{{site.alert.end}}

Android code often uses the
[`android.support`]({{site.android-dev}}/topic/libraries/support-library/)
libraries to ensure backwards compatibility. The `android.support`
libraries are deprecated, and replaced with
[AndroidX]({{site.android-dev}}/jetpack/androidx/).
Android code often uses the [`android.support`][]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few instances of replacing links with [foo][]. Why is this preferable? It seems like it's easier to end up with broken links.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is our convention. The text is far more readable without the inline link. And Travis tells us of broken links.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is Travis a human or a bot? It would nice to have the validation automated since it's almost impossible to review visually.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Travis is a CI tool. We used to use it on flutter/flutter, but now it's Cirrus. Very much a bot. :) . We also run a weekly linkcheck over the site.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, phew. I didn't want a real Travis to be hurt about me not knowing if they were a bot or not. I think bot Travis will get over it.

libraries to ensure backwards compatibility.
The `android.support` libraries are deprecated,
and replaced with [AndroidX][].
AndroidX has feature parity with the old libraries
with some additional capabilities but, unfortunately, these two sets of
libraries are incompatible.
with some additional capabilities but, unfortunately,
these two sets of libraries are incompatible.

_Gradle crashes when trying to build an APK that relies on both sets
of libraries._ This page explains how you can workaround this issue.
Expand All @@ -29,9 +28,10 @@ AndroidX can break a Flutter app at compile time in two ways:
2. The app uses both deprecated and AndroidX code at the same time.

The error messages from Gradle vary. Sometimes the messages mention
"package androidx" or "package android.support" directly. However, often the
Gradle error messages aren't obvious, and instead talk about
"AAPT," "AAPT2," or otherwise mention failing at "parsing resources."
"package androidx" or "package android.support" directly.
However, often the Gradle error messages aren't obvious,
and instead talk about "AAPT," "AAPT2,"
or otherwise mention failing at "parsing resources."

These problems must be fixed by either manually migrating the
code to the same library, or downgrading to versions of the plugins
Expand All @@ -43,16 +43,14 @@ that still use the original support libraries.
It's impossible to fully migrate your app to AndroidX if it's
actively using any plugins that rely on the old support library.
If your app depends on plugins that use the old `android.support`
packages, you'll need to [avoid using AndroidX](#avoiding-androidx).
packages, you'll need to [avoid using AndroidX][].
{{site.alert.end}}

First make sure that `compileSdkVersion` is at least `28` in
`app/build.gradle`. This property controls the version of the
Android SDK that Gradle uses to build your APK. It doesn't affect
the minimum SDK version that your app can run on. See the Android
developer docs on [the module-level build
file]({{site.android-dev}}/studio/build/#module-level)
for more information.
developer docs on the [module-level build file][] for more information.

#### Recommended: Use Android Studio to migrate your app

Expand All @@ -61,18 +59,20 @@ Use the following instructions:

1. Import your Flutter app into Android Studio so that the IDE can
parse the Android code following the steps in
[Editing Android code in Android Studio with full IDE
support](/docs/development/tools/android-studio#android-ide).
2. Follow the instructions for [Migrating to
AndroidX]({{site.android-dev}}/jetpack/androidx/migrate).
[Editing Android code in Android Studio with full IDE support][].
2. Follow the instructions for [Migrating to AndroidX][].

#### Not recommended: Manually migrate your app

See [Migrating to
AndroidX]({{site.android-dev}}/jetpack/androidx/migrate) for more detailed
instructions on how to do this. Below are some steps that you'll likely need to go through as part of this process, listed here for reference. However the specific things you need to do will depend on your build configuration and could differ from the example changes suggested here.
See [Migrating to AndroidX][] for more detailed instructions
on how to do this. Below are some steps that you'll likely
need to go through as part of this process,
listed here for reference. However the specific things
you need to do will depend on your build configuration
and could differ from the example changes suggested here.

1. In `android/gradle/wrapper/gradle-wrapper.properties` change the line starting with `distributionUrl` like this:
1. In `android/gradle/wrapper/gradle-wrapper.properties`,
change the line starting with `distributionUrl` like this:

```
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
Expand All @@ -94,7 +94,7 @@ instructions on how to do this. Below are some steps that you'll likely need to
}
```

3. In `android/gradle.properties`, append
3. In `android/gradle.properties`, append the following:

```
android.enableJetifier=true
Expand All @@ -103,9 +103,12 @@ instructions on how to do this. Below are some steps that you'll likely need to

4. In `android/app/build.gradle`:

Under `android {`, make sure `compileSdkVersion` and `targetSdkVersion` are at least 28.
Under `android {`, make sure `compileSdkVersion` and
`targetSdkVersion` are at least 28.

5. Replace all deprecated libraries with the AndroidX equivalents. For instance, if you're using the default `.gradle` files make the following changes:
5. Replace all deprecated libraries with the AndroidX equivalents.
For instance, if you're using the default `.gradle` files
make the following changes:

In `android/app/build.gradle`

Expand Down Expand Up @@ -181,12 +184,11 @@ coming from another plugin besides these.

## For plugin maintainers: Migrating a Flutter plugin to AndroidX

Migrating a Flutter plugin to AndroidX follows basically the same process as
[migrating a Flutter app](#how-to-migrate-a-flutter-app-to-androidx),
Migrating a Flutter plugin to AndroidX follows basically
the same process as [migrating a Flutter app][],
but with some additional concerns and some slight changes.

1. Make sure to increment the [major
version]({{site.dart-site}}/tools/pub/versioning#semantic-versions) of
1. Make sure to increment the [major version][] of
your plugin for this change and clearly document it in your plugin's
changelog. This breaking change requires manual migration for
users to fix. Pub treats digits differently depending on whether
Expand All @@ -198,3 +200,12 @@ but with some additional concerns and some slight changes.
IDE as if it's a regular Flutter app. Android Studio also imports and
parses the plugin's Android code.


[`android.support`]: {{site.android-dev}}/topic/libraries/support-library/
[AndroidX]: {{site.android-dev}}/jetpack/androidx/
[avoid using AndroidX]: #avoiding-androidx
[Editing Android code in Android Studio with full IDE support]: /docs/development/tools/android-studio#android-ide
[major version]: {{site.dart-site}}/tools/pub/versioning#semantic-versions
[Migrating to AndroidX]: {{site.android-dev}}/jetpack/androidx/migrate
[module-level build file]: {{site.android-dev}}/studio/build/#module-level
[migrating a Flutter app]: #how-to-migrate-a-flutter-app-to-androidx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ You’ll set up your isolate for background execution using callbacks and
a callback dispatcher.

For more information and a geofencing example that uses background
execution of Dart code, see [Executing Dart in the Background with
Flutter Plugins and
Geofencing]({{site.flutter-medium}}/executing-dart-in-the-background-with-flutter-plugins-and-geofencing-2b3e40a1a124),
execution of Dart code, see
[Executing Dart in the Background with Flutter Plugins and Geofencing][],
an article in the Flutter Publication on Medium. At the end of this article,
you’ll find links to example code, and relevant documentation for Dart,
iOS, and Android.


[Executing Dart in the Background with Flutter Plugins and Geofencing]: {{site.flutter-medium}}/executing-dart-in-the-background-with-flutter-plugins-and-geofencing-2b3e40a1a124
109 changes: 60 additions & 49 deletions src/docs/development/packages-and-plugins/developing-packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ description: How to write packages and plugins for Flutter.

## Package introduction

Packages enable the creation of modular code that can be shared easily. A
minimal package consists of:
Packages enable the creation of modular code that can be shared easily.
A minimal package consists of:

* A `pubspec.yaml` file: A metadata file that declares the package name,
version, author, etc.
Expand All @@ -17,25 +17,24 @@ minimal package consists of:

{{site.alert.note}}
For a list of dos and don'ts when writing an effective plugin,
see [Writing a good
plugin]({{site.flutter-medium}}/writing-a-good-flutter-plugin-1a561b986c9c)
on Medium.
see [Writing a good plugin][] on Medium.
{{site.alert.end}}

### Package types {#types}

Packages can contain several kinds of content:

* *Dart packages*: General packages written in Dart, for example the
[`path`]({{site.pub}}/packages/path) package. Some of these might
* *Dart packages*: General packages written in Dart,
for example the [`path`][] package. Some of these might
contain Flutter specific functionality and thus have a dependency on the
Flutter framework, restricting their use to Flutter only, for example the
[`fluro`]({{site.pub}}/packages/fluro) package.
Flutter framework, restricting their use to Flutter only,
for example the [`fluro`][] package.

* *Plugin packages*: A specialized Dart package which contain an API written in
Dart code combined with a platform-specific implementation for Android (using
Java or Kotlin), and/or for iOS (using ObjC or Swift). A concrete example is
the [`battery`]({{site.pub}}/packages/battery) plugin package.
* *Plugin packages*: A specialized Dart package that contains
an API written in Dart code combined with a platform-specific
implementation for Android (using Java or Kotlin),
and/or for iOS (using ObjC or Swift).
A concrete example is the [`battery`][] plugin package.

## Developing Dart packages {#dart}

Expand All @@ -50,33 +49,31 @@ $ flutter create --template=package hello
This creates a package project in the `hello/` folder with the following
specialized content:

* `lib/hello.dart`:
- The Dart code for the package.
* `test/hello_test.dart`:
- The [unit tests](/docs/testing#unit-tests) for the package.
**`lib/hello.dart`**
: The Dart code for the package.
**`test/hello_test.dart`**
: The [unit tests][] for the package.

### Step 2: Implement the package

For pure Dart packages, simply add the functionality inside the main
`lib/<package name>.dart` file, or in several files in the `lib` directory.

To test the package, add [unit tests](/docs/testing#unit-tests)
To test the package, add [unit tests][]
in a `test` directory.

For additional details on how to organize the package contents, see the
[Dart library
package]({{site.dart-site}}/guides/libraries/create-library-packages)
documentation.
For additional details on how to organize the package contents,
see the [Dart library package][] documentation.

## Developing plugin packages {#plugin}

If you want to develop a package that calls into platform-specific APIs, you
need to develop a plugin package. A plugin package is a specialized version of a
Dart package, that in addition to the content described above also contains
platform-specific implementations written for Android (Java or Kotlin code), for
iOS (Objective-C or Swift code), or for both. The API is connected to the
platform-specific implementation(s) using [platform
channels](/docs/development/platform-integration/platform-channels).
If you want to develop a package that calls into platform-specific APIs,
you need to develop a plugin package. A plugin package is a specialized
version of a Dart package, that in addition to the content described
above also contains platform-specific implementations written for
Android (Java or Kotlin code), for iOS (Objective-C or Swift code),
or for both. The API is connected to the
platform-specific implementation(s) using [platform channels][].

### Step 1: Create the package

Expand Down Expand Up @@ -118,9 +115,9 @@ experience.

#### Step 2a: Define the package API (.dart)

The API of the plugin package is defined in Dart code. Open the main `hello/`
folder in your favorite [Flutter editor](/docs/get-started/editor). Locate the file
`lib/hello.dart`.
The API of the plugin package is defined in Dart code.
Open the main `hello/` folder in your favorite [Flutter editor][].
Locate the file `lib/hello.dart`.

#### Step 2b: Add Android platform code (.java/.kt)

Expand Down Expand Up @@ -165,24 +162,24 @@ You can run the example app by pressing the &#9654; button.

#### Step 2d: Connect the API and the platform code

Finally, you need to connect the API written in Dart code with the platform-specific
implementations. This is done using [platform
channels](/docs/development/platform-integration/platform-channels).
Finally, you need to connect the API written in Dart code
with the platform-specific implementations.
This is done using [platform channels][].

## Adding documentation

It is recommended practice to add the following documentation to all packages:

1. A `README.md` file that introduces the package
1. A `CHANGELOG.md` file that documents changes in each version
1. A [`LICENSE`](#adding-licenses-to-the-license-file) file containing the terms under which the package is licensed
1. A [`LICENSE`][] file containing the terms under which the
package is licensed
1. API documentation for all public APIs (see below for details)

### API documentation

When you publish a package, API documentation is automatically generated and
published to dartdocs.org, see for example the [device_info
docs]({{site.pub-api}}/device_info/latest)
published to pub.dev, see for example the [device_info docs][].

If you wish to generate API documentation locally on your developement machine, use the following commands:

Expand All @@ -202,8 +199,8 @@ If you wish to generate API documentation locally on your developement machine,

`%FLUTTER_ROOT%\bin\cache\dart-sdk\bin\dartdoc` (on Windows)

For tips on how to write API documentation, see [Effective Dart:
Documentation]({{site.dart-site}}/guides/language/effective-dart/documentation).
For tips on how to write API documentation,
see [Effective Dart: Documentation][].

### Adding licenses to the LICENSE file

Expand Down Expand Up @@ -263,32 +260,31 @@ package_1
## Publishing packages {#publish}

Once you have implemented a package, you can publish it on the
[Pub site]({{site.pub}}), so that other developers can
easily use it.
[pub.dev][], so that other developers can easily use it.

Prior to publishing, make sure to review the `pubspec.yaml`,
`README.md`, and `CHANGELOG.md` files to make sure their content
is complete and correct. Also, to improve the quality and
usability of your package, consider including the items below.

Prior to publishing, make sure to review the `pubspec.yaml`, `README.md`, and
`CHANGELOG.md` files to make sure their content is complete and correct. Also, to improve the quality and usability of your package, consider including the items below.
* Diverse code usage examples
* Screenshots, animated gifs, or videos
* A link to the corresponding code repository

Next, run the dry-run command to see if everything passes analysis:

```terminal
$ flutter pub pub publish --dry-run
$ flutter pub publish --dry-run
```

(Note the redundant `pub pub`, which is needed until [issue #33302](https://github.com/flutter/flutter/issues/33302) is resolved).

Finally, run the actual publish command:

```terminal
$ flutter pub pub publish
```

For details on publishing, see the
[publishing docs]({{site.dart-site}}/tools/pub/publishing)
for the Pub site.
[publishing docs][] for the pub.dev.

## Handling package interdependencies {#dependencies}

Expand Down Expand Up @@ -336,3 +332,18 @@ Pod::Spec.new do |s|
```
You can now `#import "UrlLauncherPlugin.h"` and access the `UrlLauncherPlugin` class in the source code
at `hello/ios/Classes`.


[`battery`]: {{site.pub}}/packages/battery
[Dart library package]: {{site.dart-site}}/guides/libraries/create-library-packages
[device_info docs]: {{site.pub-api}}/packages/device_info
[Effective Dart: Documentation]: {{site.dart-site}}/guides/language/effective-dart/documentation
[`fluro`]: {{site.pub}}/packages/fluro
[Flutter editor]: /docs/get-started/editor
[`LICENSE`]: #adding-licenses-to-the-license-file
[`path`]: {{site.pub}}/packages/path
[platform channels]: /docs/development/platform-integration/platform-channels
[pub.dev]: {{site.pub}}
[publishing docs]: {{site.dart-site}}/tools/pub/publishing
[unit tests]: /docs/testing#unit-tests
[Writing a good plugin]: {{site.flutter-medium}}/writing-a-good-flutter-plugin-1a561b986c9c
Loading