gpt4 book ai didi

android - Renderscript ScriptC 编译阻塞主线程

转载 作者:行者123 更新时间:2023-11-29 17:02:22 25 4
gpt4 key购买 nike

我正在开发一款使用自定义 RenderScript 脚本进行图像处理的应用。现在,因为我有很多这些脚本在使用中,所以我在应用程序首次启动时预加载它们。通过“预加载”我的意思是我实例化每个脚本,以便它可以在设备上编译。下面是这个操作的代码 fragment 。大约有 60 个脚本,但我认为这足以说明操作。

public class Load extends Thread {

public Load() {
super();
setPriority(Thread.MIN_PRIORITY);
}

@Override
public void run() {
new ScriptC_first(RenderScriptHelper.getInstance());
new ScriptC_second(RenderScriptHelper.getInstance());
new ScriptC_third(RenderScriptHelper.getInstance());
}
}

如您所见,我是在后台线程上执行此操作的。问题是脚本似乎在主线程上编译,不管这个。问题是他们阻止了用户界面。我用 AsyncTask 和 Service 试过这个,结果相同。我怀疑 RenderScript 在内部跳转到主线程来编译它们。

现在,在 Android Nougat (7.0) 之前,预加载相同数量的脚本需要不到 10 秒,具体取决于设备速度。在 Nougat 上,这需要将近一分钟的时间,考虑到它会阻塞 UI,这是一个大问题,尽管只是在第一次应用程序启动时。在随后的每次启动中,它都会在几秒钟内预加载(因为脚本已经编译)。

我需要预加载,因为按需实例化脚本不是一种选择,因为一旦用户开始使用应用程序,所有脚本都必须准备好并编译。

logcat 的相关部分:

E/RenderScript: Unable to open shared library (/data/user/0/com.company.myapp/cache/librs.contrast_v001.so): undefined symbol: .rs.dtor
V/RenderScript: Invoking /system/bin/bcc with args '/system/bin/bcc -unroll-runtime -scalarize-load-store -rs-global-info -rs-global-info-skip-constant -o contrast_v001 -output_path /data/user/0/com.company.myapp/cache -bclib /system/lib/libclcore.bc -mtriple armv7-none-linux-gnueabi -O 3 -load libbccQTI.so -fPIC -embedRSInfo /data/user/0/com.company.myapp/cache/contrast_v001.bc -build-checksum abadcafe'
V/RenderScript: Invoking /system/bin/ld.mc with args '/system/bin/ld.mc -shared -nostdlib /system/lib/libcompiler_rt.so -mtriple=armv7-none-linux-gnueabi --library-path=/system/vendor/lib --library-path=/system/lib -lRSDriver_adreno -lm -lc /data/user/0/com.company.myapp/cache/contrast_v001.o -o /data/user/0/com.company.myapp/cache/librs.contrast_v001.so'

此外,如果相关,我在第一次应用程序启动时使用 RenderScript.ContextType.PROFILE,在随后的每次启动时使用 RenderScript.ContextType.NORMAL。使用 RenderScript.ContextType.DEBUG 会导致脚本在每次应用程序启动时编译,所用时间与其他上下文相同,并且 logcat 输出略有不同:

V/RenderScript: Invoking /system/bin/bcc with args '/system/bin/bcc -unroll-runtime -scalarize-load-store -rs-global-info -rs-global-info-skip-constant -o contrast_v001 -output_path /data/user/0/com.company.myapp/cache -bclib /system/lib/libclcore_debug.bc -mtriple armv7-none-linux-gnueabi -O 3 -rs-debug-ctx -fPIC -embedRSInfo /data/user/0/com.company.myapp/cache/contrast_v001.bc -build-checksum abadcafe'
V/RenderScript: Invoking /system/bin/ld.mc with args '/system/bin/ld.mc -shared -nostdlib /system/lib/libcompiler_rt.so -mtriple=armv7-none-linux-gnueabi --library-path=/system/vendor/lib --library-path=/system/lib -lRSDriver_adreno -lm -lc /data/user/0/com.company.myapp/cache/contrast_v001.o -o /data/user/0/com.company.myapp/cache/librs.contrast_v001.so'

build.gradle 的相关部分:

renderscriptTargetApi 23
renderscriptSupportModeEnabled true

我搜索了有关 RenderScript 内部工作原理的文档和信息,但它确实很少,因为大部分内部工作原理都留给了设备供应商自行决定。

所以我的问题是:是否可以在不阻塞 UI 的情况下强制 RenderScript 在后台线程上编译脚本。

感谢任何帮助。

最佳答案

对于遇到此问题的任何人:我设法通过在应用程序的私有(private)进程中运行的服务解决了这个问题,声明如下:

<service
android:name="com.company.LoadService"
android:process=":loadService"
android:exported="false" />

我在服务中实例化了 ScriptC_something.class-es,因为它是一个单独的进程,所以我的 UI 线程再次空闲。

希望这对某人有帮助。

关于android - Renderscript ScriptC 编译阻塞主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42404246/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com