1

나는 이미지 처리를 위해 사용자 정의 RenderScript 스크립트를 사용하는 응용 프로그램에서 작업하고 있습니다. 자, 제가이 스크립트를 많이 사용하고 있기 때문에 먼저 앱에 미리로드합니다. "미리로드"는 각 스크립트를 인스턴스화하여 장치에서 컴파일되도록하는 것을 의미합니다. Bellow는이 작업의 코드 스 니펫입니다. 약 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()); 
    } 
} 

자세히 알 수 있듯이, 백그라운드 스레드에서이 작업을 수행하고 있습니다. 문제는 이것에 상관없이 스크립트가 주 스레드에서 컴파일되는 것처럼 보입니다. 문제는 사용자가 UI를 차단하고 있다는 것입니다. 나는 AsyncTask와 Service와 같은 결과로 이것을 시도했다. RenderScript가 내부 스레드로 컴파일되어 메인 스레드에서 컴파일 된 것으로 의심됩니다.

Android Nougat (7.0) 이전 버전에서는 동일한 속도의 스크립트를 미리로드하는 데 기기 속도에 따라 10 초가 걸렸습니다. 누우 가트 (Nougat)에서는 UI가 막히는 것을 고려할 때 큰 문제가되는데 1 분 정도 걸립니다. 첫 번째 앱 시작일뿐입니다. 이후의 모든 시작에서 스크립트가 이미 컴파일되어 있기 때문에 몇 초 안에 미리로드됩니다.

사용자가 앱을 사용하기 시작하면 모든 스크립트를 준비하고 컴파일해야하므로 주문형 스크립트를 인스턴스화하는 것은 옵션이 아니므로 사전로드가 필요합니다. 로그 캣의

주요부 :

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 다른 문맥으로 동일한 양의 시간을 가지고, 각각의 응용 프로그램 기동에 컴파일 스크립트를 발생하고 로그 캣 출력은 약간 다르다 : build.gradle의

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' 

주요부 :

renderscriptTargetApi 23 
renderscriptSupportModeEnabled true 

RenderScript 내부 작업에 대한 문서와 정보를 검색했지만, 내부 작동의 대부분이 장치 공급 업체의 재량에 맡겨져 있기 때문에 실제로는 부족합니다.

내 질문은 : UI를 차단하지 않고 RendScript가 배경 스레드에서 스크립트를 강제로 컴파일하도록 할 수 있습니까?

도움을 주시면 감사하겠습니다. 이 문제를 통해 오는 사람들을위한

답변

2

: 나는 서비스가 응용 프로그램의 개인 프로세스에서 실행의 문제를 해결하기 위해 관리는, 같은 선언 :

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

내가 내부의 ScriptC_something.class-ES를 인스턴스화 서비스이므로 별도의 프로세스이므로 내 UI 스레드는 다시 한 번 무료입니다.

희망이 있으면 도움이됩니다.