Android EventBus Kütüphanesi Kullanımı

Merhaba arkadaşlar,
Mobilhanem.com sitemiz üzerinden anlattığımız/yayınladığımız Android  derslerimize Android EventBus Kütüphanesi Kullanımı ile devam ediyoruz. Bir çok android geliştiricinin kullanması gereken kütüphanelerden biride EventBus dır. EventBus kütüphanesi ile uygulama içindeki event ları kolaylıkla yakalayabilir , Fragment, Activity, Thread, Service vb sınıflar arasında da veri transferini gerçekleştirebiliriz. Bu kütüphane olmadan zaten klasik yöntem ile yani Interface kullanarak da event ları yakalayabiliriz. Fakat bu kütüphane ile kod yapısı daha okunabilir ve düzgün bir hale gelmiştir.

( ayrıntılı incelemek için github adresi : EventBus )

EventBus kütüphanesinin işleyişini bu resimde görebiliriz. Bir event yayımlanır EventBus sayesinde de yayımlanan event ilgili abone ler tarafından yakalanır. Uygulamanızda birden fazla event olabilir yada tek bir event fırlatılır ve bütün projede o event yakalanıp kullanılır. ( örnek olarak telefonun şarj yüzdesini gösteren bir event düşünün olay tekdir ve uygulamanın her yerinde şarj yüzdesinin ne kadar olduğunun gösterilmesi EventBus tarafından kolaylıkla transfer edilir. )

EventBus kütüphanesinin nasıl kullanıldığını anlayabilmek için temel bir örnek yapalım. Bu örnekte sizlere Activity den Activity e nasıl object gönderilir , Activity den Fragment lara nasıl veri gönderilir gibi önemli unsurlardan bahsedeceğim. Öncelikle android projemize EventBus kütüphanesini import ediyoruz. build.gradle klasörüne aşağıdaki kodu ekliyoruz ve daha sonra projemizi sync ediyoruz.

compile 'org.greenrobot:eventbus:3.0.0'

GreenRobot un çıkarmış olduğu GreenRobot EventBus kütüphanesi size Square şirketinin EventBus kütüphanesinin çağırıştırabilir ikiside aynı işlev için kullanılıyor fakat Square şirketinin çıkarmış olduğu bu kütüphane artık deprecated olduğu için GreenRobot EventBus kütüphanesi tercih ediliyor.

Kısaca kullanım şeklinden de bahsedecek olursam; Fragment da yada Activity de olayın meydana geldiğini tek satır kod ile belirtiyoruz.

EventBus.getDefault().post(new EventBusEvent("Mobilhanem EventBus Kullanımı");

Bu olayı başka bir sınıfta yakalamak istiyorsak da o olayı yakalamak istediğimizi ilgili sınıfa haber veriyoruz bu işlemede register işlemi deniyor.

EventBus.getDefault().register(this);

İlgili olayı artık dinlemek istemiyorsak veya onunla ilgili işlemimiz bittiyse artık haberdar olmak istemediğimizi söylüyoruz bu işlemede unregister işlemi deniyor.

EventBus.getDefault().unregister(this);

Gerçekleştirmek istediğimiz olayı artık yakalayıp kullanmak istiyorsak da Fragment yada Activity sınıfımızda subscribe ederek fonksiyonu yazıyoruz.

@Subscribe
    public void onEvent(EventBusEvent messageEvent){

        // ilgili event alındıktan sonra yapılmasını istediğin işlemler
    }

Evet arkadaşlar temel kuralları söyledikten sonra şimdi uygulamalı olarak nasıl yapıldığını anlatalım; öncelikle EventBus sınıfımızı singleton olarak yani tek bir sınıf üzerinden kontrol etmemiz uygulamamızı rahatlatacağı için aşağıdaki yapıyı oluşturuyoruz.

GlobalBus.java

public class GlobalBus {

    private static EventBus eventBus;

    public static EventBus getBus() {
        if (eventBus == null)
            eventBus = EventBus.getDefault();
        return eventBus;
    }
}

Şimdi gelelim MainActivity sınıfımızı oluşturmaya ; bu uygulamada kullanıcı bir input girecek ve string gönder dediği anda ilgili Fragment lar tetiklenecek EventBus yardımı ile de gelen değer alınıp Fragment larda gösterilecektir. object gönder butonuna bastığımız da ise kod tarafında oluşturduğumuz User objesi diğer Activity e gönderilecek ve gerekli işlemler yapılacaktır. MainActivity sınıfımız aşağıdaki gibidir.

MainActivity.class

package com.mobilhanem.eventbusexample;

import android.content.Intent;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.mobilhanem.eventbusexample.event.ActivityToActivityEvent;
import com.mobilhanem.eventbusexample.event.ActivityToFragmentEvent;
import com.mobilhanem.eventbusexample.fragment.FirstFragment;
import com.mobilhanem.eventbusexample.fragment.SecondFragment;
import com.mobilhanem.eventbusexample.model.User;

public class MainActivity extends AppCompatActivity {

    private FragmentManager fragmentManager;
    private EditText editText;
    private Button sendBtn, sendData;
    private User user;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        addFragments();

        sendBtn = (Button)findViewById(R.id.sendBtnMsg);
        editText = (EditText)findViewById(R.id.edittextMsg);
        sendData = (Button)findViewById(R.id.sendBtnObject);

        sendBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(editText.getText().toString().length()>0){
                    GlobalBus.getBus().post(new ActivityToFragmentEvent(editText.getText().toString()));
                }
            }
        });

        sendData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(),ThirdActivity.class);
                user = new User("Alper","Beyler","Bilgisayar Mühendisi",25);
                GlobalBus.getBus().postSticky(new ActivityToActivityEvent(user));
                startActivity(intent);
            }
        });
    }

    private void addFragments() {

        fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fragment_one,new FirstFragment(),"fragmentOne");
        fragmentTransaction.add(R.id.fragment_two,new SecondFragment(),"fragmentTwo");
        fragmentTransaction.commit();
    }
}

Yukarıdaki kod yapısında gördüğünüz gibi uygulamamızda iki farklı olayın tetiklenmesini istedik birisi Fragment lara veri göndermek için diğeri ise Activity ler arası iletişim için işte bu yüzden iki farklı event tanımlıyoruz. Eğer farklı event lar tanımlamazsak EventBus da tek bir sınıf üzerinden gittiğimiz için de bir eventı tetiklediğimiz de diğer event de eğer bunu dinliyorsa orası da etkilenecektir. Bu konuda dikkat etmemiz gerekiyor. Nerede ne kullancağımızı belirleyip ona göre event lar oluşturmalıyız.

ActivityToActivityEvent.java

package com.mobilhanem.eventbusexample.event;

import com.mobilhanem.eventbusexample.model.User;

/**
 * Created by alper on 06/02/17.
 */

public class ActivityToActivityEvent {

    private User user;

    public User getUser() {
        return user;
    }

    public ActivityToActivityEvent(User user) {
        this.user = user;
    }
}

ActivityToFragment.java

package com.mobilhanem.eventbusexample.event;

/**
 * Created by alper on 05/02/17.
 */

public class ActivityToFragmentEvent {

    private String msg;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
    public ActivityToFragmentEvent(String msg) {
        this.msg = msg;
    }
}

FirstFragment.java sınıfımız aşağıdaki gibidir. onResume ve onPause methodlarında gerekli register ve unregister kodlamalarını yaptık. Yukarıda oluşturduğumuz event geldiğinde de içinden değeri alıp ekranda gösterdik. ( not: Eğer Fragment ımızı register etmeden kodu çalıştırırsak gelen değeri hiç bir şekilde alamayacağız. Ayrıca haberdar olma işlemi bittiğinde gereksiz yere kodun ilgili event dan haberdar olmasını kesmek içinde unregister demeyi kesinlikle unutmuyoruz. Aksi halde gereksiz yere haberdar olmaya devam edecek ve kodlamada memory leak olaylarına girecektir. Bu örnekte sadece iki tane event oluşturup haberdar etmeye çalıştık fakat uygulamamızın boyutun daha büyük ve kapsamlı olduğunu düşünürsek anlattığım şekilde kodlama yapmaya özen göstermeliyiz. )

FirstFragment.java

package com.mobilhanem.eventbusexample.fragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.mobilhanem.eventbusexample.GlobalBus;
import com.mobilhanem.eventbusexample.R;
import com.mobilhanem.eventbusexample.event.ActivityToFragmentEvent;

import org.greenrobot.eventbus.Subscribe;


public class FirstFragment extends Fragment {


    private TextView txtMsg;
    @Override
    public void onResume() {
        super.onResume();
        GlobalBus.getBus().register(this);
    }

    @Override
    public void onPause() {
        super.onPause();
        GlobalBus.getBus().unregister(this);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_first, container, false);
        txtMsg = (TextView)view.findViewById(R.id.txtMessageFirstFragment);
        return view;
    }

    @Subscribe
    public void onEvent(ActivityToFragmentEvent messageEvent){

        txtMsg.setText(messageEvent.getMsg());
    }

}

MainActivity sınıfımızdan postSticky kullanarak ThirdActivity sınıfımıza User objesi gönderdik ( User modelinin içinde isim, soyad, bölüm ve yaş gibi değişkenleri tuttuk ) ilgili Activity event dan haberdar olduğunda gelen User objesinin içindeki değerleri ekranda gösterdik.

ThirdActivity.java

package com.mobilhanem.eventbusexample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import com.mobilhanem.eventbusexample.event.ActivityToActivityEvent;
import com.mobilhanem.eventbusexample.model.User;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

public class ThirdActivity extends AppCompatActivity {

    private TextView txtName;
    private TextView txtSurname;
    private TextView txtAge;
    private TextView txtDepartment;
    @Override
    protected void onStart() {
        super.onStart();
        GlobalBus.getBus().register(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        GlobalBus.getBus().unregister(this);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);

        txtName = (TextView)findViewById(R.id.txtName);
        txtSurname = (TextView)findViewById(R.id.txtSurname);
        txtDepartment = (TextView)findViewById(R.id.txtDepartment);
        txtAge = (TextView)findViewById(R.id.txtAge);

    }

    @Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
    public void onEvent(ActivityToActivityEvent event) {
        txtName.setText("Ad:"+" "+event.getUser().getName());
        txtSurname.setText("Soyad:"+" "+event.getUser().getSurname());
        txtDepartment.setText("Bölüm:"+" "+event.getUser().getDepartment());
        txtAge.setText("Yaş:"+" "+String.valueOf(event.getUser().getAge()));
    }
}

User modelimizde aşağıdaki gibidir.

User.java

package com.mobilhanem.eventbusexample.model;

/**
 * Created by alper on 10/02/17.
 */

public class User {
    private String name;
    private String surname;
    private String department;
    private int age;

    public User(String name,String surname,String department,int age){
        this.name = name;
        this.surname = surname;
        this.department = department;
        this.age = age;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public String getDepartment() {
        return department;
    }

    public void setDepartment(String department) {
        this.department = department;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

Evet arkadaşlar aslında yaptığımız işlemler bu kadar EventBus kütüphanesinin kullanarak hem kod karmaşıklığını azaltmış hem de daha performanslı kodlar oluşturmuş oluyoruz. Activity , Fragment , Service , Thread vb. android bileşenleri arasında etkili bir iletişim kurmak istiyorsak EventBus kullanımı işte bu kadar kolay. Dersimizdeki kaynak kodu indirip çalıştırdığınızda yapılan işlemlerin ekran görüntüleride aşağıdaki gibidir.

İlgili iki Fragment sınıfımıza “mobilhanem” çıktısını gönderdik ve gördüğünüz gibi ekranda gösterdik.

       

Object Gönder dediğimizde ise aşağıdaki ekran görüntüsünü alacaksınız android cihazınızda.

 

EventBus olmadan Intent ler arası veri gönderimi nasıl oluyordu derseniz de bu dersimizi inceleyebilirsiniz.

Mobilhanem.com üzerinden anlattığımız mobil uygulama geliştirme derslerine devam edeceğiz. Konu hakkında sorunuzu yorum alanından sorabilirsiniz. Konu dışı sorularınızı ve tüm yazılımsal sorularınızı sorucevap.mobilhanem.com sitemizden de sorabilirsiniz.

Bir dahaki dersimizde görüşmek dileğiyle..

Tüm Android Ders, Proje ve Kaynak Kodlar için tıklayınız.

 

 

 

1

Alper Beyler

Yüksek Lisans: Çankaya Üniversitesi / Bilgisayar Mühendisliği
Lisans: Çankaya Üniversitesi / Bilgisayar Mühendisliği (4/3.30) (2010-2014)
Lisans : Viyana Teknik Üniversitesi / Bilgisayar Bilimleri (2013)

12 Yorum

  • Merhabalar. Verilerimi gerek ilkel veriler gerek sınıf objeleri/listeleri olmak üzere Sharepreference ile taşıyorum. Bu konuda düşünceleriniz alabilrimiyim. Sqlite-Shareprefernce kullanımının proje boyutuna etkisi hakkında nedir deneyimleriniz. Share yapısına alışıgım fakat uygulama boyutunu çok etkiliyor bu etki Sqlite yapısı ile aynı etkide midir.? Bunları söylerken konumun eventbusla ilişkisi; bu noktada bu üçlü veri depolama/aktarma sistemleri arasında + ve – leri aramaktayım.

    • SHAREDPREFERENCES data keydetmek içindir, data taşımak için değil. Yanlış bir yöntem Sqlite ile de veri taşınmaz bunlar verileri depolamak içindir.
      Yönteminizi değiştirmelisiniz.

      • Kaydedip gerekli yerde çekip kullanmaya taşımak olarak ifade ettim. Depolama aracı olarak kullanıyorum. Sormak istediğim uygulamanın boyutuna etkisi noktasında kıyaslanması idi.

          • Elbette yöntemlerin artıları eksileri var. Sqlite işlemlerin upraştırıcı olduğu için gerekmedikce uzak duruyorum. Soruna gelince ilgili veriyi share ile ilgili “anahlatkelime ” ile malum putString() saklıyor diğer sayfada aynı anahtar kelime ile getString() ile elde ediyorum. Ve döngü kurulduğu zaman temizleme işlemleri

          • Samir Samedov, Peki başka bir uygulama ile başka bir uyglamanın preferencesine string nasıl eklenir?

  • Anlatıma uygun şekilde kendi projeme eklediğimde şöyle hata alıyorum:

    E/EventBus: Could not dispatch event:

    göstermek istediğim bütün yapılarda NullPointerException veriyor. Bunun problemin sebebi nedir acaba?

  • Merhaba projeme Eventbus Kütüphanesini ekledim, sitede yer alan eventbus eğitiminden yararlanarak kodlamayı yaptım fakat şöyle bir hata alıyorum.
    E/EventBus: Could not dispatch event
    Göstermek istediğim bütün yapılar NullPointerException veriyor.Bu problemin sebebi nedir acaba?

Haftalık Bülten

Mobilhanem'de yayınlanan dersleri haftalık mail almak ister misiniz?