繁体   English   中英

Renderscript ScriptC编译阻塞主线程

[英]Renderscript ScriptC compile blocking main thread

我正在开发一个使用自定义RenderScript脚本进行图像处理的应用程序。 现在,由于我有很多这些脚本在使用,我首先在应用程序上预加载它们。 通过“预加载”我的意思是我实例化每个脚本,以便它可以在设备上编译。 Bellow是此操作的代码片段。 大约有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内部工作的文档和信息,但它非常缺乏,因为大多数内部工作都由设备供应商自行决定。

所以我的问题是:是否可以强制RenderScript在后台线程上编译脚本,而不会阻止UI。

任何帮助表示赞赏。

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

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

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

希望这有助于某人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM