I'm using get: ^3.12.1 and using bindings to inject my page controller and using onClose method to dispose a video_player controller but the onClose method is called twice when the page is destroyed.
Expected behavior
I think the onClose should only be called once.
Flutter Version:
1.20.4
Getx Version:
3.12.1
Describe on which device you found the bug:
Samsung s8+ / Huawei matepad pro / iPhone X with iOS 13
Here my GetPages
class AppPages {
static final List<GetPage> pages = [
GetPage(
name: AppRoutes.SPLASH,
page: () => SplashPage(),
binding: SplashBinding(),
),
GetPage(
name: AppRoutes.LOGIN,
page: () => LoginPage(),
binding: LoginBinding(),
),
GetPage(
name: AppRoutes.HOME,
page: () => HomePage(),
binding: HomeBinding(),
),
GetPage(
name: AppRoutes.COURSE_DETAIL,
page: () => CourseDetailPage(),
binding: CourseDetailBinding(),
),
GetPage(
name: AppRoutes.MY_COURSE,
page: () => MyCoursePage(),
binding: MyCourseBinding(),
),
];
}
GetMaterialApp
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'MEEDU.APP',
enableLog: true,
debugShowCheckedModeBanner: false,
home: SplashPage(),
initialBinding: SplashBinding(),
defaultTransition: Transition.rightToLeftWithFade,
getPages: AppPages.pages,
);
}
}
MyCourseBinding
import 'package:app/app/modules/my_course/my_course_controller.dart';
import 'package:get/instance_manager.dart';
import 'package:get/route_manager.dart';
class MyCourseBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut<MyCourseController>(
() => MyCourseController(),
);
}
}
MyCoursePage
import 'package:app/app/modules/my_course/my_course_controller.dart';
import 'package:app/app/modules/my_course/widgets/my_course_sections.dart';
import 'package:app/app/modules/my_course/widgets/my_course_video.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/state_manager.dart';
class MyCoursePage extends StatelessWidget {
const MyCoursePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return GetBuilder<MyCourseController>(
builder: (_) => Scaffold(
body: _.courseData == null
? Center(
child: CupertinoActivityIndicator(),
)
: Container(
child: Row(
children: [
Expanded(
flex: 3,
child: Container(
child: Column(
children: [
MyCourseVideo(),
],
),
),
),
Expanded(
flex: 2,
child: MyCourseSections(),
)
],
),
),
),
);
}
}
I'm navigating to MyCoursePage using
Get.toNamed(AppRoutes.MY_COURSE, arguments: course.id);
MyCourseController
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:meedu_player/meedu_player.dart';
import 'package:meta/meta.dart' show required;
class MyCourseController extends GetxController {
final _accountRepository = Get.find<AccountRepository>();
final _videoRepository = Get.find<VideoRepository>();
CourseData _courseData;
CourseData get courseData => _courseData;
int _lessonIndex = 0, _sectionIndex = 0;
int get lessonIndex => _lessonIndex;
int get sectionIndex => _sectionIndex;
MeeduPlayerController _meeduPlayerController;
MeeduPlayerController get meeduPlayerController => _meeduPlayerController;
@override
void onInit() {
List<DeviceOrientation> orientations = [
DeviceOrientation.portraitDown,
DeviceOrientation.portraitUp,
];
if (Get.context.isTablet) {
orientations.addAll([
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
}
_meeduPlayerController = MeeduPlayerController(
screenManager: ScreenManager(
forceLandScapeInFullscreen: true,
orientations: orientations,
),
pipEnabled: true,
showPipButton: true,
);
}
@override
void onReady() {
_load();
}
Future<void> _load() async {
final courseId = Get.arguments as String;
final result = await _accountRepository.getCourse(courseId);
if (result.error == null) {
_courseData = Extras.getCourseData(
result.data.course,
sectionsProgress: result.data.sections,
);
update();
}
}
@override
onClose() {
_dispose();
}
_dispose() async {
await _meeduPlayerController?.dispose();
_meeduPlayerController = null;
}
}
In my MyCourseController I have a video controller that is disposed in onClose method, when I close the page onClose method is called twice
[GETX] "MyCourseController" onClose() called
[GETX] "MyCourseController" deleted from memory
[GETX] "MyCourseController" onClose() called
[GETX] "MyCourseController" deleted from memory
GetBuilder tries to delete the controller, and at the same time the route is doing so.
Em had a Queue that prevented this, but I think it was removed during the split of the package.
I will fix it today.
Thanks. great job with getx. It is an amazing framework
Fix on git version, I will update do pub.dev.
Thanks for alert this.
Your GetX video series is amazing!
Hi. Thanks your the job to maintain this project. In my Project I've been updated to get: 3.12.2 to check if the onClose method is not called twice when I use bindings to inject my GetxController. In my controller I put a print to check if the onClose method is called twice
@override
void onClose() {
print("馃巸");
if (_meeduPlayerController != null) {
_meeduPlayerController.dispose();
_meeduPlayerController = null;
}
}
And in my console

Thank you for reporting this, I will correct and add a test for this to make sure it does not happen anymore.
Definitely fixed at 3.15.
Thanks for reporting this
Most helpful comment
GetBuilder tries to delete the controller, and at the same time the route is doing so.
Em had a Queue that prevented this, but I think it was removed during the split of the package.
I will fix it today.