siyamed / android-shape-imageview

Custom shaped android imageview components
MIT License
2.67k stars 599 forks source link

App crashes in android Q #85

Open ahqmrf opened 5 years ago

ahqmrf commented 5 years ago

App crashes in android Q using the HexagonImageView. I have the following stacktrace:

android.view.InflateException: Binary XML file line #9: Binary XML file line #9: Error inflating class com.github.siyamed.shapeimageview.HexagonImageView Caused by: android.view.InflateException: Binary XML file line #9: Error inflating class com.github.siyamed.shapeimageview.HexagonImageView Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Constructor.newInstance0(Native Method) at java.lang.reflect.Constructor.newInstance(Constructor.java:343) at android.view.LayoutInflater.createView(LayoutInflater.java:854) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1004) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:959) at android.view.LayoutInflater.rInflate(LayoutInflater.java:1119) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1080) at android.view.LayoutInflater.inflate(LayoutInflater.java:693) at android.view.LayoutInflater.inflate(LayoutInflater.java:545) at com.example.app.kotlinext.ExtensionUtils.inflate(Extensions.kt:67) at com.example.app.kotlinext.ExtensionUtils.inflate$default(Extensions.kt:67) at com.example.app.adapters.delegates.card.HexagonAdapterDelegate$HexagonItemViewHolder.<init>(HexagonAdapterDelegate.kt:101) at com.example.app.adapters.delegates.card.HexagonAdapterDelegate.onCreateViewHolder(HexagonAdapterDelegate.kt:91) at com.hannesdorfmann.adapterdelegates3.AdapterDelegatesManager.onCreateViewHolder(AdapterDelegatesManager.java:249) at com.hannesdorfmann.adapterdelegates3.AbsDelegationAdapter.onCreateViewHolder(AbsDelegationAdapter.java:74) at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6794) at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5975) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854) at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230) at android.support.v7.widget.GridLayoutManager.layoutChunk(GridLayoutManager.java:557) at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517) at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612) at android.support.v7.widget.GridLayoutManager.onLayoutChildren(GridLayoutManager.java:171) at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3924) at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3641) at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:4194) at android.view.View.layout(View.java:22254) at android.view.ViewGroup.layout(ViewGroup.java:6310) at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:625) at android.view.View.layout(View.java:22254) at android.view.ViewGroup.layout(ViewGroup.java:6310) at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1775) at android.view.View.layout(View.java:22254) at android.view.ViewGroup.layout(ViewGroup.java:6310) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673) at android.widget.LinearLayout.onLayout(LinearLayout.java:1582) at android.view.View.layout(View.java:22254) at android.view.ViewGroup.layout(ViewGroup.java:6310) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at android.view.View.layout(View.java:22254) at android.view.ViewGroup.layout(ViewGroup.java:6310) at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1099) at android.view.View.layout(View.java:22254) at android.view.ViewGroup.layout(ViewGroup.java:6310) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) 2019-05-28 20:43:43.372 11231-11231/com.example.app.debug E/AndroidRuntime: at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at android.view.View.layout(View.java:22254) at android.view.ViewGroup.layout(ViewGroup.java:6310) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673) at android.widget.LinearLayout.onLayout(LinearLayout.java:1582) at android.view.View.layout(View.java:22254) at android.view.ViewGroup.layout(ViewGroup.java:6310) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at android.view.View.layout(View.java:22254) at android.view.ViewGroup.layout(ViewGroup.java:6310) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673) at android.widget.LinearLayout.onLayout(LinearLayout.java:1582) at android.view.View.layout(View.java:22254) at android.view.ViewGroup.layout(ViewGroup.java:6310) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at android.view.View.layout(View.java:22254) at android.view.ViewGroup.layout(ViewGroup.java:6310) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673) at android.widget.LinearLayout.onLayout(LinearLayout.java:1582) at android.view.View.layout(View.java:22254) at android.view.ViewGroup.layout(ViewGroup.java:6310) at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332) at android.widget.FrameLayout.onLayout(FrameLayout.java:270) at com.android.internal.policy.DecorView.onLayout(DecorView.java:761) at android.view.View.layout(View.java:22254) at android.view.ViewGroup.layout(ViewGroup.java:6310) at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:3161) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2621) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1744) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7714) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:966) at android.view.Choreographer.doCallbacks(Choreographer.java:790) at android.view.Choreographer.doFrame(Choreographer.java:725) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:951) at android.os.Handler.handleCallback(Handler.java:878) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:209) at android.app.ActivityThread.main(ActivityThread.java:7046) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:486) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862) Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Lorg/kxml2/io/KXmlParser; at com.github.siyamed.shapeimageview.path.parser.SvgToPath.parse(SvgToPath.java:49) at com.github.siyamed.shapeimageview.path.parser.SvgToPath.getSVGFromInputStream(SvgToPath.java:44) at com.github.siyamed.shapeimageview.path.SvgUtil.readSvg(SvgUtil.java:22) at com.github.siyamed.shapeimageview.shader.SvgShader.setShapeResId(SvgShader.java:76) at com.github.siyamed.shapeimageview.shader.SvgShader.init(SvgShader.java:67) at com.github.siyamed.shapeimageview.ShaderImageView.setup(ShaderImageView.java:34) at com.github.siyamed.shapeimageview.ShaderImageView.<init>(ShaderImageView.java:25) at com.github.siyamed.shapeimageview.HexagonImageView.<init>(HexagonImageView.java:16) ... 94 more

AlekseiPecherei commented 4 years ago

There're two ways to fix crash.

First

  1. Include sources as module to your project.
  2. Open SvgToPath class and change this metod:

    private static PathInfo parse(InputStream in)  {
        try {
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(true);
            XmlPullParser xr = factory.newPullParser();
            SvgToPath svgHandler = new SvgToPath(xr);
            svgHandler.setDpi(DPI);
    
            xr.setInput(new InputStreamReader(in));
            svgHandler.processSvg();
    
            return svgHandler.pathInfo;
        } catch (Exception e) {
            Log.w(TAG, "Parse error: " + e);
            throw new RuntimeException(e);
        }
    }

Just replace KXmlParser to

            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(true);
            XmlPullParser xr = factory.newPullParser();

And it will be work.

The second way is to use inheritance:

  1. Extends HexagonImageView

    public class MyHexagonImageView extends HexagonImageView {
    
    public MyHexagonImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    @Override
    public ShaderHelper createImageViewHelper() {
        return new MySvgShader(R.raw.imgview_hexagon);
    }
    }
  2. Extends SvgShader

    
    public class MySvgShader extends SvgShader {
    
    @Override
    public void setShapeResId(Context context, int resId) {
        if(resId != -1) {
            shapePath = MySvgUtil.readSvg(context, resId);
        } else {
            throw new RuntimeException("No resource is defined as shape");
        }
    }

}


3. Extends MySvgUtil

public class MySvgUtil { private static final Map<Integer, PathInfo> PATH_MAP = new ConcurrentHashMap<Integer, PathInfo>();

public static final PathInfo readSvg(Context context, int resId) {
    PathInfo pathInfo = PATH_MAP.get(resId);
    if(pathInfo == null) {
        InputStream is = null;
        try {
            is = context.getResources().openRawResource(resId);
            pathInfo = MySvgToPath.getSVGFromInputStream(is);
            PATH_MAP.put(resId, pathInfo);
        } finally {
            IoUtil.closeQuitely(is);
        }
    }

    return pathInfo;
}

}

Extends SvgToPath:

public class MySvgToPath extends SvgToPath {

private static final float DPI = 72.0f;

public static PathInfo getSVGFromInputStream(InputStream inputStream) {
    return MySvgToPath.parse(inputStream);
}

private static PathInfo parse(InputStream in)  {
    try {
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(true);
        XmlPullParser xr = factory.newPullParser();
        SvgToPath svgHandler = new SvgToPath(xr);
        svgHandler.setDpi(DPI);

        xr.setInput(new InputStreamReader(in));
        svgHandler.processSvg();

        return svgHandler.pathInfo;
    } catch (Exception e) {
        Log.w(TAG, "Parse error: " + e);
        throw new RuntimeException(e);
    }
}

}


I don't check second way. But I believe it'll be work too.
mucahitsidimi commented 4 years ago

If you add this dependencies it will be work on Android Q too.

compile 'com.github.siyamed:android-shape-imageview:0.9.3@aar'
compile group: 'net.sf.kxml', name: 'kxml2-min', version: '2.3.0'