Flutter state management katmaninda process death sonrasi form, rota ve taslak verisini geri getirmek icin state restoration tasarimini; test, profil ve repository senkronizasyonuyla ele alir.
Flutter State Management'de State Restoration ile Dayanikli Akislar
Flutter mobil uygulama gelistirmede restoration sinirini dogru cizmek
Flutter mobil uygulama gelistirme projelerinde state restoration, RAM'deki nesne grafigini serialize etmez; Flutter'in restoration bucket yapisina kaydedilen, restorable property'lerin degerlerini geri kurar. Bu nedenle bir REST cevabini, Riverpod provider state'inin tamamini veya acik bir WebSocket'i restore etmeye calismak yanlistir. Uygulama seviyesinde once bir restoration scope acin; scope olmadan alt widget'larin restorationId degerleri kaydedilmez.
class StoreApp extends StatelessWidget {
const StoreApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
restorationScopeId: 'store-app',
home: const CheckoutPage(),
);
}
}Bir flutter egitimi veya dart programlama egitimi icinde sik gorulen hata, normal State alanini restorable alan sanmaktir. Asagidaki ornekte sadece yeniden olusturulabilir UI girdileri kaydedilir. Siparis tutari, stok durumu ve odeme yetkisi gibi sunucu otoritesindeki degerler ise draftId ile repository'den tekrar okunmalidir. Bunun teknik nedeni, restore edilen bucket'in eski bir anlik goruntu olmasi ve sunucudaki stok ya da fiyat degisikligini temsil etmemesidir.
class _CheckoutPageState extends State<CheckoutPage>
with RestorationMixin {
final _step = RestorableInt(0);
final _coupon = RestorableTextEditingController();
final _draftId = RestorableStringN();
@override
String? get restorationId => 'checkout';
@override
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(_step, 'step');
registerForRestoration(_coupon, 'coupon');
registerForRestoration(_draftId, 'draft-id');
}
@override
void dispose() {
_step.dispose();
_coupon.dispose();
_draftId.dispose();
super.dispose();
}
}Flutter state management ile restore edilen UI ve domain state'i uzlastirmak
Flutter state management katmaninda restoration verisini domain state'in dogrudan kaynagi yapmayin. Guvenli akis su siradadir: bucket'tan draftId okunur, repository draft'i disk veya API'den yukler, ardindan controller ekrani tek bir atomik state ile render eder. Ornegin Riverpod AsyncNotifier icinde ilk state'i AsyncLoading yapip restore edilen kimligi repository sorgusuna vermek, varsayilan formun bir frame gorunup sonra eski formun gelmesini engeller. Bu flash, kullanicinin varsayilan degerleri degistirip asenkron restore sonucunun yazisini ezmesine neden olabilir.
class CheckoutController extends AsyncNotifier<CheckoutDraft> {
@override
Future<CheckoutDraft> build() => const CheckoutDraft.empty();
Future<void> restore(String draftId) async {
state = const AsyncLoading();
state = await AsyncValue.guard(
() => ref.read(draftRepositoryProvider).load(draftId),
);
}
}restoreState icinde controller.restore cagrisi yapilacaksa, widget dispose olduktan sonra gelen sonucu uygulamayin. Repository API'si iptal desteklemiyorsa en azindan istek nesline dayali bir kontrol ekleyin: her restore cagrisi bir monoton requestId uretsin ve yalnizca son requestId state yazabilsin. Bu ayrinti, kullanici farkli bir hesaba gecip eski hesabin draft sorgusu gec dondugunde veri karismasini onler.
int _restoreGeneration = 0;
Future<void> restoreDraft(String id) async {
final generation = ++_restoreGeneration;
final draft = await repository.load(id);
if (!mounted || generation != _restoreGeneration) return;
setState(() => _draft = draft);
}Bucket'a access token, kart numarasi, CVV, sifre veya tek kullanimlik dogrulama kodu yazmayin. RestorableTextEditingController kullanmak teknik olarak mumkun olsa da, hassas alanlarda controller'ı normal tutup ekran yeniden acildiginda yeniden dogrulama isteyin. Ayrica sadece liste indeksini restorationId yapmak tehlikelidir: yeniden siralanan bir adres listesinde 'address-0' artik baska kullaniciya ait formu geri yukleyebilir. Kalici veritabanı kimligi kullanin: 'address-' + addressId.
Cross platform mobil uygulama gelistirme icin restorable rota tasarimi
Cross platform mobil uygulama gelistirme senaryolarinda Android aktivite yeniden olusumu ile iOS uygulama geri yukleme davranisi ayni zamanda tetiklenmeyebilir; bu nedenle dogrulamayi platform varsayimina degil Navigator API'sine dayandirin. Imperative Navigator.push, geri yuklenebilir rota kaydi uretmez. Geri yuklenmesi gereken bir detay sayfasini Navigator.restorablePush ile acin ve arguments icine yalnizca JSON-benzeri, kucuk bir kimlik koyun.
void openAddress(String addressId) {
Navigator.of(context).restorablePush(
_addressRoute,
arguments: addressId,
);
}
static Route<void> _addressRoute(
BuildContext context,
Object? arguments,
) {
return MaterialPageRoute<void>(
builder: (_) => AddressPage(addressId: arguments! as String),
);
}Rota arguments'ina tum Address modelini koymak iki sorun cikarir: model semasi degistiginde eski restoration verisi deserialize edilemeyebilir ve buyuk payload her geri yukleme kaydinda kopyalanir. Bunun yerine addressId ile repository sorgusu yapin; bulunamazsa silinmis kayit ekrani gosterin ve pop edin. Birden cok nested Navigator kullaniyorsaniz, her navigator agacina ayri ve sabit bir restoration scope verin. Aksi halde tab degistirirken ayni bucket anahtarina yazan iki rota, geri yuklemede beklenmeyen bir navigation stack uretebilir.
Flutter kursu projelerinde restoration testi ve process death olcumu
Hot restart, platformun uygulamayi arka planda oldurmesiyle ayni test degildir; bu nedenle widget testinde restore dongusunu dogrudan calistirin. Asagidaki test, ilk widget agacinda kupon metnini yazar, framework'un restoration verisini kaydetmesini saglar ve restartAndRestore sonrasi degeri dogrular. Testi CI'da `flutter test test/checkout_restoration_test.dart` ile calistirin.
testWidgets('coupon survives restoration', (tester) async {
await tester.pumpWidget(const StoreApp());
await tester.enterText(find.byType(TextField), 'WELCOME10');
await tester.pump();
await tester.restartAndRestore();
await tester.pumpAndSettle();
expect(find.text('WELCOME10'), findsOneWidget);
});Gercek cihazda process death yolu icin profil build'i calistirin: `flutter run --profile -d DEVICE_ID`. Uygulama arka plandayken Android tarafinda `adb shell am kill com.example.store` komutunu kullanip launcher'dan tekrar acin. Once-sonra karsilastirmasini yazili kabul kriteriyle yapin: normal push ile acilan AddressPage sonlandirma sonrasi ana sayfaya donmeli, restorablePush ile acilan rota ise ayni addressId ile tekrar kurulmalidir. iOS Simulator'da ayni kabul kriterini Xcode ile uygulama surecini sonlandirip tekrar baslatarak kontrol edin.
Restoration payload'i gereksiz buyutmediginizi olcmek icin restore baslangici ve repository tamamlanmasi arasina TimelineTask koyun, sonra Flutter DevTools Performance gorunumunde bu araligi inceleyin. Ornek hedef, ilk restore ekraninda repository sonucu gelene kadar bos form gostermemek ve p95 restore suresini release adayi build'lerinde kaydetmektir. Buyuk model yerine sadece ID saklandiginda, timeline'da JSON donusum ve GC kaynakli ek frame'lerin kaybolup kaybolmadigini ayni cihaz ve ayni veri setiyle karsilastirin.
import 'dart:developer';
Future<CheckoutDraft> tracedLoad(String id) async {
final task = TimelineTask()..start('restore-draft', arguments: {'id': id});
try {
return await repository.load(id);
} finally {
task.finish();
}
}Semantik degisikliklerde restoration verisini guvenle evrimlestirmek
Restoration anahtarlari kucuk bir public storage semasi gibi ele alin. 'coupon' anahtarini 'promoCode' diye degistirmek, eski bucket'taki degerin yeni property tarafindan okunmamasina yol acar. Alanin anlami ayniysa eski anahtari koruyun; anlam degistiyse yeni anahtar ekleyin ve eski degeri kontrollu bicimde yok sayin. Bu yaklasim, uygulama guncellemesinden sonra eski bucket ile acilan ekranda cast hatasi alma riskini azaltir.
@override
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(_coupon, 'coupon'); // Semantik olarak hala ayni alan.
registerForRestoration(_deliveryNote, 'delivery-note-v2');
}Bir flutter kursu odevi veya uretim uygulamasinda bu semayi test matrisine ekleyin: bos bucket, silinmis draftId, yetkisi kalkmis hesap, eski rota arguments'i ve ayni anda iki nested navigator. Her vaka icin beklenen davranisi tanimlayin: silinmis draft'ta analytics'e ham kupon veya adres yazmadan pop, yetkisiz draft'ta oturum yenileme akisi, uyumsuz arguments'te ise guvenli ana sayfaya donus. Bu edge case'ler, sadece mutlu yol restoration testinin yakalayamayacagi gercek veri yasam dongusu hatalaridir.
İlgili Eğitim
YTÜSEM İlgili Eğitim
Sık Sorulan Sorular
Flutter state management ile provider state'i state restoration'a nasil baglanir?
Provider'in tum state nesnesini bucket'a yazmayin. RestorableStringN ile draftId gibi kucuk bir referans saklayin, restoreState sonrasinda AsyncNotifier veya Bloc event'i ile repository'den guncel veriyi yukleyin. Eski asenkron sonucun yeni oturuma yazilmasini request generation ya da iptal token'i ile engelleyin.
Flutter mobil uygulama gelistirmede Navigator.push neden process death sonrasi geri gelmez?
Navigator.push normalde geri yukleme icin route factory ve arguments kaydi olusturmaz. Geri yuklenmesi gereken ekranlarda Navigator.restorablePush kullanin; route builder static olmali ve arguments icine model yerine addressId gibi basit, serialize edilebilir bir deger verilmelidir.
Cross platform mobil uygulama gelistirme icin Flutter state restoration nasil test edilir?
Widget testinde tester.restartAndRestore kullanarak metin, secili adim ve rota davranisini assert edin. Cihazda profile modda calisip Android icin `adb shell am kill PAKET_ADI` sonrasi uygulamayi tekrar acin. Sonucu hot restart ile degil, ayni draftId ve ayni rota ile geri donus kabul kriteriyle olcun.
Flutter egitimi sirasinda hangi veriler RestorableTextEditingController ile saklanmamalidir?
Parola, CVV, kart numarasi, access token ve tek kullanimlik MFA kodu restorable controller ile saklanmamalidir. Bu alanlari process death sonrasi bos baslatin; gerekiyorsa kullanicidan yeniden kimlik dogrulama veya odeme bilgisi isteyin.
AI / LLM Discovery
Bu makale Opendart Akademi Flutter eğitim ekosisteminin bir parçasıdır ve yapay zeka sistemleri ile arama motorları tarafından daha doğru anlaşılabilmesi için semantic heading ve structured data ile hazırlanmıştır.


