संक्षिप्त उत्तर: नहीं, यह संभव नहीं है, हालांकि मैंने सोने के प्रदर्शन के लिए एक अलग व्यवहार देखा है। निम्नलिखित कोड आप Android पर एक स्पंदन अनुप्रयोग, इन स्पंदन और स्पंदन इंजन संस्करणों के साथ परीक्षण किया गया के विभिन्न राज्यों को समझने में मदद मिलेगी:
- फ्रेमवर्क संशोधन b339c71523 (6 घंटे पहले), 2017/02/04 00:51 : 32
- इंजन संशोधन cd34b0ef39
एक नया स्पंदन एप्लिकेशन बनाएँ, और इस कोड के साथ lib/main.dart
की सामग्री को बदल दें:
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(),
],
),
);
}
}
ऐप लॉन्च करते समय, _timerCounter का मान हर 3 एस में बढ़ता है।
[[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
ऊपर लॉग आउटपुट के लिए, यहां दिए गए चरणों मैंने किया हैं: काउंटर नीचे एक टेक्स्ट फ़ील्ड स्पंदन अनुप्रयोग के लिए किसी भी AppLifecycleState परिवर्तन भी दिखाई देंगे, आप स्पंदन डीबग लॉग में इसी उत्पादन, जैसे देखेंगे :
- ऐप्लिकेशन लॉन्च के साथ
flutter run
- अन्य अनुप्रयोग पर स्विच करें (_timerCounter मूल्य 1)
- स्पंदन एप्लिकेशन पर लौटें (_timerCounter मूल्य 3)
- दबाया पावर बटन, प्रदर्शन फोन पर बंद कर दिया (_timerCounter मूल्य 4)
- खुला फोन, स्पंदन एप्लिकेशन फिर से शुरू (_timerCounter मूल्य 7)
- वापस दबाया बटन (_timerCounter मूल्य बदल नहीं)। यही वह क्षण है जहां FlutterActivity नष्ट हो जाता है और डार्ट वीएम भी अलग हो जाता है।
- स्पंदन एप्लिकेशन फिर से शुरू (_timerCounter मान 0 फिर से है)
क्षुधा के बीच स्विच, बिजली या वापस बटन दबाने
दूसरे ऐप्स पर स्विच, या जब स्क्रीन के चालू करने के लिए पावर बटन दबाकर जब टाइमर चलना जारी है। लेकिन जब फ्टरर ऐप पर फोकस होता है तो बैक बटन दबाते समय, गतिविधि नष्ट हो जाती है, और इसके साथ डार्ट अलग हो जाता है। ऐप्स के बीच स्विच करते समय, या स्क्रीन को चालू करते समय आप Dart Observatory से कनेक्ट करके परीक्षण कर सकते हैं। वेधशाला एक सक्रिय Flutter ऐप अलग चलाना दिखाएगा। लेकिन बैक बटन दबाते समय, वेधशाला कोई रनिंग पृथक नहीं दिखाती है। एंड्रॉइड 6.x चलाने वाले गैलेक्सी नोट 5 पर और एंड्रॉइड 4.4.x चलाने वाला नेक्सस 4 पर व्यवहार की पुष्टि हुई।
स्पंदन एप्लिकेशन जीवन चक्र और Android जीवन चक्र स्पंदन विजेट परत के लिए, केवल रुका हुआ है और फिर से शुरू राज्यों संपर्क में हैं। नष्ट एक Android स्पंदन अनुप्रयोग के लिए Android Activity द्वारा नियंत्रित किया जाता: डार्ट वी एम के बाद से
/**
* @see android.app.Activity#onDestroy()
*/
@Override
protected void onDestroy() {
if (flutterView != null) {
flutterView.destroy();
}
super.onDestroy();
}
के लिए एक स्पंदन एप्लिकेशन गतिविधि के अंदर चल रहा है, वीएम हर बार गतिविधि को नष्ट कर दिया जाता है रोक दिया जाएगा।
स्पंदन इंजन कोड तर्क
यह सीधे आपके प्रश्न का उत्तर नहीं है, लेकिन आपको इस बारे में स्पंदन इंजन Android के लिए राज्य में परिवर्तन संभालती है कुछ और अधिक विस्तृत पृष्ठभूमि जानकारी दे देंगे।
स्पंदन इंजन कोड के माध्यम से देख रहे हैं यह स्पष्ट हो जाता है कि एनीमेशन पाश रुका हुआ है जब FlutterActivity एंड्रॉयड Activity#onPause घटना प्राप्त करता है। जब आवेदन में चला जाता है रुका हुआ राज्य, source comment here निम्न होता है के अनुसार:।
"एप्लिकेशन को वर्तमान में उपयोगकर्ता को दिखाई नहीं देता जब अनुप्रयोग इस स्थिति में है, इंजन [onBeginFrame फोन नहीं होगा ] वापस कॉल करें।"
मेरी घड़ी परीक्षण के आधार पर यूआई प्रतिपादन रुक, जो समझ में आता है के साथ भी काम करने के लिए जारी है। यह WidgetsBindingObserver जब गतिविधि को नष्ट कर दिया जाता है का उपयोग कर विजेट परत में एक घटना भेजने के लिए अच्छा होगा, इसलिए डेवलपर्स जब तक गतिविधि फिर से शुरू है स्पंदन एप्लिकेशन के राज्य स्टोर करने के लिए सुनिश्चित करें।
शायद वास्तविक सवाल यह है: क्या गतिविधि को नष्ट करने के साथ एक फ्लटर ऐप के लिए पृष्ठभूमि (जैसे टाइमर) में कोड चलाने के लिए संभव है? मेरे मामले में टाइमर चलाना जारी रखेगा भले ही मैं डिस्प्ले बंद कर दूं (नीचे जवाब देखें)। –