Android JNI - Call function on Android UI thread from C++

后端 未结 4 1721
醉梦人生
醉梦人生 2020-12-08 17:51

Our game engine Cocos2d-x runs natively on android on its own non-Java-UI-thread. We need to call certain Java functions from C++ via

4条回答
  •  天命终不由人
    2020-12-08 17:52

    Another option is to use the Arcana.cpp C++ library, which includes an Android Looper based "scheduler." In its simplest form, you can use it like this:

    #include 
    
    void SomeFunctionCalledFromUIThread()
    {
      // Note: The '64' below is the max size of the callables passed to the scheduler.
      // This is done to reduce allocations and make schedulers more efficient.
      auto looper_scheduler = arcana::looper_scheduler<64>::get_for_current_thread();
    
      // Get on a background thread to test getting back on the UI thread.
      std::thread worker([looper_scheduler = std::move(looper_scheduler)]() {
        looper_scheduler([]() {
          // Do something on the UI (looper) thread
        });
      });
    }
    

    Schedulers are a general construct in Arcana.cpp, and are also used in the low overhead cross platform async task system, so if you opt to use that then you can do typical async task programming with this scheduler:

    #include 
    #include 
    #include 
    
    // Schedulers need to outlive task chains, so imagine m_looper_scheduler and m_background_dispatcher are created and stored from some constructor.
    // "Dispatchers" in Arcana.cpp are a class of schedulers that own their own work queue.
    
    arcana::task SomeFunctionCalledFromUIThread() {
      return arcana::make_task(m_background_dispatcher, arcana::cancellation::none(), []() {
        // Do something on a background thread (via background_dispatcher).
      }).then(m_looper_scheduler, arcana::cancellation::none(), []() {
        // Do something on the UI thread (via looper_scheduler).
      });
    }
    

    If you want to get more adventurous, C++ coroutines can be used with tasks, or directly with schedulers:

    #include 
    #include 
    #include 
    #include 
    
    arcana::task SomeFunctionCalledFromUIThread() { 
      auto looper_scheduler = arcana::looper_scheduler<64>::get_for_current_thread();
      arcana::background_dispatcher<64> background_dispatcher;
    
      // Code executing here is on the UI thread (since the function is called from the UI thread).
    
      co_await arcana::switch_to(background_dispatcher);
    
      // Code executing here is on a background thread.
    
      co_await arcana::switch_to(looper_scheduler);
    
      // Code executing here is back on the UI thread.
    }
    

    You can read more about Arcana.cpp schedulers, tasks, and coroutines here: https://github.com/microsoft/arcana.cpp/blob/master/Source/Arcana.Tasks.md

提交回复
热议问题