2011-01-11 3 views
3

AIDL 인터페이스가있는 전체 벽을 붙였습니다. 나는 제 3 자 응용 프로그램을 통해 제어되어야하는 응용 프로그램을 가지고 있습니다. (필자는 이것에 대한 충분한 제어권을 가졌으므로 필자는 자신의 활동에 필요한 것을 구현하도록 요청할 수 있습니다)두 응용 프로그램 간의 AIDL 인터페이스

원래 응용 프로그램은 또한 인터페이스 그리고 모든 것을 배경 서비스로 변경하고 테스트를 위해 백그라운드로 서비스 응용 프로그램을 시작할 수있는 더미 응용 프로그램을 만들었습니다.

이제 서비스 (주로 start, stop, sendData)의 메소드 호출을 요청하고 싶습니다. 두 앱의 .aidl 파일을 만들었습니다. 다른 AIDL이 패키지는 "foo.otherapp"입니다 제외하고는 동일하면서 AIDL 파일은 하나의 방법 (이 여기에 몇 가지 다른 질문의 예의입니다.)

package foo.testapp; 
interface IScript 
{ 
    String executeScript(String script); 
} 

을 구현합니다. 필자가 온라인에서 찾은 구현은 두 보조 파일 모두에 대해 동일한 패키지를 가지고 있지만이 때문에 오류가 발생합니다 (네임 스페이스와 패키지가 싫어지기 때문에 이것은 내 문제에 불과하다고 생각합니다. 그것들을 바꿀 수있다, 나는 그것을 할 수있다)

계획은이 방법을 사용하여 서비스에 문자열을 보내고 올바른 방법을 호출하기 위해 사전 정의 된 문자열을 전환했다 (향상시킬 경우 세 가지 다른 방법을 구현할 수도 있음). 사용법).

... 어쨌든 나는 서비스의 의도를 시작할 수 "없습니다 오류는 AIDL가 연결을 얻을 수

{행위 = foo.testapp.IScript은} : 발견되지

나는이 추측은

이 내 시험 활동 응용 프로그램에서 구현 한 것입니다) 그래서. PackageNames은 내 오해 즉, 함께 할 수있는 뭔가가 또는 것

한 OnCreate에서 다음
private final IScript.Stub mBinder = new IScript.Stub() 
{ 
    @Override 
    public String executeScript(String script) throws RemoteException 
    { 
     // TODO Auto-generated method stub 
    } 
}; 
IScript mService = null; 
private ServiceConnection mConnection = new ServiceConnection() 
{ 
    public void onServiceConnected(ComponentName className, IBinder service) 
    { 
     mService = IScript.Stub.asInterface(service); 
    } 
    public void onServiceDisconnected(ComponentName className) 
    { 
     mService = null; 
    } 
}; 

16,() 메소드 나는이 작업을 수행 할 수 있습니다 : 서비스 클래스에서

bindService(new Intent(IScript.class.getName()), 
      mConnection, Context.BIND_AUTO_CREATE); 

을 나는이있다;

@Override 
public IBinder onBind(Intent intent) 
{ 
    // Select the interface to return. If your service only implements 
    // a single interface, you can just return it here without checking 
    // the Intent. 
    if (IScript.class.getName().equals(intent.getAction())) 
    { 
     return mBinder; 
    } 
    return null; 
} 

/** 
* The IRemoteInterface is defined through IDL 
*/ 
private final IScript.Stub mBinder = new IScript.Stub() 
{ 
    @Override 
    public String executeScript(String script) throws RemoteException 
    { 
     if (script == "test") 
     { 
      return "foo"; 
     } 
     return "fail"; 
    } 
}; 

마지막으로 매니페스트 파일입니다.

실제로 실제로, 나는 manifest 파일에 뭔가를 추가해야하는지 잘 모르겠다. 한 예에서 나는 이것을 보았다.

<intent-filter> 
     <action android:name="foo.otherapp.IScript" /> 
    </intent-filter> 

<intent-filter> 
     <action android:name="foo.testapp.IScript" /> 
    </intent-filter> 

나는 오류가 어느 곳이 될 수 있다고 생각합니다. 나는 이것을 껌과 붕대로 씹어 내려고 노력해 왔습니다. 이 기본 개념을 오해 한 것 같습니다.

어쨌든, 어떤 도움을 환영합니다.

미리 감사드립니다.

답변

3

내가 정확한 해결책을 발견하기 때문에 내 자신의 질문에 대답하기로 결정했다.

My Life With Android

모든 클라이언트 폴더에서

소스가 클라이언트에 간다 (당신이 당신의 자신의 프로젝트에이를 구현하고 가정) 소스를 붙여 올바르게 패키지 이름과 함수 이름을 변경 사본 단지 일 활동 및 serviceimpl은 서비스로 이동합니다. 나는 '서비스 활동'을 필요로하지 않았으므로 그것을 버렸습니다 (실제로는 어쨌든 호출되지 않습니다).

여러 링크를 게시하는 데 충분한 평판이 없으므로 페이지 상단에서 소스를 얻을 수 있습니다.

"업데이트 : Android SDK 1.5 용 업데이트 된 예제 프로그램을 확인하십시오."

1

나는 이것으로 또한 고투했다. 당신은 RemoteInterface가 맞다고 추측 할 수 있습니다.aidl은 서비스와 테스트 앱 모두에서 동일한 패키지 이름을 가져야합니다. 그래서 어디에 넣을까요?

이클립스에서 개발하는 경우에는 공통 소스 폴더 (두 프로젝트 공통)를 두는 것이 트릭입니다.이 폴더를 두 프로젝트와 빌드 속성/소스 외부에서 만들려면 '링크 소스'를 클릭하고 공통 출처의 위치. (원하는 이름으로 부를 수 있습니다.) 두 프로젝트 모두에서이 작업을 수행하고 거기에 interface.aidl을 삽입하십시오. 두 프로젝트의 패키지 탐색기에 나타나며 한 프로젝트에서 변경하면 다른 프로젝트도 업데이트됩니다.

일반적인 소스 폴더에서 interface.aidl을 서비스와 동일한 이름의 패키지에 넣었습니다.

개미를 사용하여 빌드하는 경우 기본 ant_rules.xml이 두 개의 보조 폴더를 지원하지 않으므로 다소 까다로워집니다. 따라서 build.xml을 아주 조금 수정해야합니다. 새 대상 추가 및 모든 종속성.

나는 여기에 '다운로드 소스'에서 샘플을 적용하여 17 장 형성가는 내 프로젝트를 가지고 :

link text

+0

제안 해 주셔서 감사합니다. 나는 어제 이것을 빨리 시험해 보았고 아직 그것을 이해할 수 없었다. 그런 다음 패키지 이름을 리팩토링하여 고유 한 .service 및 .client와 동일하게하려고했습니다. 그래서 foo.projectname.client & foo.projectname.service. 이것은 그때 나에게 많은 회색 머리카락을 일으키는 심한 버그로 이끌었습니다. 응용 프로그램이 에뮬레이터에 설치하지 못했습니다 ... 오류 발생 시간의 70-80 % 클래스가 발견되지 않고 때로는 부드럽게 설치됩니다. 시작됩니다. 따라서 게시 한 소스를 기반으로 바인딩을 다시 작성하겠습니다. 결과와 함께, 희망을 갖고 오늘. –

+0

어제는 약간 바빴고 전혀 할 수 없었습니다. 어쨌든 ... 저는 이제 작업 공간에 AIDL이라는 폴더를 만들었습니다. foo.service 폴더를 만들고 거기에 interface.aidl 파일을 놓았고 aidl 파일의 패키지 이름은 foo.service입니다. 문제는 지금 가져올 수 없다는 것입니다. 나는 또한 .aidl 파일을 AIDL 폴더 루트에 넣으려고했다. 나는 일식을 사용하고있다. –

+0

나는 이걸 가지고 놀았고, 결국 당신이 링크 한 소스로부터 튜토리얼 프로젝트를 구축하기로 결심했다. 튜토리얼은 최소한 (나는 그것에 연결된 책에서 해결 된 튜토리얼의 종류인지 알기 위해 노력하지 않았다. 오류 Intent를 발견하지 못했습니다. 근본적으로 현재 프로젝트와 동일한 상태에 있습니다. 나는 주제 조금 더 봤고 금광을 쳤다. 별도의 애플리케이션을 통한 통신을위한 매우 단순하고 작은 튜토리얼. http://mylifewithandroid.blogspot.com/2008/01/invoking-services.html –