本机调用阻塞主线程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了本机调用阻塞主线程相关的知识,希望对你有一定的参考价值。

我有一些android应用程序应该在启动时加载一些数据并尽快处理它。为了在本机代码中完成更好的性能数据处理。但是在一段时间内,数据量增加了,并且在处理时变为阻止UI。奇怪的是我从后台线程启动JNI调用,我相信本机代码也应该在后台工作。这么几个问题:

  1. 如何检测原生代码在主线程中工作?
  2. 如何检测谁阻止UI?

一些代码示例:

        // 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;
}
答案

Android在<unistd.h>中定义了系统调用getpid()和gettid()。如果pid_t返回值相等,那么您的本机代码将在UI线程上运行。

另一答案

我为此目的使用BlockCanary。如果您了解LeakCanaryBlockCanary会以相同的方式提供有关UI阻止的报告。

enter image description here

另一答案

如何检测本机代码在主线程中工作?

您可以在代码中应用Log方法。

例如,您的代码是:

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

插入日志方法;

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

现在,如果if语句运行,您的设备将键入控制台。因此,在您的线程中,您可以将Log方法插入关键行以查看它是否正在运行。

如何检测谁阻止UI?

在我的第一个答案中,如果您在代码中实现Log方法,您可以再次从控制台中看到它。

但是如果你想要正确地做,我建议你检查Asynctask。这需要时间来学习如何正确实现它,但是在Android中将长作业传递到后台的最实用的方法是Asynctask。

以上是关于本机调用阻塞主线程的主要内容,如果未能解决你的问题,请参考以下文章

子线程怎么不阻塞主线程

从后台线程调用 startActivity 并且主线程被阻塞时,Activity 延迟启动

在辅助线程中调用 select()/pselect() 会导致主线程阻塞吗?

同步 异步 阻塞 非阻塞概念区分

CompletableFutureCompletableFuture测试runAsync()方法调用CompletableFuture.join()/get()方法阻塞主线程

cordova 3.0 FileWriter 线程警告:对 File.write 的 exec() 调用阻塞了主线程...应该使用 CordovaInterface.getThreadPool()