Введение


В данной публикации хочу показать пример взаимодействия (получение и отправки данных) приложения и службы, в операционной системе Андроид. Публикация рассчитана на начинающих программистов, теории практически не будет, так как основная цель рассказать, как это сделать.


Схема взаимодействия будет следующая, пр��ложение регистрирует приемник широковещательных сообщений, который получает данные от службы, далее запускается сама служба, передача данных от приложения к службе будет реализована через AIDL механизм.

Перед тем как начать, у вас должны быть установлены основные компоненты для создания Андроид приложений, такие как Java (JDK и JRE), Eclipse, Android SDK и плагин ADT для Eclipse, о том, как это установить и настроить вы можете прочесть на страницах Хабрахабр.

1. Создаем приложение и службу


Запускаем Eclipse, далее нажимаем Ctrl+N, в появившемся диалоговом окне выбираем пункт «Android Project» и следуем инструкции, показанной на изображении:



Тем самым мы создали каркас приложения, теперь нужно добавить службу, для этого необходимо создать новый класс, наследованный от класса Service, нажимаем правой кнопкой мыши по пакету нашего проекта:



Далее появится диалоговое окно, в котором необходимо сделать следующие действия:



Теперь добавим наш сервис в файл AndroidManifest.xml, для этого открываем его в Eclipse и делаем следующее:



2. Получение информации от службы


Для получения информации от службы, необходимо зарегистрировать приемник широковещательных сообщений, для этого добавим соответствующий код в методы onCreate и onDestroy приложения:

@Override
public void onCreate(Bundle savedInstanceState) 
{
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);
	//Регистрация приемника
	IntentFilter filter = new IntentFilter();
	filter.addAction("AppService");
	service = new BroadcastReceiver() 
	{
		@Override
		public void onReceive(Context context, Intent intent) 
		{
			if(intent.getAction().equals("AppService"))
			{
				Log.i("AppService",intent.getStringExtra("Data"));
			}
		}
	};
	registerReceiver(service, filter);
        //Запуск службы
        startService(new Intent(this,MainService.class));
	
}
@Override
protected void onDestroy()
{	
	super.onDestroy();
	if(service!= null){unregisterReceiver(service);}
	stopService(new Intent(this,MainService.class));
}


В службе, информация передается путем отправки широковещательного сообщения, добавим метод onCreate и отправку:

@Override
public void onCreate()
{
	super.onCreate();
	Intent in = new Intent("AppService");
	in.putExtra("Data","Служба запущена.");
	sendBroadcast(in);
}


Запускаем наше приложение и видим в LogCat информацию, полученную от службы и обработанную в основном коде приложении:



3. Передача данных службе


Теперь добавим механизм AIDL к нашему проекту, для этого добавим файл с расширение aidl:



Появится диалоговое окно, в котором вводим следующие данные:



Откроется окно редактирования файла UpdateService.aidl, добавляем следующий код:

package ru.blagin.appservice;

interface UpdateService 
{
        String UpdateSrv(String strTest);
}


После чего необходимо сохранить изменения и пересобрать проект, если отключена опция автоматической сборки, далее ADT плагин автоматически сгенерирует код, необходимый для работы данного механизма. Теперь нужно изменить код основного приложения и службы. Добавим реализацию интерфейса ServiceConnection в основной код приложения, изменим запуск и остановку службы, а так же добавим кнопку, при нажатии на которую будет осуществлена передача данных:

package ru.blagin.appservice;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import ru.blagin.appservice.UpdateService;

public class Main extends Activity 
{
	private BroadcastReceiver brService = null;
	
	UpdateService iService = null;
	private ServiceConnection mConnection = new ServiceConnection() 
	{
		public void onServiceDisconnected(ComponentName name)
		{
			iService = null;
		}
		public void onServiceConnected(ComponentName name, IBinder service)
		{
			iService = UpdateService.Stub.asInterface(service);
		}
	};
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
              	
      	//Регистрация приемника
        	IntentFilter filter = new IntentFilter();
		filter.addAction("AppService");
		brService = new BroadcastReceiver() 
		{
			@Override
			public void onReceive(Context context, Intent intent) 
			{
				if(intent.getAction().equals("AppService"))
				{
					Log.i("AppService",intent.getStringExtra("Data"));					
				}
		    }
		};
		registerReceiver(brService, filter);
		
		//Запуск службы
      	bindService(new Intent(this,MainService.class),mConnection,BIND_AUTO_CREATE);
      
      	Button bt = (Button)findViewById(R.id.buttonSend);
      	bt.setOnClickListener(new OnClickListener()
		{
			public void onClick(View v)
			{
				//Отправляем данные
				try
				{
		        	String strResult = iService.UpdateSrv("String from app");
		        	Log.i("AppService",strResult);
		        	
				}catch(RemoteException e){Log.e("AppService",e.getMessage());}
			}
		});
    }
    @Override
    protected void onDestroy()
    {	
    	super.onDestroy();
    	if(brService!= null){unregisterReceiver(brService);}
    	if(mConnection!= null){unbindService(mConnection);}
    }
}


Внесем изменения в код службы:

package ru.blagin.appservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

public class MainService extends Service
{
	Intent in = null;
	@Override
	public void onCreate()
	{
		super.onCreate();
		in = new Intent("AppService");
		in.putExtra("Data","Служба запущена.");
        	sendBroadcast(in);
	}
	@Override
	public IBinder onBind(Intent intent)
	{
	    return new UpdateService.Stub() 
	    {
			public String UpdateSrv(String strTest) throws RemoteException
			{
				strTest = strTest + " and service.";
				in.putExtra("Data","Вызов метода интерфейса.");
		        	sendBroadcast(in);
				return strTest;
			}
	    };
	}
	@Override
	public void onDestroy()
	{
		super.onDestroy();
	}
}


Запускаем приложение и нажимаем кнопку, происходит отправка тестовой строки в сервис, далее к строке добавляется еще одна и результат выводится через методы класса Log:



Заключение


Надеюсь, эта небольшая статья поможет вам в дальнейшем уже глубже разобраться в механизмах взаимодействия и работы приложений в операционной системе Андроид. Хотелось еще раз отметить, что данный текст, создавался исключительно для начинающих программистов и главным критерием, написания, было ответить на вопрос «Как это сделать?».

Исходный код приложения.

Список используемой литературы


  1. Pro Android 3 — Satya Komatineni, Dave MacLean, Sayed Hashimi, 2011 г.
  2. AIDL (Android Interface Definition Language) и коммуникация между процессами (IPC) (umobisoft).