티스토리 뷰

Android/Service

Service (4) - bindService

parkho79 2018. 10. 16. 21:57
728x90



bindService 구현

하단 예제 코드는 단일 process 는 물론 다른 process(package) 와 양방향 통신도 가능하다.

  

1. Service 구현

public class PhService extends Service
{
public interface MessengerMsg {
int CONNECT = 1;
int DISCONNECT = 2;
int GET_TIMESTAMP = 3;
int MUSIC_PLAY = 4;
int MUSIC_STOP = 5;
}
// Activity 와 통신할 messenger
private final Messenger mServiceMessenger = new Messenger(new ServiceHandler());
private Messenger mActivityMessenger;
private MediaPlayer mMediaPlayer;
private long mStartTime;
private class ServiceHandler extends Handler {
@Override
public void handleMessage(Message a_msg) {
Message replyMsg;
switch (a_msg.what) {
case MessengerMsg.CONNECT:
mActivityMessenger = a_msg.replyTo;
replyMsg = Message.obtain(null, MessengerMsg.CONNECT);
try {
mActivityMessenger.send(replyMsg);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case MessengerMsg.DISCONNECT:
mActivityMessenger = null;
break;
case MessengerMsg.GET_TIMESTAMP:
Bundle bundle = new Bundle();
bundle.putLong("parkho", getTime());
replyMsg = Message.obtain(null, MessengerMsg.GET_TIMESTAMP);
replyMsg.setData(bundle);
try {
mActivityMessenger.send(replyMsg);
} catch (RemoteException e) {
e.printStackTrace();
}
// 1초에 한 번씩 time 확인
sendEmptyMessageDelayed(MessengerMsg.GET_TIMESTAMP, 1000);
break;
case MessengerMsg.MUSIC_PLAY:
onStartMusic();
break;
case MessengerMsg.MUSIC_STOP:
onStopMusic();
removeCallbacksAndMessages(null);
break;
default:
super.handleMessage(a_msg);
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
mStartTime = 0;
if (mMediaPlayer != null) {
mMediaPlayer.stop();
}
}
@Override
public IBinder onBind(Intent intent) {
return mServiceMessenger.getBinder();
}
@Override
public boolean onUnbind(Intent intent) {
return true;
}
private void onStartMusic() {
mStartTime = SystemClock.elapsedRealtime();
mMediaPlayer = MediaPlayer.create(this, R.raw.sample);
mMediaPlayer.setLooping(false);
mMediaPlayer.start();
}
private void onStopMusic() {
mMediaPlayer.stop();
mMediaPlayer.seekTo(0);
}
private long getTime() {
return SystemClock.elapsedRealtime() - mStartTime;
}
}
view raw PhService.java hosted with ❤ by GitHub

 

2. Manifest 등록

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.parkho.servicesample">
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity android:name=".PhMainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".PhService"
android:process=":newprocess" />
</application>
</manifest>

 

3. Layout 생성

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="24.00dp"
android:text="@string/start_music" />
<Button
android:id="@+id/btn_stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="24.00dp"
android:text="@string/stop_music" />
<TextView
android:id="@+id/tv_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="24.00dp"
android:gravity="center"
android:text="@string/default_time_value" />
</LinearLayout>
view raw layout.xml hosted with ❤ by GitHub

 

4. MainActivity

public class PhMainActivity extends AppCompatActivity
{
// Service 와 통신할 messenger
final Messenger mActivityMessenger = new Messenger(new ActivityHandler());
private Messenger mBoundServiceMessenger;
private TextView mTvTime;
private class ActivityHandler extends Handler {
@Override
public void handleMessage(Message a_msg) {
switch (a_msg.what) {
case MessengerMsg.CONNECT:
Snackbar.make(findViewById(android.R.id.content), R.string.service_connected, Snackbar.LENGTH_LONG).show();
break;
case MessengerMsg.GET_TIMESTAMP:
String strTime = convertTimeFormat(a_msg.getData().getLong("parkho"));
mTvTime.setText(strTime);
break;
default:
super.handleMessage(a_msg);
}
}
}
// https://www.truiton.com/2015/01/android-bind-service-using-messenger/
private ServiceConnection mServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName a_name, IBinder a_service) {
mBoundServiceMessenger = new Messenger(a_service);
Message msg = Message.obtain(null, MessengerMsg.CONNECT);
msg.replyTo = mActivityMessenger;
try {
mBoundServiceMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void onServiceDisconnected(ComponentName a_name) {
mBoundServiceMessenger = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnStart = findViewById(R.id.btn_start);
btnStart.setOnClickListener(new OnClickListener() {
public void onClick(View a_view) {
Message msg = Message.obtain(null, MessengerMsg.MUSIC_PLAY);
try {
mBoundServiceMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
msg = Message.obtain(null, MessengerMsg.GET_TIMESTAMP);
try {
mBoundServiceMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
Button btnStop = findViewById(R.id.btn_stop);
btnStop.setOnClickListener(new OnClickListener() {
public void onClick(View a_view) {
Message msg = Message.obtain(null, MessengerMsg.MUSIC_STOP);
try {
mBoundServiceMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
mTvTime = findViewById(R.id.tv_time);
}
@Override
protected void onStart() {
super.onStart();
// 서비스 시작
Intent intent = new Intent(this, PhService.class);
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
Message msg = Message.obtain(null, MessengerMsg.DISCONNECT);
try {
mBoundServiceMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
if (mBoundServiceMessenger != null) {
unbindService(mServiceConnection);
mBoundServiceMessenger = null;
}
}
/**
* Time format
*/
private String convertTimeFormat(final long a_time) {
final long hr = TimeUnit.MILLISECONDS.toHours(a_time);
final long min = TimeUnit.MILLISECONDS.toMinutes(a_time - TimeUnit.HOURS.toMillis(hr));
final long sec = TimeUnit.MILLISECONDS.toSeconds(a_time - TimeUnit.HOURS.toMillis(hr) - TimeUnit.MINUTES.toMillis(min));
final String strSec = String.format("%02d:%02d:%02d", hr, min, sec);
return strSec;
}
}



위 예제는 하단 link 에서 확인할 수 있다.

https://github.com/parkho79/ServiceSample3



728x90

'Android > Service' 카테고리의 다른 글

[Android O] Not allowed to start service Intent  (2) 2018.10.19
Service (3) - bound service  (0) 2018.10.10
Service (2) - started service  (3) 2018.08.28
Service (1)  (1) 2018.08.21
댓글