Pull to refresh

Взаимодействие между приложением и службой

Reading time 5 min
Views 20K

Введение


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


Схема взаимодействия будет следующая, приложение регистрирует приемник широковещательных сообщений, который получает данные от службы, далее запускается сама служба, передача данных от приложения к службе будет реализована через 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).
Tags:
Hubs:
+29
Comments 18
Comments Comments 18

Articles