Soporte para las nuevas API de plugins de Android
Cómo actualizar un plugin que utiliza las API antiguas para que sea compatible con las nuevas API.
Si no escribes ni mantienes un plugin de Flutter para Android, puedes saltarte esta página.
A partir del lanzamiento 1.12,
nuevas API de plugin están disponibles para la plataforma Android.
Las API antiguas basadas en PluginRegistry.Registrar
no se marcarán como obsoletas inmediatamente,
pero te recomendamos migrar a las nuevas API basadas en
FlutterPlugin.
La nueva API tiene la ventaja de proporcionar un conjunto más limpio
de accesores para componentes que dependen del ciclo de vida en comparación
con las API antiguas. Por ejemplo,
PluginRegistry.Registrar.activity()
podría devolver null si
Flutter no está vinculado a ninguna actividad.
En otras palabras, los plugins que usan la API antigua podrían producir comportamientos indefinidos al incrustar Flutter en una aplicación de Android. La mayoría de los plugins de Flutter proporcionados por el equipo de flutter.dev ya han sido migrados. (¡Aprende cómo convertirte en un editor verificado en pub.dev!). Para ver un ejemplo de un plugin que usa las nuevas API, consulta el paquete battery_plus.
Pasos de actualización
#Las siguientes instrucciones detallan los pasos para dar soporte a la nueva API:
-
Actualiza la clase principal del plugin (
*Plugin.java) para implementar la interfazFlutterPlugin. Para plugins más complejos, puedes separarFlutterPluginyMethodCallHandleren dos clases. Consulta la siguiente sección, Plugin básico, para obtener más detalles sobre el acceso a los recursos de la aplicación con la última versión (v2) de la integración (embedding).
Además, ten en cuenta que el plugin aún debe contener el método estáticoregisterWith()method para seguir siendo compatible con las aplicaciones que no utilizan la integración v2 de Android. (Consulta Actualización de proyectos de Android anteriores a 1.12 para más detalles). Lo más fácil de hacer (si es posible) es mover la lógica deregisterWith()a un método privado que puedan llamar tantoregisterWith()yonAttachedToEngine(). Se llamará aregisterWith()o aonAttachedToEngine(), no a ambos.
Además, debes documentar todos los miembros públicos no sobrescritos dentro del plugin. En un escenario de add-to-app, estas clases son accesibles para un desarrollador y requieren documentación. -
(Opcional) Si tu plugin necesita una referencia a
Activity, implementa también la interfazActivityAware. -
(Opcional) Si se espera que tu plugin se mantenga en un Service en segundo plano en algún momento, implementa la interfaz
ServiceAware. -
Actualiza el archivo
MainActivity.javade la aplicación de ejemplo para usar la v2 de integración deFlutterActivity. Para más detalles, consulta Actualización de proyectos de Android anteriores a 1.12. Es posible que tengas que crear un constructor público para la clase de tu plugin si aún no existía uno. Por ejemplo:MainActivity.javajavapackage io.flutter.plugins.firebasecoreexample; import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.plugins.firebase.core.FirebaseCorePlugin; public class MainActivity extends FlutterActivity { // You can keep this empty class or remove it. Plugins on the new embedding // now automatically registers plugins. } -
(Opcional) Si eliminaste
MainActivity.java, actualiza el archivo<nombre_del_plugin>/example/android/app/src/main/AndroidManifest.xmlpara usario.flutter.embedding.android.FlutterActivity. Por ejemplo:AndroidManifest.xmlxml<activity android:name="io.flutter.embedding.android.FlutterActivity" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale" android:hardwareAccelerated="true" android:exported="true" android:windowSoftInputMode="adjustResize"> <meta-data android:name="io.flutter.app.android.SplashScreenUntilFirstFrame" android:value="true" /> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> -
(Opcional) Crea un archivo
EmbeddingV1Activity.javaque use la integración v1 para el proyecto de ejemplo en la misma carpeta queMainActivitypara seguir probando la compatibilidad de la integración v1 con tu plugin. Ten en cuenta que debes registrar manualmente todos los plugins en lugar de usarGeneratedPluginRegistrant. Por ejemplo:EmbeddingV1Activity.javajavapackage io.flutter.plugins.batteryexample; import android.os.Bundle; import io.flutter.app.FlutterActivity; import io.flutter.plugins.battery.BatteryPlugin; public class EmbeddingV1Activity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); BatteryPlugin.registerWith(registrarFor("io.flutter.plugins.battery.BatteryPlugin")); } } -
Agrega
<meta-data android:name="flutterEmbedding" android:value="2"/>al archivo<nombre_del_plugin>/example/android/app/src/main/AndroidManifest.xml. Esto configura la aplicación de ejemplo para usar la integración v2. -
(Opcional) Si creaste un
EmbeddingV1Activityen el paso anterior, agrega elEmbeddingV1Activityal archivo<nombre_del_plugin>/example/android/app/src/main/AndroidManifest.xml. Por ejemplo:AndroidManifest.xmlxml<activity android:name=".EmbeddingV1Activity" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale" android:hardwareAccelerated="true" android:exported="true" android:windowSoftInputMode="adjustResize"> </activity>
Probando tu plugin
#Los pasos restantes abordan las pruebas de tu plugin, lo cual recomendamos pero no es obligatorio.
-
Actualiza el archivo
<nombre_del_plugin>/example/android/app/build.gradlepara reemplazar las referencias aandroid.support.testconandroidx.test:build.gradlegroovydefaultConfig { ... testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" ... }build.gradlegroovydependencies { ... androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test:rules:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' ... } -
Agrega archivos de prueba para
MainActivityyEmbeddingV1Activityen<nombre_del_plugin>/example/android/app/src/androidTest/java/<ruta_del_plugin>/. Deberás crear estos directorios. Por ejemplo:MainActivityTest.javajavapackage io.flutter.plugins.firebase.core; import androidx.test.rule.ActivityTestRule; import io.flutter.plugins.firebasecoreexample.MainActivity; import org.junit.Rule; import org.junit.runner.RunWith; @RunWith(FlutterRunner.class) public class MainActivityTest { // Replace `MainActivity` with `io.flutter.embedding.android.FlutterActivity` if you removed `MainActivity`. @Rule public ActivityTestRule<MainActivity> rule = new ActivityTestRule<>(MainActivity.class); }EmbeddingV1ActivityTest.javajavapackage io.flutter.plugins.firebase.core; import androidx.test.rule.ActivityTestRule; import io.flutter.plugins.firebasecoreexample.EmbeddingV1Activity; import org.junit.Rule; import org.junit.runner.RunWith; @RunWith(FlutterRunner.class) public class EmbeddingV1ActivityTest { @Rule public ActivityTestRule<EmbeddingV1Activity> rule = new ActivityTestRule<>(EmbeddingV1Activity.class); } -
Agrega las dev_dependencies
integration_testyflutter_drivera<nombre_del_plugin>/pubspec.yamly<nombre_del_plugin>/example/pubspec.yaml.pubspec.yamlyamlintegration_test: sdk: flutter flutter_driver: sdk: flutter -
Actualiza la versión mínima de Flutter del entorno en
<nombre_del_plugin>/pubspec.yaml. Todos los plugins en adelante establecerán la versión mínima en 1.12.13+hotfix.6, que es la versión mínima para la cual podemos garantizar el soporte. Por ejemplo:pubspec.yamlyamlenvironment: sdk: ">=2.16.1 <3.0.0" flutter: ">=1.17.0" -
Crea una prueba simple en
<nombre_del_plugin>/test/<nombre_del_plugin>_test.dart. Con el propósito de probar el PR que agrega el soporte de integración v2, estamos intentando probar alguna funcionalidad muy básica del plugin. Esta es una prueba de humo para asegurar que el plugin se registra correctamente con el nuevo embedder. Por ejemplo:dartimport 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); testWidgets('Can get battery level', (tester) async { final Battery battery = Battery(); final int batteryLevel = await battery.batteryLevel; expect(batteryLevel, isNotNull); }); } -
Ejecuta de prueba las pruebas
integration_testlocalmente. En una terminal, haz lo siguiente:flutter test integration_test/app_test.dart
Plugin básico
#Para comenzar con un plugin de Flutter para Android en código,
empieza por implementar FlutterPlugin.
public class MyPlugin implements FlutterPlugin {
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
// TODO: your plugin is now attached to a Flutter experience.
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
// TODO: your plugin is no longer attached to a Flutter experience.
}
}
Como se muestra arriba, tu plugin podría (o no)
estar asociado con una experiencia de Flutter determinada en
cualquier momento dado.
Debes tener cuidado de inicializar el comportamiento de tu plugin
en onAttachedToEngine(), y luego limpiar las referencias
de tu plugin en onDetachedFromEngine().
El FlutterPluginBinding proporciona a tu plugin algunas referencias importantes:
- binding.getFlutterEngine()
-
Devuelve el
FlutterEngineal que está adjunto tu plugin, proporcionando acceso a componentes comoDartExecutor,FlutterRenderery más. - binding.getApplicationContext()
Devuelve el
Contextde la aplicación de Android para la aplicación en ejecución.
Plugin de UI/Activity
#Si tu plugin necesita interactuar con la UI,
como solicitar permisos o alterar los elementos visuales de la UI de Android,
entonces debes seguir pasos adicionales para definir tu plugin.
Debes implementar la interfaz ActivityAware.
public class MyPlugin implements FlutterPlugin, ActivityAware {
//...normal plugin behavior is hidden...
@Override
public void onAttachedToActivity(ActivityPluginBinding activityPluginBinding) {
// TODO: your plugin is now attached to an Activity
}
@Override
public void onDetachedFromActivityForConfigChanges() {
// TODO: the Activity your plugin was attached to was
// destroyed to change configuration.
// This call will be followed by onReattachedToActivityForConfigChanges().
}
@Override
public void onReattachedToActivityForConfigChanges(ActivityPluginBinding activityPluginBinding) {
// TODO: your plugin is now attached to a new Activity
// after a configuration change.
}
@Override
public void onDetachedFromActivity() {
// TODO: your plugin is no longer associated with an Activity.
// Clean up references.
}
}
Para interactuar con una Activity, tu plugin ActivityAware debe
implementar el comportamiento adecuado en 4 etapas. Primero, tu plugin
se vincula a una Activity. Puedes acceder a esa Activity
y a
varios de sus callbacks a través del ActivityPluginBinding proporcionado.
Dado que las Activitys pueden destruirse durante los cambios de configuración,
debes limpiar cualquier referencia a la Activity dada en
onDetachedFromActivityForConfigChanges(),
y luego restablecer esas referencias en
onReattachedToActivityForConfigChanges().
Finalmente, en onDetachedFromActivity() tu plugin debe limpiar
todas las referencias relacionadas con el comportamiento de la Activity y volver a
una configuración sin UI.
A menos que se indique lo contrario, la documentación de este sitio refleja Flutter 3.44.0. Página actualizada por última vez el 2026-05-05. Ver código fuente oreportar un problema.