【发布时间】:2013-01-12 05:54:20
【问题描述】:
我有一个MainActivity,它将向远程AutoCompleteService 服务发出IPC 调用。
在AutoCompleteService的IPC函数执行期间,服务将再次向MainActivity发出IPC调用。
MainActivity.java
// Receive IPC call from AutoCompleteService.
private StockInfoObserver.Stub stockInfoObserver = new StockInfoObserver.Stub() {
@Override
public void update(StockInfo stockInfo) throws RemoteException {
// TODO Auto-generated method stub
Log.i(TAG, android.os.Process.myPid() + " : MainActivity receive ipc call : " + Thread.currentThread().getId());
}
};
...
...
...
// Issue IPC call to AutoCompleteService.
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// Test on API.
try {
Log.i(TAG, android.os.Process.myPid() + " : MainActivity start issue IPC call to remote service : " + Thread.currentThread().getId());
// autoCompleteApi.handle will issue IPC call to remote service.
autoCompleteApi.handle("abc");
Log.i(TAG, android.os.Process.myPid() + " : MainActivity end issue IPC call to remote service : " + Thread.currentThread().getId());
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
AutoCompleteService.java
private AutoCompleteApi.Stub autoCompleteApi = new AutoCompleteApi.Stub() {
private List<StockInfoObserver> stockInfoObservers = new ArrayList<StockInfoObserver>();
@Override
public void handle(String string) {
Log.i(TAG, android.os.Process.myPid() + " : AutoCompleteService start receive ipc call : " + Thread.currentThread().getId());
try {
for (StockInfoObserver stockInfoObserver : stockInfoObservers) {
Log.i(TAG, android.os.Process.myPid() + " : AutoCompleteService start IPC call to MainActivity : " + Thread.currentThread().getId());
// stockInfoObserver.update will issue IPC call back to MainActivity
stockInfoObserver.update(null);
Log.i(TAG, android.os.Process.myPid() + " : AutoCompleteService end IPC call to MainActivity : " + Thread.currentThread().getId());
}
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(TAG, android.os.Process.myPid() + " : AutoCompleteService end receive ipc call : " + Thread.currentThread().getId());
}
@Override
public void attachStockInfoObserver(StockInfoObserver stockInfoObserver)
throws RemoteException {
if (stockInfoObservers.contains(stockInfoObserver) == false) {
stockInfoObservers.add(stockInfoObserver);
}
}
};
我最初的预期是,会发生死锁。这是由于我的观察。发出 IPC 调用时,发出者只会在 IPC 接收者完成其 IPC 函数执行后从 IPC 调用返回。
-
MainActivity通过autoCompleteApi.handle向AutoCompleteService发出IPC 调用。 -
MainActivity现在将等待AutoCompleteService完成执行。 -
AutoCompleteService通过stockInfoObserver.update向MainActivity发出IPC 调用。 -
AutoCompleteService现在将等待MainActivity完成执行。 - 但是,
MainActivity的线程还在等待,没有线程可以执行update函数。 - 两个进程一直相互等待。
但是,上述情况不会发生。这是我得到的日志。一切都完美无缺。
// Log in MainActivity TAG
3930 : MainActivity start issue IPC call to remote service : 1
3930 : MainActivity receive ipc call : 1
3930 : MainActivity end issue IPC call to remote service : 1
// Log in AutoCompleteService TAG
3961 : AutoCompleteService start receive ipc call : 494
3961 : AutoCompleteService start IPC call to MainActivity : 494
3961 : AutoCompleteService end IPC call to MainActivity : 494
3961 : AutoCompleteService end receive ipc call : 494
但我真的不明白。 如果 MainActivity 线程(Id 为 1)没有从函数调用 (autoCompleteApi.handle) 返回,它如何“跳转”到执行另一个函数 (update(StockInfo stockInfo))?
我希望 MainActivity 接收 ipc 调用 被不同的线程打印。不是 ID 为 1 的线程。如果不是,应该会发生死锁。
如果您有兴趣尝试,请在此处下载完整的源代码:https://www.dropbox.com/s/8hd7v5acjd213l1/jstock-android2.zip
【问题讨论】:
-
我的猜测是 LogCat 无法跟上这里的流程变化。在写入来自 AutoCompleteService 的日志之前,您收到返回给 MainActivity 的 IPC 回调真的没有任何意义。
-
对不起。日志来自 2 个不同的 TAG。
标签: android