Looper'ın GUI çerçevesi bağlamında ne olduğunu daha iyi anlayabilirsiniz. Lüper 2 şey yapmak için yapılır.
1) Looper , run () yöntemi döndüğünde sona eren normal bir iş parçacığını , Android uygulaması çalışana kadar sürekli çalışan bir şeye dönüştürür , bu da GUI çerçevesinde gereklidir (Teknik olarak, run () yöntemi geri döndüğünde hala sona erer. aşağıda ne demek istediğimi netleştirin).
2) Looper , GUI çerçevesinde de yapılması gereken işlerin sıralandığı bir kuyruk sağlar .
Bildiğiniz gibi, bir uygulama başlatıldığında, sistem uygulama için "ana" olarak adlandırılan bir yürütme dizisi oluşturur ve Android uygulamaları normalde varsayılan olarak "ana iş parçacığı" olarak tek bir iş parçacığında çalışır. Ancak ana iplik bazı gizli, özel iplik değildir . Bu sadece new Thread()
kod ile oluşturduğunuz iş parçacıklarına benzer normal bir iş parçacığıdır , yani run () yöntemi döndüğünde sonlandırılır! Aşağıdaki örneği düşünün.
public class HelloRunnable implements Runnable {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
Şimdi bu basit prensibi Android uygulamalarına uygulayalım. Bir Android uygulaması normal iş parçacığında çalışırsa ne olur? "Ana" veya "Kullanıcı Arayüzü" olarak adlandırılan bir iş parçacığı veya uygulamanızı başlatan her şey ve tüm kullanıcı arayüzünü çizer. Böylece, ilk ekran kullanıcılara gösterilir. Peki şimdi ne olacak? Ana iş parçacığı sonlandırılıyor mu? Hayır, olmamalı. Kullanıcılar bir şeyler yapmayı beklemeli, değil mi? Fakat bu davranışı nasıl başarabiliriz? İle deneyebiliriz Object.wait()
veyaThread.sleep()
. Örneğin, ana iş parçacığı ilk ekranı görüntülemek için ilk işini bitirir ve uyur. Uyanır, yani yapılacak yeni bir iş getirildiğinde kesintiye uğramak anlamına gelir. Şimdiye kadar çok iyi, ama şu anda birden fazla işi tutmak için kuyruk benzeri bir veri yapısına ihtiyacımız var. Bir kullanıcının ekrana seri olarak dokunduğu ve bir görevin tamamlanması daha uzun sürdüğü bir durumu düşünün. Bu nedenle, yapılacak işleri ilk giren ilk çıkar yolunda tutabilmek için bir veri yapısına ihtiyacımız var. Ayrıca, kesme kullanarak sürekli çalışan ve işlenen iş geldiğinde iş parçacığının uygulanmasının kolay olmadığını ve karmaşık ve çoğu zaman sürdürülemez koda yol açtığını hayal edebilirsiniz. Böyle bir amaç için yeni bir mekanizma oluşturmayı tercih ediyoruz ve Looper'ın konusu bu . Looper sınıfının resmi belge"Varsayılan olarak iş parçacıklarının kendileriyle ilişkili bir mesaj döngüsü yoktur" ve Looper "bir iş parçacığı için bir mesaj döngüsü çalıştırmak için kullanılan bir sınıftır". Şimdi bunun ne anlama geldiğini anlayabilirsiniz.
İşleri daha net hale getirmek için, ana iş parçacığının dönüştürüldüğü kodu kontrol edelim. Her şey ActivityThread sınıfında olur . Main () yönteminde, normal bir ana iş parçasını ihtiyacımız olan bir şeye dönüştüren aşağıdaki kodu bulabilirsiniz.
public final class ActivityThread {
...
public static void main(String[] args) {
...
Looper.prepareMainLooper();
Looper.loop();
...
}
}
ve Looper.loop()
yöntem sonsuz döngü ve bir mesajı ayıklayın ve birer birer işleyin:
public static void loop() {
...
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
...
msg.target.dispatchMessage(msg);
...
}
}
Yani, temelde Looper GUI çerçevesinde oluşan bir problemi çözmek için yapılmış bir sınıftır. Ancak bu tür ihtiyaçlar başka durumlarda da ortaya çıkabilir. Aslında çok iş parçacığı uygulaması için oldukça ünlü bir desen ve Doug Lea tarafından " Java Eşzamanlı Programlama " (Daha, Bölüm 4.1.4 "İşçi Konu" yararlı olacaktır) hakkında daha fazla bilgi edinebilirsiniz . Ayrıca, bu tür bir mekanizmanın Android çerçevesinde benzersiz olmadığını hayal edebilirsiniz, ancak tüm GUI çerçevesinin buna biraz benzemesi gerekebilir. Java Swing çerçevesinde neredeyse aynı mekanizmayı bulabilirsiniz.