Mobil Programlama

Android

Android Servisler

Lisans: Creative Commons 26.11.2020 tarihinde güncellendi
Bakabileceğiniz Etiketler: Eğitmen: Geleceği Yazanlar Ekibi

 

Android uygulamalarında arka planda çalışan ve kullanıcının uygulamayla olan ilişkisini etkilemeyen işlemler için Service adında bir sınıf bulunur. Veritabanı güncellemeleri, günlük hata raporlarının bildirilmesi gibi rutin arka plan işlemleri için bir servis yaratma ihtiyacı duyduğumuzda Service sınıfından bir alt sınıf yaratarak gerekli işlemleri kullanıcıyı rahatsız etmeden gerçekleştirebiliriz.

Bu bölümde Service tipi bir sınıf olan IntentService sınıfından bahsedeceğiz. Bir Activity içerisinden tetiklenerek harekete geçen IntentService, işlemlerini kullanıcıyı rahatsız etmeden arka planda yürütür ve kendini yok eder. Örneğimizde arka planda bir web sitesinden bilgi alıp bunu ön planda yer alan (UI Thread) bir görsel öğeye LocalBroadCastManager ile nasıl aktaracağımızı göreceğiz.

Öncelikle yeni bir proje yaratalım ve AndroidManifest dosyası içerisinde aşağıdaki düzenlemeleri gerçekleştirelim:

 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.turkcell.backgroundservice"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
 
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.turkcell.backgroundservice.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
        <service
            android:name=".HelloService"
            android:exported="false" />
    </application>
 
    <uses-permission android:name="android.permission.INTERNET" />
 
</manifest>

 

 

Uzaktaki bir web servisine bağlanacağımızdan uygulamadan internet iznini almamız gerekmektedir. Yaratacağımız servisin de uygulama tarafında sorunsuz çalışması için application içerisinde bir service olarak tanımlanması gerekir. Biz oluşturacağımız servise HelloService adını verdik. Buradaki exported özelliği servisin uygulama dışından tetiklenmemesi için yanlış (false) değerini aldı.

Bu noktadan sonra HelloService adlı sınıfı aşağıdaki gibi oluşturalım:

 

package com.turkcell.backgroundservice;

import android.app.IntentService;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

public class HelloService extends IntentService {
    private static final String serviceName = "HelloService";

    public HelloService() {
        super(serviceName);
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        String url = intent.getData().toString();
        Log.d("HelloService", url);
        String urlContent = ConnectionHelper.getUrl(url);
        Log.d("HelloService", urlContent);

        Intent serviceIntent = new Intent(serviceName);
        serviceIntent.putExtra("urlContent", urlContent);
        LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(serviceIntent);
    }
}

 

 

IntentService sınıfı bizden onHandleIntent metodunu gerçekleştirmemizi ister. Biz bu metot içerisinde bir URL içeriğini indirip LocalBroadCastManager üzerinden ana ekranla paylaşan bir kod yazdık. İçeriği indirilecek web adresi gönderilen Intent ile beraber alındı ve daha önceki bölümlerde kullandığımız ConnectionHelper sınıfı ile internet üzerinden indirildi. Daha sonra yeni bir Intent içerisine urlContent anahtarıyla servisin içeriği eklendi ve LocalBroadcastManager ile uygulama içerisine “HelloService” adında bir uyarı olarak atıldı. Burada uygulama içerisindeki bu uyarıları dinleyen kayıtlı metotlar gönderilen mesajı alarak içerisindeki urlContent değerini okuyabilecekler.

Son olarak MainActivity sınıfına göz atalım:

 

package com.turkcell.backgroundservice;
 
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.webkit.WebView;
 
public class MainActivity extends Activity {
 
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
 
      Intent intent = new Intent(MainActivity.this, HelloService.class);
      intent.setData(Uri.parse("http://www.turkcell.com.tr"));
 
      startService(intent);
      LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(mMessageReceiver, new IntentFilter("HelloService"));
    }
 
   @Override
   protected void onDestroy() {
      super.onDestroy();
      LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(mMessageReceiver);
   }
 
   private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
 
    @Override
    public void onReceive(Context context, Intent intent) {
      WebView webview = (WebView) findViewById(R.id.webview);
      webview.getSettings().setJavaScriptEnabled(true);
      webview.loadData(intent.getStringExtra("urlContent"), "text/html;", null);
    }
  };
}

 

 

onCreate altında startService ile yeni bir servis tetikleyebiliriz. Burada servise gönderilen Intent içinde setData metoduyla servisin içeriğini indireceği web adresi (URL) bilgisini veriyoruz. Bu noktada HelloService içerisindeki kod turkcell.com.tr adresinin içeriğini çekip bir LocalBroadcast uyarısı atacaktır. Gelen uyarıyı yakalayabilmek için bir BroadcastReceiver oluşturarak bunu daha önceki bölümlerdeki gibi kaydederiz. HelloService istenilen işlemleri tamamladıktan sonra Turkcell web sitesindeki HTML kodunu bir String olarak Intent üzerinden yollayacaktır. Biz de bu String değerini intent.getStringExtra metoduyla yakalayarak layout dosyası üzerinde oluşturduğumuz bir WebView içerisine vereceğiz. Bu ekranda kullandığımız layout dosyası aşağıdaki gibidir:

 

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
 
    <WebView
        android:id="@+id/webview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        />
 
</RelativeLayout>