我有一些Android应用程序应该在启动时加载一些数据并尽快处理它。为了在本机代码中完成更好的性能数据处理。 但是在一段时间内,数据量增加了,并且在处理时变为阻止UI。奇怪的是我从后台线程启动JNI调用,我相信本机代码也应该在后台工作。 这么几个问题:
一些代码示例:
// 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;
}
答案 0 :(得分:2)
Android在< unistd.h> 中定义了系统调用 getpid()和 gettid()。如果 pid_t 返回值相等,那么您的本机代码将在UI线程上运行。
答案 1 :(得分:1)
我出于此目的使用BlockCanary。如果您了解LeakCanary
,BlockCanary
会以相同的方式提供有关UI阻止的报告。
答案 2 :(得分:1)
如何检测本机代码是否在主线程中工作?
您可以在代码中应用Log方法。
例如,您的代码是:
if(myInt > 0){
doSth();
}
插入日志方法;
if(myInt > 0){
doSth();
Log.i("Info", "if statement is true.");
}
现在,如果if语句运行,您的设备将键入控制台。因此,在您的线程中,您可以将Log方法插入关键行以查看它是否正在运行。
如何检测谁阻止UI?
在我的第一个回答中,如果您在代码中实现Log方法,则可以再次从控制台中看到它。
但是如果你想要正确地做,我建议你检查Asynctask。这需要时间来学习如何正确实现它,但在Android中将长作业传递到后台的最实用的方法是Asynctask。