일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 자바네트워크
- python
- jpa
- Database
- flet
- oracle
- GPT-4's answer
- 리눅스
- JVM
- 코틀린
- chatGPT's answer
- 유닉스
- 자바암호
- kotlin
- 역학
- 고전역학
- 소프트웨어공학
- 파이썬
- 웹 크롤링
- spring data jpa
- 인프라
- 데이터베이스
- Java
- write by GPT-4
- 시스템
- NIO
- 자바
- android
- write by chatGPT
- spring integration
- Today
- Total
기억을 지배하는 기록
Android Inter-App Communication 본문
이번 튜토리얼에서는 두 개의 Process 사이에서 하나가 다른 Process의 Service을 호출하는 방법에 대하여 설명하고 있습니다.
본 문서에서는 다음 내용을 다룹니다.
Invocation Handler을 작성하는 방법
Remote Service을 Bind 하는 방법
Invocation을 호출한 Process에게 Value Return 하는 방법
Step 1: Create the Service
Invocation될 Service을 만듭니다. Service에는반드시 IBinder 객체를 Return하는 onBind Method을 Override해야 합니다.
Service에서는 Messenger 컴포넌트를 사용합니다. 이 Messenger 컴포넌트는 내부 Process 간 Communication 이 가능하게 해줍니다.
public class RemoteService extends Service { private Messenger messenger; //receives remote invocations
@Override public IBinder onBind(Intent intent) { if(this.messenger == null) { synchronized(RemoteService.class) { if(this.messenger == null) { this.messenger = new Messenger(new IncomingHandler()); } } } //Return the proper IBinder instance return this.messenger.getBinder(); } |
Step 2: Implement the Handler
Handler는 Messenger을 등록할수 있는 컴포넌트 입니다. 이 컴포넌트는 Remote Invocation을 받을 수 있는 컴포너트 중 하나 입니다.
Handler는 들어온 요청의 Messenger에 따라 요청을 처리하고 응답을 보내게 되어있습니다.
private class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { System.out.println("*****************************************"); System.out.println("Remote Service successfully invoked!!!!!!"); System.out.println("*****************************************");
int what = msg.what;
Toast.makeText(RemoteService.this.getApplicationContext(), "Remote Service invoked-("+what+")", Toast.LENGTH_LONG).show();
//Setup the reply message Message message = Message.obtain(null, 2, 0, 0); try { //make the RPC invocation Messenger replyTo = msg.replyTo; replyTo.send(message); } catch(RemoteException rme) { //Show an Error Message Toast.makeText(RemoteService.this, "Invocation Failed!!", Toast.LENGTH_LONG).show(); } } } |
아래는 RemoterService Application의 Full Source입니다.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.openmobster.remote.service.android.app" android:versionCode="1" android:versionName="1.0"> <application android:label="@string/app_name" android:icon="@drawable/icon"> <activity android:name="org.openmobster.app.MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> </intent-filter> </activity>
<service android:name="org.openmobster.app.RemoteService" android:exported="true"> </service> </application> <uses-permission android:name="android.permission.INTERNET" /> </manifest> |
“org.openmobster.app.MainActivity”는 Hello world 수준으로 만들어 줍니다.
RemoteService
package org.openmobster.app; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.Handler; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.widget.Toast; public class RemoteService extends Service { private Messenger messenger; //receives remote invocations
@Override public IBinder onBind(Intent intent) { if(this.messenger == null) { synchronized(RemoteService.class) { if(this.messenger == null) { this.messenger = new Messenger(new IncomingHandler()); } } } //Return the proper IBinder instance return this.messenger.getBinder(); }
private class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { System.out.println("*****************************************"); System.out.println("Remote Service successfully invoked!!!!!!"); System.out.println("*****************************************");
int what = msg.what;
Toast.makeText(RemoteService.this.getApplicationContext(), "Remote Service invoked-("+what+")", Toast.LENGTH_LONG).show();
//Setup the reply message Message message = Message.obtain(null, 2, 0, 0); try { //make the RPC invocation Messenger replyTo = msg.replyTo; replyTo.send(message); } catch(RemoteException rme) { //Show an Error Message Toast.makeText(RemoteService.this, "Invocation Failed!!", Toast.LENGTH_LONG).show(); } } } } |
Step 3: Create a Client ServiceConnection Object
Client가 Service에 바인딩하는 경우 이 호출은 비동기 방식입니다. 시스템은 클라이언트에게 ServiceConnection 같은 Callback 메커니즘을 제공하고 있습니다.
클라이언트는 제공된 IBinder 인스턴스를 사용하여 Messenger 객체를 설정합니다.
private class RemoteServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName component, IBinder binder) { MainActivity.this.messenger = new Messenger(binder);
MainActivity.this.isBound = true; } @Override public void onServiceDisconnected(ComponentName component) { MainActivity.this.messenger = null;
MainActivity.this.isBound = false; } } |
Step 4: Bind to the Remote Service
Intent을 생성하고 Invoke될 Service을 가리키는 ClassName을 지정합니다.
@Override protected void onStart() { super.onStart();
//Bind to the remote service Intent intent = new Intent(); intent.setClassName("org.openmobster.remote.service.android.app", "org.openmobster.app.RemoteService");
this.bindService(intent, this.connection, Context.BIND_AUTO_CREATE); } |
Step 5: Make the Remote Invocation
Message.obtain을 이용하여 Message 객체를 생성합니다. message.replyTo에 Local Messenger를 담습니다. Messenger에 Message을 담아 Send합니다.
//Setup the message for invocation Message message = Message.obtain(null, 1, 0, 0); try { //Set the ReplyTo Messenger for processing the invocation response message.replyTo = MainActivity.this.replyTo;
//Make the invocation MainActivity.this.messenger.send(message); } catch(RemoteException rme) { //Show an Error Message Toast.makeText(MainActivity.this, "Invocation Failed!!", Toast.LENGTH_LONG).show(); } |
아래는 RemoteClient Full Source입니다.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.openmobster.app" android:versionCode="1" android:versionName="1.0"> <application android:label="@string/app_name" android:icon="@drawable/icon"> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET" /> </manifest> |
/layout/main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
<Button android:id="@+id/invoke" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Invoke Remote Service" /> </LinearLayout> |
MainActivity
package org.openmobster.app; import java.lang.reflect.Field; 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.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity { private Messenger messenger = null; //used to make an RPC invocation private boolean isBound = false; private ServiceConnection connection;//receives callbacks from bind and unbind invocations private Messenger replyTo = null; //invocation replies are processed by this Messenger
public MainActivity() {
}
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.connection = new RemoteServiceConnection(); this.replyTo = new Messenger(new IncomingHandler()); }
@Override protected void onStart() { super.onStart();
//Bind to the remote service Intent intent = new Intent(); intent.setClassName("org.openmobster.remote.service.android.app", "org.openmobster.app.RemoteService");
this.bindService(intent, this.connection, Context.BIND_AUTO_CREATE); }
@Override protected void onStop() { super.onStop();
//Unbind if it is bound to the service if(this.isBound) { this.unbindService(connection); this.isBound = false; } } @Override protected void onResume() { try { super.onResume();
//render the main screen String layoutClass = this.getPackageName()+".R$layout"; String main = "main"; Class clazz = Class.forName(layoutClass); Field field = clazz.getField(main); int screenId = field.getInt(clazz); this.setContentView(screenId);
//Invoke Remote button Button invokeButton = (Button)findViewById(R.id.invoke); invokeButton.setOnClickListener(new onClickListener(){ @Override public void onClick(View button) { if(MainActivity.this.isBound) { //Setup the message for invocation Message message = Message.obtain(null, 1, 0, 0); try { //Set the ReplyTo Messenger for processing the invocation response message.replyTo = MainActivity.this.replyTo;
//Make the invocation MainActivity.this.messenger.send(message); } catch(RemoteException rme) { //Show an Error Message Toast.makeText(MainActivity.this, "Invocation Failed!!", Toast.LENGTH_LONG).show(); } } else { Toast.makeText(MainActivity.this, "Service is Not Bound!!", Toast.LENGTH_LONG).show(); } } } ); } catch(Exception e) { e.printStackTrace(System.out); } }
private class RemoteServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName component, IBinder binder) { MainActivity.this.messenger = new Messenger(binder);
MainActivity.this.isBound = true; } @Override public void onServiceDisconnected(ComponentName component) { MainActivity.this.messenger = null;
MainActivity.this.isBound = false; } }
private class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { System.out.println("*****************************************"); System.out.println("Return successfully received!!!!!!"); System.out.println("*****************************************");
int what = msg.what;
Toast.makeText(MainActivity.this.getApplicationContext(), "Remote Service replied-("+what+")", Toast.LENGTH_LONG).show(); } } } |
'오래된글 > Articles' 카테고리의 다른 글
Android에서 Httpclient와 WebView간 HttpSession 공유 (0) | 2018.04.19 |
---|---|
당신의 개발팀에 동기부여하는 5가지 방법 (0) | 2018.04.19 |
Getting all EJB home interface object from a HashMap (0) | 2018.04.19 |
안정성 패턴 (0) | 2018.04.19 |
Android Thread 내에서 UI 핸들링 (0) | 2018.04.19 |