Search code examples
androidandroid-softkeyboard

How to fix Android Cannot get a dirty matrix error?


An unknown error was output while using the soft keyboard

A/OpenGLRenderer: Cannot get a dirty matrix!
A/libc: Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 42843 (Thread-12), pid 15445

Why does such an error occur?? How do you solve it?


Solution

  • do not call View#getLocationOnScreen or View#getMatrix on you worker thread,


    View#getLocationOnScreen or View#getMatrix will reset variable 'mPrimitiveFields.mMatrixOrPivotDirty' to false and check it, if true then crash;

    Many APIs that run on the main thread like View#setScaleX/setScaleY/setAlpha will set variable 'mPrimitiveFields.mMatrixOrPivotDirty' to true

    so if 'View#getLocationOnScreen or View#getMatrix' run on worker thread, it is possible to concurrently modify the variable 'mPrimitiveFields.mMatrixOrPivotDirty' and cause a crash

    f you want a more detailed analysis, visit this: https://www.jianshu.com/p/d6d3bb641198


    http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/jni/android_view_RenderNode.cpp http://androidxref.com/9.0.0_r3/xref/frameworks/base/libs/hwui/RenderProperties.h

    View#getLocationOnScreen or View#getMatrix -> android_view_RenderNode.cpp#android_view_RenderNode_getTransformMatrix ->

        static void android_view_RenderNode_getTransformMatrix(jlong renderNodePtr, jlong outMatrixPtr) {
            RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
            SkMatrix* outMatrix = reinterpret_cast<SkMatrix*>(outMatrixPtr);
    
            // call updateMatrix to reset 'mPrimitiveFields.mMatrixOrPivotDirty' to false
            renderNode->mutateStagingProperties().updateMatrix();
            // check 'mPrimitiveFields.mMatrixOrPivotDirty', if true then crash
            const SkMatrix* transformMatrix = renderNode->stagingProperties().getTransformMatrix();
    
            if (transformMatrix) {
                *outMatrix = *transformMatrix;
            } else {
                outMatrix->setIdentity();
            }
        }
    
        const SkMatrix* getTransformMatrix() const {
            LOG_ALWAYS_FATAL_IF(mPrimitiveFields.mMatrixOrPivotDirty, "Cannot get a dirty matrix!");
            return mComputedFields.mTransformMatrix;
        }