本机活页夹回调挂起

问题描述 投票:0回答:1

我正在使用 NXP EVK 开发 AOSP 代码库。我有一个接收回调的活页夹接口。有两种客户端可以连接到服务。一个客户端产生数据,另一个客户端是数据的消费者。消费者通过 IMyServiceListener 接收数据,生产者通过 IMyClientListener 获取新客户端连接的通知。发生的情况是在我的服务连接函数的实现中,我尝试调用生产者的回调(onNewClient),但它挂起并且永远不会返回。生产者和消费者都运行在不同的进程中。 Consumer 与 Producer 具有类似的实现,它只是订阅 IMyClientListener 回调而不是 IMyServiceListener。

场景:

  1. 服务开始
  2. 制作人开始
  3. 生产者调用connect
  4. 生产者订阅IMyClientListener
  5. 生产者等待回调
  6. 消费者开始
  7. 消费者呼叫接通
  8. 在服务连接函数中,服务调用IMyClientListener的回调并永远挂起。

我尝试使用线程执行步骤 8,但该线程仍然永远挂起。

// AIDL interfaces

interface IMyServiceListener {
    boolean onData(in byte[] data);
}

interface IMyClientListener {
    boolean onNewClient();
}

interface IMyService  {
    boolean connect();
    boolean subscribeToClientListener(IMyClientListener listener);
    boolean subscribeToListener(IMyServiceListener listener);
}

//////////Service code using platform c++ binder

class CMyService : public BnMyService
{
    sp<IMyClientListener> mClientListener = nullptr;
    sp<IMyListener> mListener = nullptr;
public:

    static void instantiate() {
        defaultServiceManager()->addService(
                String16("com.my.service"), new CMyService());
    }
   
    binder::Status connect(bool* _aidl_return)
    {

       //blah blah other code to connect
       
       if (mClientListener != nullptr)
       {
           mClientListener->onNewClient();
           // Above code hangs
       }
    }
    
    binder::Status subscribeToClientListener(const sp<IMyClientListener>& listener, bool* _aidl_return)
    {
        mClientListener = listener;
        *_aidl_return = true;
    }
    
    binder::Status subscribeToListener(const sp<IMyListener>& listener, bool* _aidl_return)
    {
        mListener = listener;
        *_aidl_return = true;
    }   
    
}



/////////Producer code using NDK binder

struct CClientListenerData
{
    void* mUserData = nullptr;
};


class CMyClientListener : public aidl::com::my::BpMyClientListener
{
private:
    CClientListenerData* mListener = nullptr;
public:
    explicit CMyClientListener(const ::ndk::SpAIBinder& binder, CClientListenerData* listener) : BpMyClientListener(binder) {mListener = listener;}
    virtual ~CMyClientListener() = default;
    virtual ::ndk::ScopedAStatus onNewClient(bool* _aidl_return) override;
};

::ndk::ScopedAStatus CMyClientListener::onNewClient(bool* _aidl_return)
{
    // Got the callback

    return ndk::ScopedAStatus::ok();
}


class CMyProducer
{
private:
    std::shared_ptr<aidl::com::my::IMyService> mMyServiceInterface;
    std::shared_ptr<::aidl::com::my::IMyClientListener> mMyClientListener;
    ::ndk::SpAIBinder mNewBinder = ::ndk::SpAIBinder(CreateBinder::NewBinder());
    CClientListenerData mListener;
    CMyClientListener mCMyClientListener = CMyClientListener(mNewBinder, &mListener);
public:


    CMyProducer()
    {
        mMyClientListener = std::shared_ptr<::aidl::com::my::IMyClientListener>(&mCMyClientListener);
    }

    bool Connect() {
        ::ndk::SpAIBinder binder(AServiceManager_getService("com.my.service"));
        mMyServiceInterface = aidl::com::my::IMyService::fromBinder(binder);
        bool ret = false;
        mMyServiceInterface->connect(&ret);
        return ret;
    }
   
    bool SubscribeToClient(bool* _aidl_return))
    {
        mMyServiceInterface->subscribeToClientListener(mMyClientListener, &ret);
    }

};
android android-ndk android-source android-binder
1个回答
0
投票

我以前也遇到过这个问题。我认为可以通过在 CMyProducer 开头添加

ABinderProcess_startThreadPool()
来解决。

© www.soinside.com 2019 - 2024. All rights reserved.