Skip to content

Commit

Permalink
Android helper functions.
Browse files Browse the repository at this point in the history
Two helper functions to help developers to easily run C++ code on Android UI thread.
  • Loading branch information
bog-dan-ro committed Feb 17, 2016
1 parent 5cc29db commit a3e4d26
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 0 deletions.
6 changes: 6 additions & 0 deletions utils/README.md
@@ -0,0 +1,6 @@
#Android helper functions

Two helper functions to help developers to easily run C++ code on Android UI thread.

Check https://www.kdab.com/qt-on-android-how-to-run-c-code-on-android-ui-thread to learn more about this functions.

11 changes: 11 additions & 0 deletions utils/android/src/com/kdab/android/utils/Runnable.java
@@ -0,0 +1,11 @@
package com.kdab.android.utils;

class Runnable implements java.lang.Runnable
{
@Override
public void run() {
runPendingCppRunnables();
}

public static native void runPendingCppRunnables();
}
56 changes: 56 additions & 0 deletions utils/androidutils.cpp
@@ -0,0 +1,56 @@
#include "androidutils.h"

#include <deque>
#include <memory>
#include <mutex>

#include <QtAndroid>
#include <QSemaphore>
#include <QAndroidJniEnvironment>

namespace KDAB {
namespace Android {

static std::deque<Runnable> s_pendingRunnables;
static std::mutex s_pendingRunnablesMutex;

void runOnAndroidThread(const Runnable &runnable)
{
s_pendingRunnablesMutex.lock();
bool triggerRun = s_pendingRunnables.empty();
s_pendingRunnables.push_back(runnable);
s_pendingRunnablesMutex.unlock();
if (triggerRun) {
QtAndroid::androidActivity().callMethod<void>("runOnUiThread",
"(Ljava/lang/Runnable;)V",
QAndroidJniObject("com/kdab/android/utils/Runnable").object());
}
}

void runOnAndroidThreadSync(const Runnable &runnable, int waitMs)
{
std::shared_ptr<QSemaphore> sem = std::make_shared<QSemaphore>();
runOnAndroidThread([sem, &runnable](){
runnable();
sem->release();
});
sem->tryAcquire(1, waitMs);
}

extern "C" JNIEXPORT void JNICALL Java_com_kdab_android_utils_Runnable_runPendingCppRunnables(JNIEnv */*env*/, jobject /*obj*/)
{
for (;;) { // run all posted runnables
s_pendingRunnablesMutex.lock();
if (s_pendingRunnables.empty()) {
s_pendingRunnablesMutex.unlock();
break;
}
Runnable runnable(std::move(s_pendingRunnables.front()));
s_pendingRunnables.pop_front();
s_pendingRunnablesMutex.unlock();
runnable();
}
}

} // namespace Android
} // KDAB
22 changes: 22 additions & 0 deletions utils/androidutils.h
@@ -0,0 +1,22 @@
#ifndef ANDROIDUTILS_H
#define ANDROIDUTILS_H

#include <functional>

namespace KDAB {
namespace Android {

typedef std::function<void()> Runnable;

/// Posts a runnable on Android thread, then exists.
/// If you call runOnAndroidThread from Android UI thread,
/// it will execute the runnable immediately
void runOnAndroidThread(const Runnable &runnable);

/// Posts a runnable on Android thread then waits until it's executed.
void runOnAndroidThreadSync(const Runnable &runnable, int waitMs = INT_MAX);

} // namespace Android
} // KDAB

#endif // ANDROIDUTILS_H

0 comments on commit a3e4d26

Please sign in to comment.