Câu trả lời ngắn gọn: không, không thể, mặc dù tôi đã quan sát thấy một hành vi khác nhau cho màn hình sẽ chuyển sang chế độ ngủ. Mã sau đây sẽ giúp bạn hiểu các trạng thái khác nhau của ứng dụng Rung trên Android, được thử nghiệm với các phiên bản Flutter và Flutter Engine này:
- Sửa đổi khung b339c71523 (6 giờ trước), 2017-02-04 00:51 : 32
- phiên bản động cơ cd34b0ef39
Tạo một ứng dụng Flutter mới, và thay thế nội dung của lib/main.dart
với mã này:
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(new MyApp());
}
class LifecycleWatcher extends StatefulWidget {
@override
_LifecycleWatcherState createState() => new _LifecycleWatcherState();
}
class _LifecycleWatcherState extends State<LifecycleWatcher>
with WidgetsBindingObserver {
AppLifecycleState _lastLifecyleState;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void onDeactivate() {
super.deactivate();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
print("LifecycleWatcherState#didChangeAppLifecycleState state=${state.toString()}");
setState(() {
_lastLifecyleState = state;
});
}
@override
Widget build(BuildContext context) {
if (_lastLifecyleState == null)
return new Text('This widget has not observed any lifecycle changes.');
return new Text(
'The most recent lifecycle state this widget observed was: $_lastLifecyleState.');
}
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter App Lifecycle'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _timerCounter = 0;
// ignore: unused_field only created once
Timer _timer;
_MyHomePageState() {
print("_MyHomePageState#constructor, creating new Timer.periodic");
_timer = new Timer.periodic(
new Duration(milliseconds: 3000), _incrementTimerCounter);
}
void _incrementTimerCounter(Timer t) {
print("_timerCounter is $_timerCounter");
setState(() {
_timerCounter++;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(config.title),
),
body: new Block(
children: [
new Text(
'Timer called $_timerCounter time${ _timerCounter == 1 ? '' : 's' }.',
),
new LifecycleWatcher(),
],
),
);
}
}
Khi khởi chạy ứng dụng, giá trị của _timerCounter được tăng lên mỗi 3 giây. Một trường text bên dưới quầy sẽ hiển thị bất kỳ AppLifecycleState thay đổi cho các ứng dụng Flutter, bạn sẽ thấy đầu ra tương ứng trong Flutter debug log, ví dụ:
[[email protected]:~/flutter/helloworld]$ flutter run
Launching lib/main.dart on SM N920S in debug mode...
Building APK in debug mode (android-arm)... 6440ms
Installing build/app.apk... 6496ms
I/flutter (28196): _MyHomePageState#constructor, creating new Timer.periodic
Syncing files to device...
I/flutter (28196): _timerCounter is 0
To hot reload your app on the fly, press "r" or F5. To restart the app entirely, press "R".
The Observatory debugger and profiler is available at: http://127.0.0.1:8108/
For a more detailed help message, press "h" or F1. To quit, press "q", F10, or Ctrl-C.
I/flutter (28196): _timerCounter is 1
I/flutter (28196): LifecycleWatcherState#didChangeAppLifecycleState state=AppLifecycleState.paused
I/flutter (28196): _timerCounter is 2
I/flutter (28196): _timerCounter is 3
I/flutter (28196): LifecycleWatcherState#didChangeAppLifecycleState state=AppLifecycleState.resumed
I/flutter (28196): _timerCounter is 4
I/flutter (28196): LifecycleWatcherState#didChangeAppLifecycleState state=AppLifecycleState.paused
I/flutter (28196): _timerCounter is 5
I/flutter (28196): _timerCounter is 6
I/flutter (28196): _timerCounter is 7
I/flutter (28196): LifecycleWatcherState#didChangeAppLifecycleState state=AppLifecycleState.resumed
I/flutter (28196): LifecycleWatcherState#didChangeAppLifecycleState state=AppLifecycleState.paused
I/flutter (28196): _timerCounter is 8
I/flutter (28196): _MyHomePageState#constructor, creating new Timer.periodic
I/flutter (28196): _timerCounter is 0
I/flutter (28196): _timerCounter is 1
Đối với các dữ liệu ghi nhận ở trên, sau đây là các bước tôi đã làm :
- Khởi chạy ứng dụng với
flutter run
- Chuyển sang ứng dụng khác (_timerCounter giá trị 1)
- Return to ứng dụng Flutter (_timerCounter giá trị 3)
- nút nguồn Pressed, màn hình tắt (giá trị _timerCounter 4)
- điện thoại Unlocked, Flutter ứng dụng trở lại (giá trị _timerCounter 7)
- Pressed lại nút trên điện thoại (giá trị _timerCounter không thay đổi). Đây là thời điểm mà FlutterActivity bị phá hủy và Dart VM Isolate là tốt.
- ứng dụng Flutter nối lại (giá trị _timerCounter là 0 nữa)
Chuyển đổi giữa các ứng dụng, nhấn điện hoặc nút quay lại
Khi chuyển sang ứng dụng khác, hoặc khi nhấn nút nguồn để bật của màn hình hẹn giờ tiếp tục chạy. Nhưng khi nhấn nút quay lại trong khi ứng dụng Rung có tiêu điểm, Hoạt động sẽ bị hủy và với Dart cô lập. Bạn có thể kiểm tra điều đó bằng cách kết nối với Dart Observatory khi chuyển đổi giữa các ứng dụng hoặc xoay màn hình. Đài quan sát sẽ hiển thị một ứng dụng Flutter hoạt động Cô lập chạy. Nhưng khi nhấn nút quay lại, Đài quan sát sẽ không hiển thị Isolate đang chạy. Hành vi này đã được xác nhận trên Galaxy Note 5 chạy Android 6.x và Nexus 4 chạy Android 4.4.x.
vòng đời ứng dụng Flutter và vòng đời Android Đối với các lớp phụ tùng Flutter, chỉ có dừng và tiếp tục bang được tiếp xúc. Phá hủy được xử lý bởi Android Activity cho một ứng dụng Android Flutter:
/**
* @see android.app.Activity#onDestroy()
*/
@Override
protected void onDestroy() {
if (flutterView != null) {
flutterView.destroy();
}
super.onDestroy();
}
Kể từ khi Dart VM cho một ứng dụng Flutter đang chạy bên trong Hoạt động, VM sẽ được dừng lại mỗi khi Hoạt động bị tiêu diệt.
Flutter Động cơ mã logic
này không trực tiếp trả lời câu hỏi của bạn, nhưng sẽ cung cấp cho bạn một số thông tin nền chi tiết về cách động cơ Flutter xử lý thay đổi trạng thái cho Android.
Tìm kiếm thông qua mã công cụ Rung động trở nên rõ ràng rằng vòng lặp hoạt ảnh bị tạm dừng khi số FlutterActivity nhận được sự kiện Android Activity#onPause. Khi ứng dụng đi vào dừng nhà nước, theo source comment here sau xảy ra:
"Ứng dụng này hiện chưa rõ ràng cho người dùng khi ứng dụng ở trạng thái này, động cơ sẽ không gọi [onBeginFrame. ] gọi lại."
Dựa trên thử nghiệm của tôi, bộ hẹn giờ tiếp tục hoạt động ngay cả khi hiển thị giao diện người dùng bị tạm dừng, điều này có ý nghĩa. Sẽ rất tốt khi gửi sự kiện vào lớp tiện ích bằng cách sử dụng WidgetsBindingObserver khi Hoạt động bị hủy, vì vậy nhà phát triển có thể đảm bảo lưu trữ trạng thái của ứng dụng Rung cho đến khi Hoạt động được tiếp tục.
Có thể câu hỏi thực sự là: Có thể chạy mã trong nền (ví dụ: hẹn giờ) cho ứng dụng Rung với Hoạt động bị hủy không? Trong trường hợp của tôi, bộ hẹn giờ sẽ tiếp tục chạy ngay cả khi tôi tắt màn hình (xem câu trả lời bên dưới). –