Renderscript ScriptC编译阻止主线程

问题描述:

我正在使用自定义RenderScript脚本进行图像处理的应用程序。现在,由于我有很多这些脚本正在使用,我将它们预先加载到应用程序首次启动。通过“预加载”我的意思是我实例化每个脚本,以便它可以在设备上编译。波纹是这个操作的代码片段。大约有60个脚本,但我认为这足以说明操作。Renderscript ScriptC编译阻止主线程

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和服务相同的结果。我怀疑RenderScript内部在主线程上跳转以编译它们。

现在,在Android Nougat(7.0)之前,根据设备速度的不同,预加载相同数量的脚本的时间不到10秒。在牛轧糖上花费近一分钟的时间,这是一个巨大的问题,考虑到它阻止了用户界面,尽管只是第一次启动应用程序。在随后的每次启动时,它都会在几秒钟之内预加载(因为脚本已经编译完成)。

我需要预加载,因为根据需要实例化脚本不是一个选项,因为所有脚本必须在用户开始使用该应用程序后进行编译和编译。所述的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.NORMAL在以后每次启动使用RenderScript.ContextType.PROFILE。使用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线程再次免费。

希望这可以帮助别人。