Flutter Android WorkManager Kullanımı
Merhaba değerli okurlar, bu yazımda sizlere Flutter Android WorkManager Kullanımını anlatmaya çalışacağım.
Veri senkronizasyonu, periyodik bildirimler, arka planda dosya indirme/yükleme gibi görevler için arka plan görevlerinden(background tasks) yardım alırız.
Peki neden WorkManager kullanırız?
WorkManager, Google’ın Android’de arka plan görevleri için önerdiği modern ve akıllı bir kütüphanedir.
- Güvenilirlik: Belki de en önemli özelliği bu. WorkManager’a teslim ettiğiniz bir görev, uygulama yeniden başlatılsa, hatta telefon kapanıp açılsa bile (izinler dahilinde) eninde sonunda çalıştırılmak üzere sıraya alınır. İşin yarım kalma derdi olmaz.
- Pil ve Kaynak : WorkManager, görevin ne zaman çalışacağına akıllıca karar verir. Cihazın şarj durumu, ağ bağlantısı gibi koşulları göz önünde bulundurarak sistem kaynaklarını ve pili verimli kullanır.
- Modern: Eski yöntemlerin (AlarmManager, JobScheduler vb.) karmaşıklığını ortadan kaldıran, modern Android sürümleriyle uyumlu, resmi olarak tavsiye edilen çözümdür.
Yazımın hemen başlarında bahsettim ancak tekrar bahsetmekte fayda olabilir.
WorkManager ile Neler Yapılabilir?
- Veri Senkronizasyonu: Uygulama açıldığında kullanıcıyı bekletmemek için verileri periyodik olarak arka planda sunucuyla eşitleyebilirsiniz.
- Periyodik Bildirimler: “Bugün şu kadar adım attın!” gibi hatırlatma veya özet bildirimlerini belirli aralıklarla gönderebilirsiniz.
- Log Gönderimi: Uygulamada oluşan hataları veya önemli olayları, cihaz boştayken veya Wi-Fi’ye bağlıyken sunucuya yükleyebilirsiniz.
- Önbellek Temizliği: Belirli aralıklarla eski önbellek dosyalarını temizleyebilirsiniz.
- Veri Yedekleme: Kullanıcı verilerini düzenli olarak yedekleyebilirsiniz.
Bu bilgilerden sonra gelin birlikte kurulum ve kullanım detaylarına göz atalım;
WorkManager Kurulumu
Her zamanki gibi, ilk iş pubspec.yaml dosyamıza workmanager paketini eklemek:
dependencies:
flutter:
sdk: flutter
workmanager: ^0.5.1 # En güncel sürümü kontrol etmeyi unutmayın
Android Konfigürasyonları
WorkManager, Android’e özgü bir kütüphane olduğu için Android projemizde birkaç ayarlama yapmamız gerekiyor.
android/app/src/main/AndroidManifest.xml dosyasını açın ve şu satırları ekleyin:
<manifest xmlns:android=”http://schemas.android.com/apk/res/android"
package=”com.example.uygulamaniz”
xmlns:tools=”http://schemas.android.com/tools"><! — Cihaz açıldığında görevleri tetikleyebilmek için gerekli izin →
<uses-permission android:name=”android.permission.RECEIVE_BOOT_COMPLETED”/><application …>
<! — WorkManager’ın düzgün çalışması için gerekli tanımlama →
<provider
android:name=”androidx.startup.InitializationProvider”
android:authorities=”${applicationId}.workmanager-init”
android:exported=”false”
tools:node=”merge”>
<meta-data
android:name=”androidx.work.WorkManagerInitializer”
android:value=”androidx.work.impl.WorkManagerInitializer”
tools:node=”replace” />
</provider>
</application>
</manifest>
Not: tools:node=”replace” kısmını, projenizde başka başlatma sağlayıcıları varsa çakışmaları önlemek için ekleyebilirsiniz. Genellikle merge yeterlidir, ancak hata alırsanız replace deneyin.
MainActivity.kt (Kotlin) veya MainActivity.java (Java) Düzenlemesi:
Uygulamanızın ana aktivite dosyasını (android/app/src/main/kotlin/…/MainActivity.kt veya android/app/src/main/java/…/MainActivity.java) açıp, WorkManager’ı uygulama başlangıcında haberdar etmemiz gerekiyor.
Kotlin için (MainActivity.kt):
package com.example.uygulamaniz // Kendi paket adınızla değiştirin
import io.flutter.embedding.android.FlutterActivity
import androidx.work.WorkManager // Bu satırı ekleyin
import android.os.Bundle // Bu satırı ekleyin
class MainActivity: FlutterActivity() {
// WorkManager'ı başlatmak için bu bloğu ekleyebilirsiniz,
// ancak WorkManager artık genellikle otomatik başlatma (InitializationProvider)
// ile çalıştığı için bu adımı atlayabilirsiniz.
// Yine de emin olmak için veya eski sürümlerde eklemek gerekebilir.
// override fun onCreate(savedInstanceState: Bundle?) {
// super.onCreate(savedInstanceState)
// try {
// WorkManager.getInstance(applicationContext)
// } catch (e: Exception) {
// // Başlatma hatası olursa loglayabilirsiniz.
// }
// }
}
Güncel WorkManager sürümleri genellikle InitializationProvider sayesinde bu manuel onCreate başlatmasına ihtiyaç duymaz, ancak dokümantasyon veya karşılaştığınız bir sorun bunu gerektirirse ekleyebilirsiniz.
Flutter Tarafında Kullanımı
WorkManager’ı Başlatalım (main.dart):
Uygulamanızın giriş noktası olan main.dart dosyasında, runApp öncesinde WorkManager’ı başlatmalıyız:
import 'package:flutter/material.dart';
import 'package:workmanager/workmanager.dart';
// Arka plan görevlerini yönetecek fonksiyon (birazdan tanımlayacağız)
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) async {
print("Native called background task: $task"); // Hangi görevin çağrıldığını görmek için
// Burada hangi görev geldiyse ona göre işlem yapabilirsiniz
switch (task) {
case "basitArkaPlanGorevi":
print("Basit arka plan görevi çalışıyor...");
// Ağır bir işlem veya API çağrısı simülasyonu
await Future.delayed(Duration(seconds: 10));
print("Basit arka plan görevi bitti.");
break;
case Workmanager.iOSBackgroundTask:
// iOS için özel durumlar burada ele alınabilir (bu makalenin konusu değil)
print("iOS özel arka plan görevi.");
break;
}
// Görevin başarılı bittiğini sisteme bildirelim
return Future.value(true);
});
}
void main() async {
// Flutter'ın hazır olduğundan emin olalım
WidgetsFlutterBinding.ensureInitialized();
// WorkManager'ı başlatalım
await Workmanager().initialize(
callbackDispatcher, // Arka planda çalışacak fonksiyonumuz
isInDebugMode: true, // Geliştirme sırasında logları görmek için true yapın
);
runApp(MyApp());
}
// Geri kalan uygulama kodunuz...
class MyApp extends StatelessWidget { ... }
callbackDispatcher Fonksiyonu:
Dikkat ettiyseniz, Workmanager().initialize metoduna callbackDispatcher adında bir fonksiyon verdik. Bu fonksiyon, WorkManager bir görevi çalıştırmak istediğinde arka planda çağrılacak olan fonksiyondur.
Çok Önemli: callbackDispatcher fonksiyonu mutlaka dosyanın en üst seviyesinde (top-level) tanımlanmalı veya statik (static) bir metod olmalıdır. Çünkü bu fonksiyon, uygulamanızın ana arayüzü çalışmıyorken bile çağrılabilir olmalıdır.
Yukarıdaki main.dart örneğinde callbackDispatcher fonksiyonunun temel yapısını görebilirsiniz. executeTask içine yazdığınız kodlar, WorkManager görevi tetiklediğinde çalışır. task parametresi, hangi görevin tetiklendiğini belirtir.
Görevi Planlama Zamanı:
Artık bir görevi nasıl çalıştıracağımızı biliyoruz. Peki, görevi nasıl planlayacağız? Genellikle kullanıcının bir eylemiyle (örneğin bir butona basmasıyla) veya uygulamanın belirli bir mantığına göre görevleri kaydedersiniz.
// Bu fonksiyonu istediğiniz yerden çağırabilirsiniz (örn: bir butonun onPressed'inden)
void scheduleMyTask() {
Workmanager().registerOneOffTask(
"task-identifier-1", // Görev için benzersiz bir ID
"basitArkaPlanGorevi", // callbackDispatcher'da yakalayacağımız görev adı
initialDelay: Duration(seconds: 10), // İsteğe bağlı: Hemen değil, 10 sn sonra başlasın
constraints: Constraints(
networkType: NetworkType.connected, // Sadece internet varken çalışsın
requiresCharging: false, // Şarjda olma zorunluluğu yok
requiresBatteryNotLow: true, // Pil düşükken çalışma
),
inputData: <String, dynamic>{ // Göreve veri göndermek isterseniz
'mesaj': 'Merhaba Arka Plan!',
'kullaniciId': 123,
},
);
print("Görev planlandı!");
}
// Örnek bir Buton ile Tetikleme
class MyHomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("WorkManager Denemesi")),
body: Center(
child: ElevatedButton(
onPressed: () {
scheduleMyTask();
},
child: Text("Arka Plan Görevini Planla"),
),
),
);
}
}
Burada registerOneOffTask ile tek seferlik bir görev planladık. constraints parametresi ile görevin hangi koşullarda çalışacağını belirttik. Bu, pil ve veri tasarrufu için çok önemlidir!
WorkManager sadece tek seferlik görevlerle sınırlı değil.
- Tek Seferlik Görevler (registerOneOffTask): Yukarıda gördüğümüz gibi, bir kez çalışması gereken işler için idealdir.
- Periyodik Görevler (registerPeriodicTask): Belirli aralıklarla (örneğin her saat başı) tekrar etmesi gereken görevler için kullanılır.
Workmanager().registerPeriodicTask(
"periodic-task-id",
"veriSenkronizasyonu", // callbackDispatcher'daki ilgili case adı
frequency: Duration(hours: 1), // Minimum 15 dakika olabilir
constraints: Constraints(networkType: NetworkType.connected),
);
- Zincirleme Görevler: Bir görevin bitiminde başka bir görevin başlaması gibi daha karmaşık iş akışları da oluşturabilirsiniz (WorkManager’ın kendi dokümantasyonunda WorkManager.beginWith().then()…enqueue() gibi yapılarla anlatılır).
Bu yazımda sizlere Flutter Android WorkManager Kullanımını anlatmaya çalıştım. WorkManager paketini Flutter uygulamamızda Android kısmı için nasıl kullanabiliriz sizlere aktarmaya çalıştım. Umarım ilgilisi için faydalı bir yazı olmuştur.
Github: www.github.com/abdullah017
Linkedin: www.linkedin.com/in/abdullahtas
Stackoverflow: https://stackoverflow.com/users/13807726/abdullah-t