Bu derste bound service çeşidini incelemeye başlıyoruz. İlk olarak şuana kadar service türleri neydi onları açıklayalım, daha sonra bound service’in bunlardan farklarını anlatalım.
Daha önce started service konusunu incelemiştik. Bu servis geriye herhangi bir değer göndermeyen ve de onu çağıran componentten bağımsız olarak arka planda çalışan bir servis türüydü. yani onu çağıran activity kapansa bile çalışmaya devam ediyordu.
Intent servis de aslında started servicesin özel bir türü diyebiliriz(IntentService sınıfı Service sınıfından extend olur). Started servisten farkı ise yapı olarak uzun süren işlemleri ele alacak şekilde tasarlanmıştır. Yani main thread üzerinde değil de worker threadde çalışacak şekilde oluşturulmuş, uzun sürecek işlemler için gelen bir servis türüdür. Bu servisin started servisten farkı işlem bittiğinde destroy olmasıydı.
Her iki serviste 4 ana component olan activity, broadcast receiver, content provider ve de servis ile başlatılabilirdi. Ve her iki servis türü de tek taraflı bir iletişim vardı, onları başlatan componentlere geri veri göndermezlerdi(Bu sorunun çözmek için result receiver veya broadcast receiver kullanmıştık) Şimdi gelelim bound servis konusuna….
Bound service, adından da anlaşılacağı gibi onu çağıran componente bağımlıdır. Yani onu çağıran component sona erdiğinde servisimizde sona erer. 4 ana componentten 3ünü servise bound edebilirsiniz, BroadcastReceiver hariç… Bir componente bağımlı olduğundan stopService veya stopSelf methodları kullanılmaz. Ona bound olmuş aktif bir component kalmadığında kendisini sonlandırır. Ve sürekli olarak onu çağıran componentle iletişim halindedir. Bound service de main thread üzerinde çalışır. Bu yüzden uzun sürecek işlemleri bunda yapmamak gerekir.
Bound Servisde, onBind methodu diğer servislerin aksine null değil, bir IBinder geriye döner. Bu sayede biz onu bir componente bağlarız. bindService methoduyla bağı kurar, unBindService methodu ile ilgili bağı koparırırz.
Android dünyasında Bound service -> Server, onu başlatan component -> client olarak bilinir. Genellikle bind işlemi onStart() methodu içinde, unBind işlemi onStop methodu içerisinde çağrılır. Böylece servisimiz sadece Activity kullanıcıya görünürken aktiftir. Eğer siz activity’niz kullanıcıya görünür değilken de servisin aktif olmasını istiyorsanız bindService methodunu onCreate içinde, unbindService() methodunu onDestroy içinde çağırmalısınız.
Bu derste sadece service sınıfımızı oluşturduk. Bu sınıfta her saniyede bir random bir sayı üreten bir methodu bulunmaktadır. Ve biz servisi durdurana kadar bu işlem devam eder. Eğer biz bunu main thread üzerinde çalıştırırsak ANR(Application Not responding) hatası alırız. Bu yüzden random sayı üreten bu methodu farklı bir thread üzerinde çalıştırmak için Thread sınıfını kullandık. Siz burda Asynctask sınıfını da kullanabilirsiniz. Ayrıca bu servisi onu çağıran componente bağlamak için gerekli alt yapıyı hazırladık. Yazdığımız kodlar sayesinde, onBind methodu oluşturduğumuz yerel bağlayıcı sınıfın nesnesini geriye dönebilecek.
Neden yerel diyoruz? Çünkü servisimize bağlayacağımız component ile(MainActivity) servisimiz aynı uygulama yani aynı process üzerinde çalışıyor. İki farklı uygulama üzerindeki component ve servis bağlama işlemi için daha sonra remote binder ifadesini kullanacağız.
Ayrıca bu sınıfta tüm servis sınıfımızı geriye dönecek bir getService methodu da bulunmaktadır. Bu sınıfları nasıl ve nerede kullanacağımızı bir sonraki derste anlatacağım.
Bu derste yazılan kodlar aşağıdaki gibidir :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
public class MainActivity extends AppCompatActivity { private final static String TAG = MainActivity.class.getSimpleName(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void startMyBoundService(View view) { Intent intent = new Intent(this, MyBoundService.class); startService(intent); } public void stopMyBoundService(View view) { Intent intent = new Intent(this, MyBoundService.class); stopService(intent); } public void bindMyBoundService(View view) { } public void unbindMyBoundService(View view) { } public void getRandomNumber(View view) { } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
public class MyBoundService extends Service { private final static String TAG=MyBoundService.class.getSimpleName(); private int sayi; private boolean sayiUreticisiAcikMi; class MyLocalBinder extends Binder{ public MyBoundService getService(){ return MyBoundService.this; } } private IBinder myLocalBinder=new MyLocalBinder(); @Nullable @Override public IBinder onBind(Intent intent) { Log.i(TAG, "ONBIND"); return myLocalBinder; } @Override public void onCreate() { Log.i(TAG, "ONCREATE"); super.onCreate(); } @Override public void onDestroy() { Log.i(TAG, "ONDESTROY"); sayiUreticisiAcikMi=false; super.onDestroy(); } @Override public int onStartCommand(Intent intent,int flags, int startId) { Log.i(TAG, "ONSTARTCOMMAND"); sayiUreticisiAcikMi=true; new Thread(new Runnable() { @Override public void run() { sayiUret(); } }).start(); return START_STICKY; } private void sayiUret(){ while(sayiUreticisiAcikMi) { try { Thread.sleep(1000); sayi = new Random().nextInt(100); Log.i(TAG, "Sayi : " + sayi + " Thread Adı: " + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="12dp" android:onClick="startMyBoundService" android:text="START SERVICE" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignStart="@+id/button3" android:layout_below="@+id/button3" android:layout_marginTop="12dp" android:onClick="stopMyBoundService" android:text="STOP SERVICE" /> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignStart="@+id/button4" android:layout_below="@+id/button4" android:layout_marginTop="15dp" android:onClick="bindMyBoundService" android:text="BIND SERVICE" /> <Button android:id="@+id/button6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignStart="@+id/button5" android:layout_below="@+id/button5" android:layout_marginTop="15dp" android:onClick="unbindMyBoundService" android:text="UNBIND SERVICE" /> <Button android:id="@+id/button7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/button6" android:layout_centerHorizontal="true" android:layout_marginTop="20dp" android:onClick="getRandomNumber" android:text="Rastgele Sayıyı Al" /> </RelativeLayout> |