----------------------------------------------------------------------------------------------
출처: http://pgm-progger.blogspot.com/2011/05/android_5959.html
----------------------------------------------------------------------------------------------
이 샘플소스는 안드로이드 설치폴더에 android-sdk-windowssamplesandroid-8ApiDemos 위치에
원본 소스 코드가 있습니다.
현재 프로세스와는 다른 프로세스에서 실행되는 서비스를 호출하기 위해서는
IPC(Inter Process Call)방식을 이용하여 다른 프로세스 상에서 실행되는 서비스의 메소드를 실행하고,
콜백 결과값을 받을 수 있습니다.
aidl 파일에 인터페이스를 정의하여, 다른 프로세스의 서비스 메소드와 콜백 메소드 등을 정의합니다.
이 인터페이스를 통하여 프로세스 간의 메소드 호출정보를 주고받아, 서로 메소드 호출과 콜백이
가능해 지게 됩니다. 메소드 호출은 원격 서비스를 호출하는 쪽에서 원격 서비스의 메소드를 호출하고,
콜백은 원격 서비스에서 자신을 호출한 쪽으로 값을 반환해 주는 것입니다.
그리고 서비스를 강제종료 하게되면 자동으로 시스템에서 다시 시작합니다.
참고로, UI갱신하는 코드는 반드시 메인쓰레드로 실행되는 상황에서만 수행할 수 있기 때문에,
서비스에서 UI를 갱신하는 등의 작업을 할 수 없고, 메인쓰레드의 메소드를 호출하는 식으로 처리를
하셔야 합니다.
먼저 두개의 액티비티와 서비스를 정의하고 있는 RemoteService.java 파일을 추가합니다.
RemoteService.Controller 액티비티는 단순히 서비스를 시작하고 종료하는 처리만 하고 있습니다.
RemoteService.Binding 액티비티에서는 원격 서비스를 호출하고, 콜백값을 받고, 원격 서비스를
강제 종료하는 등의 처리를 하고 있습니다.
/* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// in a sub-package.
{ final RemoteCallbackList<IRemoteServiceCallback> mCallbacks
int mValue = 0;
@Override {
// Display a notification about us starting.
// While this service is running, it will continually increment a number. // Send the first message that is used to perform the increment. {
// Tell the user we stopped.
// Unregister all callbacks.
// Remove the next pending message to increment the counter, stopping the increment loop.
@Override { // you can just return it here without checking the Intent. // 반환합니다. Stub 객체는 서비스를 호출하는 쪽으로, 호출되는 서비스의 사용할 인터페이스 // 호출 정보를 넘겨주어, 호출하는 쪽에서 다른 프로세스의 서비스 메소드들을 호출할 수 있게 // 됩니다. // ISecondary.aidl 두 개 파일에 인터페이스를 선언하고 있습니다. // 있습니다. {
if (ISecondary.class.getName().equals(intent.getAction())) {
return null; /** * 메소드들을 정의하여, 그 처리를 하고 있습니다. { {
public void unregisterCallback(IRemoteServiceCallback cb) {
/** { {
public void basicTypes(int anInt, long aLong, boolean aBoolean, {
private static final int REPORT_MSG = 1;
/** * This is used to schedule increments of our value. * 있습니다. { public void handleMessage(Message msg) { { // It is time to bump the value!
// Broadcast to all clients the new value. { // The RemoteCallbackList will take care of removing mCallbacks.finishBroadcast();
// Repeat every 1 second. break;
default:
{ // Set the icon, scrolling text and timestamp // The PendingIntent to launch our activity if the user selects this notification // Set the info for the views that show in the notification panel.
// ---------------------------------------------------------------------- /** { { // Watch for button clicks.
{ { private onClickListener mStopListener = new onClickListener() { {
// ---------------------------------------------------------------------- /** { * 인터페이스 입니다. /** Another interface we use on the service. * 종료되지 않고, 강제 종료 된 서비스들을 되 살리게 됩니다.
Button mKillButton; private boolean mIsBound; { // Watch for button clicks. mKillButton = (Button)findViewById(R.id.kill); mCallbackText = (TextView)findViewById(R.id.callback); /** private ServiceConnection mConnection = new ServiceConnection() { { // We want to monitor the service for as long as we are connected to it. {
// As part of the sample, tell the user what happened.
{ // As part of the sample, tell the user what happened.
{ { public void onServiceDisconnected(ComponentName className) { private onClickListener mBindListener = new onClickListener() { { // This allows other applications to be installed that replace the remote service // by implementing the same interface. // 서비스 객체를 받아오기 위해서, 두개의 서비스를 연결하는 bindService 메소드를 // 호출하고 있습니다.
{ { { { // 해제합니다.
// Detach our existing connection. /* { { { // Note that, though this API allows us to request to kill any process // based on its PID, // the kernel will still impose standard restrictions on which PIDs // you are actually able to kill. // Typically this means only the process running your application // and any additional processes created by that app as shown here; // packages sharing a common UID will also be able to kill each // other's processes. } catch (RemoteException ex) {
// ---------------------------------------------------------------------- /** * 계속해서 갱신을 시키게 됩니다. { {
private static final int BUMP_MSG = 1;
/* { public void handleMessage(Message msg) { { default: };
|
원하시는 액티비티 클래스 파일을 원하시는 패키지 경로에 추가해 줍니다.
여기서는 Test011.java 로 추가했습니다. 위의 두개의 액티비티를 선택할 수 있도록 버튼 두개를 두어서,
각 버튼 클릭시 해당 액티비티를 실행하고 있습니다.
package korsoft.net.Test011;
import android.app.Activity;
public class Test011 extends Activity { /** Called when the activity is first created. */ {
Button btn1 = (Button)findViewById(R.id.btnRemoteServiceStart);
btn1.setOnClickListener(new onClickListener() { {
btn2.setOnClickListener(new onClickListener() { { }
|
위의 세개의 액티비티 레이아웃 파일을 추가해 줍니다.
/layout/main.xml , remote_service_binding.xml, remote_service_controller.xml 세 개 추가해줍니다.
/layout/main.xml
<?xml version="1.0" encoding="utf-8"?> <Button android:id="@+id/btnRemoteServiceStart" <Button android:id="@+id/btnRemoteServiceBind" </LinearLayout>
|
<?xml version="1.0" encoding="utf-8"?> http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software
|
/layout/remote_service_controller.xml
<?xml version="1.0" encoding="utf-8"?> http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
<Button android:id="@+id/stop" </LinearLayout>
|
이제 프로세스간에 메소드 호출 정보를 정의하는 aidl 파일을 세개 추가해 줍니다.
원하시는 경로에 추가해 주시면 됩니다. 그리고 코드와 설정파일에서 해당 패키지 경로만
맞춰주시면 됩니다.
IRemoteService.aidl
원격 서비스에서 정수를 증가시켜서 반환해주는 메소드를 정의하는 인터페이스 입니다.
/* package korsoft.net.Test011; import korsoft.net.Test011.IRemoteServiceCallback; /** /**
|
IRemoteServiceCallback.aidl
위에서 원격 서비스에서 증가한 정수값을 액티비티로 받아오는 콜백 메소드를 정의하는 인터페이스 입니다.
/*
|
ISecondary.aidl
액티비티에서 원격 서비스를 강제 종료시키기 위해서,
원격 서비스의 프로세스 아이다값을 받아오기 위한 메소드를 정의하는 인터페이스 입니다.
/* /** { /**
|
/res/drawable-hdpi/stat-sample.png 파일을 안드로이드 sdk 폴더에서 현재 프로젝트로 복사해 옵니다.
문자열 리소스를 /res/values/strings.xml 파일에 설정해 줍니다.
<?xml version="1.0" encoding="utf-8"?>
<string name="remote_service_started">Remote service has started</string> <string name="activity_remote_service_controller">App/Service/Remote Service Controller</string> <string name="bind_service">Bind Service</string> <string name="start_service">Start Service</string> <string name="btnRemoteServiceStart">remote service start</string>
</resources>
|
마지막으로 AndroidManifest.xml 파일을 다음과 같이 설정해 줍니다.
<?xml version="1.0" encoding="utf-8"?>
<application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".Test011" <!-- <service android:name=".RemoteService" android:process=":remote">
<activity android:name=".RemoteService$Controller" <activity android:name=".RemoteService$Binding" </application> </manifest>
|
'IT_Programming > Android_Java' 카테고리의 다른 글
[펌] 안드로이드 전역 변수 사용하기! (android global variable) (0) | 2012.03.06 |
---|---|
[펌] How to quit an application in Android (0) | 2012.03.06 |
[펌][Android/안드로이드] Paint에 Filter 적용하기 + draw에 효과주기. (0) | 2012.02.20 |
[Android] 성능을 위한 설계 - 이동훈님 (0) | 2012.02.16 |
[펌] manifest activity 태그의 multiprocess 속성. (0) | 2012.02.03 |