상세 컨텐츠

본문 제목

[Android]외부 바인드 서비스

Android 개발

by mobile 2013. 9. 21. 18:17

본문

반응형

서비스에 연결하는 방법에 따라 Local Procedure Call(LPC - 일명 lightweight Procedure Call) 으로 구현하는 방법과 Remote Procedure Call(RPC)로 구현하는 방법 으로 나누어 진다.


- RPC(Remote Procedure Call)

내부 바인드 서비스는 액티비티와 서비스 컴포넌트들이 동일한 프로세스내에세 작동하는 경우를 말한다. 서비스와 액티비티는 서로의 메서드와 필드를 컴파일시점에 알고 있고 또한 동일한 프로세스에서 작동하므로 영역 침해등의 문제가 발생하지 않는다. 외부 바인드서비스는 서비스나 서비스를 호출한 애플리케이션 컴포넌트(보통 액티비티)들이 서로 별개의 프로세스에서 작동하는 경우를 말한다. 이 경우 자신이 만든 컴포넌트라 하더라도 액티비티에서 서비스의 메서드를 호출하고 자 한다면, 자신 프로젝트 내부 자바 프로그래도 아니고 또한 안드로이드의 android.jar 파일도 아니므로 해당 메서드를 인지하지 못한는 문제가 가 발생한다.


■ 단방향 메시지를 이용한 바인드 서비스

메신저는 외부 바인드서비스와 연결하여 프로세스간에 메시지를 전송할 수 있도록 만든 클래스이다. 메신저의 생성자는 아래와 같이 두 종류가 있다.

- public Messenager(Handler target)

: 내부 핸들러와 연결되는 메신저이다. 메시지를 통해 작업 요청을 받기 위해서 서비스에서 내부 핸들러 객체를 사용하여 메신저 인스턴스를 생성한다. 메시지를 전송하는 Messenger.send(Message) 메서드의 기능은 핸들러의 Handler.sendMessage(Message) 메서드와 동일 하다.

- public Messenger(IBinder target)

: IBinder 객체로 전달된 핸들러를 사용하여 액티비티에서 메신저를 생성한다. 이때 새로 생성된 메신저는 서비스에 소속된 매신저의 복제이다.

- public IBinder getBinder()

: IBinder 객체를 생성하여 반환한다.

- public void send(Message message)

: 메시지 핸들러에게 전달한다. 만약 문제가 발생한다면 RemoteException 예외가 발생한다.



// AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.onewaymessengerservice"

    android:versionCode="1"

    android:versionName="1.0" >


    <uses-sdk

        android:minSdkVersion="8"

        android:targetSdkVersion="10" />


    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android:name="com.example.onewaymessengerservice.MsgServiceActivity"

            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="com.example.onewaymessengerservice.MessengerService" android:process=":remote" />

    </application>


</manifest>


// MsgServiceActivity.java

package com.example.onewaymessengerservice;


import android.app.Activity;

import android.content.ComponentName;

import android.content.Context;

import android.content.Intent;

import android.content.ServiceConnection;

import android.os.Bundle;

import android.os.IBinder;

import android.os.Message;

import android.os.Messenger;

import android.os.RemoteException;

import android.view.Menu;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TextView;

import android.widget.Toast;


public class MsgServiceActivity extends Activity {


Messenger mServiceMessenger = null;

boolean mIsBound;

TextView mCallbackText;


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);


Button button = (Button) findViewById(R.id.bind);

button.setOnClickListener(mBindListener);

button = (Button) findViewById(R.id.unbind);

button.setOnClickListener(mUnBindListener);


mCallbackText = (TextView) findViewById(R.id.callback);

mCallbackText.setText("Not attached.");

}


private final OnClickListener mBindListener = new OnClickListener() {


@Override

public void onClick(View arg0) {

// TODO Auto-generated method stub

doBindService();

}

};


private final OnClickListener mUnBindListener = new OnClickListener() {


@Override

public void onClick(View v) {

// TODO Auto-generated method stub

doUnbindService();

}

};


void doBindService() {

mIsBound = bindService(new Intent(MsgServiceActivity.this,

MessengerService.class), mConnection, Context.BIND_AUTO_CREATE);

}


void doUnbindService() {

if (mIsBound) {

unbindService(mConnection);

mIsBound = false;

mCallbackText.setText("Unbinding.");

}

}


private final ServiceConnection mConnection = new ServiceConnection() {


@Override

public void onServiceDisconnected(ComponentName className) {

// TODO Auto-generated method stub

mServiceMessenger = null;

mCallbackText.setText("Disconnected.");

Toast.makeText(MsgServiceActivity.this,

R.string.remote_service_disconnected, Toast.LENGTH_SHORT)

.show();

}


@Override

public void onServiceConnected(ComponentName className, IBinder service) {

// TODO Auto-generated method stub

mServiceMessenger = new Messenger(service);

mCallbackText.setText("Attached.");


try {

Message msg = Message.obtain(null,

MessengerService.MSG_REGISTER_CLIENT);

mServiceMessenger.send(msg);

} catch (RemoteException e) {

// TODO: handle exception

}

Toast.makeText(MsgServiceActivity.this,

R.string.remote_service_connected, Toast.LENGTH_SHORT)

.show();

}

};


@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.msg, menu);

return true;

}


}


// MessengerService.java

package com.example.onewaymessengerservice;


import android.app.Notification;

import android.app.NotificationManager;

import android.app.PendingIntent;

import android.app.Service;

import android.content.Intent;

import android.os.Handler;

import android.os.IBinder;

import android.os.Message;

import android.os.Messenger;

import android.widget.Toast;


public class MessengerService extends Service {


NotificationManager mNM;


static final int MSG_REGISTER_CLIENT = 1;

static final int MSG_UNREGSTER_CLIENT = 2;

static final int MSG_SET_VALUE = 3;


class ServiceHandler extends Handler {


@Override

public void handleMessage(Message msg) {

// TODO Auto-generated method stub

String mText;

switch (msg.what) {

case MSG_REGISTER_CLIENT:

mText = "MSG_REGISTER_CLIENT";

break;

case MSG_UNREGSTER_CLIENT:

mText = "MSG_UNREGSTER_CLIENT";

break;

default:

super.handleMessage(msg);

mText = "Default";

break;

}

Toast.makeText(MessengerService.this, mText, Toast.LENGTH_SHORT)

.show();

}

}


final Messenger mServiceMessenger = new Messenger(new ServiceHandler());


@Override

public void onCreate() {

// TODO Auto-generated method stub

super.onCreate();

mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

showNotification();

}


@Override

public void onDestroy() {

// TODO Auto-generated method stub

super.onDestroy();

mNM.cancel(R.string.remote_service_stopped);

Toast.makeText(this, R.string.remote_service_stopped, Toast.LENGTH_SHORT).show();

}


@Override

public IBinder onBind(Intent arg0) {

// TODO Auto-generated method stub

return mServiceMessenger.getBinder();

}


private void showNotification() {

CharSequence text = getText(R.string.remote_service_started);

Notification notification = new Notification(R.drawable.ic_launcher,

text, System.currentTimeMillis());

PendingIntent contentIntent = PendingIntent.getActivity(this, 0,

new Intent(this, MsgServiceActivity.class), 0);


notification.setLatestEventInfo(this,

getText(R.string.remote_service_label), text, contentIntent);

mNM.notify(R.string.remote_service_started, notification);

}

}


반응형

관련글 더보기

댓글 영역