Android IPC调用期间发生死锁的可能性

Android IPC调用期间发生死锁的可能性,android,Android,我有一个main活动,它将向远程自动完成服务服务发出IPC调用 在执行AutoCompleteService的IPC功能期间,该服务将向MainActivity发出另一个IPC回调 MainActivity.java AutoCompleteService.java 但我真的不明白如果MainActivity线程(Id为1)没有从函数调用返回(autocompletepi.handle),它如何“跳转”到执行另一个函数(update(StockInfo StockInfo))? 我希望,ma

我有一个
main活动
,它将向远程
自动完成服务
服务发出IPC调用

在执行
AutoCompleteService
的IPC功能期间,该服务将向
MainActivity
发出另一个IPC回调

MainActivity.java AutoCompleteService.java

但我真的不明白如果MainActivity线程(Id为1)没有从函数调用返回(
autocompletepi.handle
),它如何“跳转”到执行另一个函数(
update(StockInfo StockInfo)
)?

我希望,main活动收到由不同线程打印的ipc调用。不是Id为1的线程。否则,就会出现死锁


如果您有兴趣尝试,请在此处下载完整的源代码:

一个有趣的问题。我的第一个想法是,传入的IPC调用是在不同的线程上处理的(因为传入的IPC调用通常会发生这种情况),结果在这个特定场景中是错误的

当传入调用到达时查看执行堆栈(最新的堆栈帧位于顶部):

main活动$1.0更新
主要活动1.5美元交易

MainActivity$1.execTransact我猜LogCat无法跟上这里的流程更改。在写入AutoCompleteService的日志之前,将IPC回调回MainActivity是毫无意义的。对不起。日志来自2个不同的标记。但是如果你查看我的日志,你会发现同一个线程正在MainActivity中运行。@YanChengCHEOK:那么你是在错误地解释你的日志。例如,您正在记录进程ID,并认为它们是线程ID。@Commonware:为什么这么说?我想
Thread.currentThread().getId
能证明运行的是同一个线程吗?请注意,我同时记录了进程id(前面)和线程id(后面)@YanChengCHEOK这是一个很好的观点,我需要更仔细地研究这个问题。@YanChengCHEOK:哎呀,对不起,我刚才关注的是左边的数字列,这是您的进程id。也就是说,AIDL IPC调用不会出现在主应用程序线程中,在主应用程序线程中调用了
setOnClickListener()
,因此我仍然认为Henry是正确的,并且日志记录中存在一些问题。
// 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();
        }

    }

});
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);
        }
    }
};
// 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$1.update
MainActivity$1.onTransact
MainActivity$1.execTransact         <- this gets called by the incoming IPC call
BinderProxy.transact                <- this is where the outgoing IPC call is made
AutoCompleteApi$Stub$Proxy.handle
MainActivity$3.onClick
...