anber
anber

Reputation: 3665

Native call blocks main thread

I have some Android app that should load some data on start and process it as soon as possible. For better performance data processing done in native code. But in some time data amount was increased and it becomes to block UI while processing. The weird thing is that I launch JNI call from background thread and I believe native code should also work in background. So few questions:

  1. how to detect is native code works in main thread?
  2. how to detect who blocks UI?

Some code sample:

        // java
        new Thread(new Runnable() {
            @Override
            public void run() {
              ResourceLoader.loadListsAndParse(); // native call
            }
        }).start();


// c++
void RulesManager::loadRules() {
   if (!rules_loaded_) {
        using namespace std;
        base::FilePath my_dir;
        GetCacheDirectory(&my_dir);
        this->loadRulesInternal(my_dir, true);
   }
}

void RulesManager::loadRulesInternal(base::FilePath& path, bool processExceptions) {
   base::FileEnumerator files(path, false, base::FileEnumerator::FILES);
   for (base::FilePath name = files.Next(); !name.empty(); name = files.Next()) {
        this->loadRulesFromFile(name.AsUTF8Unsafe(), processExceptions);
   }
}

bool RulesManager::loadRulesFromFile(const std::string& filePath, bool processException) {
    bool result = false;
    std::ifstream file(filePath);
    std::string str;
    while (std::getline(file, str)) {
        result = this->addRule(str, processException);
    }
    return result;
}

Upvotes: 2

Views: 1438

Answers (3)

Alex Cohn
Alex Cohn

Reputation: 57163

Android has system calls getpid() and gettid() defined in <unistd.h>. If the pid_t return values are equal, then your native code runs on the UI thread.

Upvotes: 2

Serhat T&#252;rkman
Serhat T&#252;rkman

Reputation: 403

How to detect is native code works in main thread?

You can apply Log method inside your code.

For example your code is:

if(myInt > 0){
  doSth();
}

Insert Log method;

if(myInt > 0){
 doSth();
 Log.i("Info", "if statement is true.");
}

now your device will type to the console if your if statement runs. So in your thread, you can insert Log method to critical lines to see if it is running or not.

how to detect who blocks UI?

As in my first answer, again you can see it from the console if you implement Log methods to your code.

But if you want to do it properly, I suggest you to check Asynctask. This will take time to learn how to implement it properly but the most practical way to pass the long jobs to background in Android is Asynctask.

Upvotes: 1

Denysole
Denysole

Reputation: 4051

I use BlockCanary for that purposes. If you know about LeakCanary, BlockCanary provides reports about UI blocking in the same way.

enter image description here

Upvotes: 1

Related Questions