Skip to content
This repository has been archived by the owner on Jul 14, 2021. It is now read-only.

页面中有时候会有这种报错java.lang.NullPointerException: Attempt to read from field 'java.lang.Object android.util.Pair.second' on a null object reference #344

Closed
raulbest opened this issue May 3, 2018 · 10 comments

Comments

@raulbest
Copy link

raulbest commented May 3, 2018

java.lang.NullPointerException: Attempt to read from field 'java.lang.Object android.util.Pair.second' on a null object reference
at com.alibaba.android.vlayout.DelegateAdapter.findAdapterByIndex(DelegateAdapter.java:485)
at com.alibaba.android.vlayout.DelegateAdapter.onCreateViewHolder(DelegateAdapter.java:123)
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6493)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5680)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5563)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5559)
at com.alibaba.android.vlayout.ExposeLinearLayoutManagerEx$LayoutState.next(ExposeLinearLayoutManagerEx.java:1629)
at com.alibaba.android.vlayout.VirtualLayoutManager$LayoutStateWrapper.next(VirtualLayoutManager.java:1065)
at com.alibaba.android.vlayout.layout.SingleLayoutHelper.layoutViews(SingleLayoutHelper.java:78)
at com.alibaba.android.vlayout.layout.BaseLayoutHelper.doLayout(BaseLayoutHelper.java:318)
at com.alibaba.android.vlayout.VirtualLayoutManager.layoutChunk(VirtualLayoutManager.java:657)
at com.alibaba.android.vlayout.ExposeLinearLayoutManagerEx.fill(ExposeLinearLayoutManagerEx.java:1162)
at com.alibaba.android.vlayout.ExposeLinearLayoutManagerEx.onLayoutChildren(ExposeLinearLayoutManagerEx.java:365)
at com.alibaba.android.vlayout.VirtualLayoutManager.onLayoutChildren(VirtualLayoutManager.java:475)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3693)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3410)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3962)
at android.view.View.layout(View.java:16772)
at android.view.ViewGroup.layout(ViewGroup.java:5462)
at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:611)
at android.view.View.layout(View.java:16772)
at android.view.ViewGroup.layout(ViewGroup.java:5462)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1096)
at android.view.View.layout(View.java:16772)
at android.view.ViewGroup.layout(ViewGroup.java:5462)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:338)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16772)
at android.view.ViewGroup.layout(ViewGroup.java:5462)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:338)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16772)
at android.view.ViewGroup.layout(ViewGroup.java:5462)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1764)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1607)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1516)
at android.view.View.layout(View.java:16772)
at android.view.ViewGroup.layout(ViewGroup.java:5462)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:338)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16772)
at android.view.ViewGroup.layout(ViewGroup.java:5462)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1764)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1607)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1516)
at android.view.View.layout(View.java:16772)
at android.view.ViewGroup.layout(ViewGroup.java:5462)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:338)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:2757)
at android.view.View.layout(View.java:16772)
at android.view.ViewGroup.layout(ViewGroup.java:5462)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2234)

@JDDJJ
Copy link

JDDJJ commented May 21, 2018

这种问题 大概率是data改变 但是视图没有notify 这个问题不常发生 但是希望 作者还是讲这些异常throw一下 否则开发者没办法控制

@JDDJJ
Copy link

JDDJJ commented May 21, 2018

性能问题啊

@peerless2012
Copy link

我这里是必现的,我断点发现问题出在Cantor这个类上。
经测试,当返回ViewType比较大的时候,getCantor返回的值经过reverseCantor后不能得到正确的值。

测试代码:
输入:

        public static void main(String[] args) {
		long cantor = Cantor.getCantor(1000052, 0);
		long[] result = new long[2];
		Cantor.reverseCantor(cantor, result);
		System.out.println("index = " + result[1] + ", type = " + result[0]);
	}

输出结果是:

index = -2147483648, type = -2146483596

@Fyyvictory
Copy link

我现在使用也是有时候出现这个问题,有没有能够改善的方法呢?

@raulbest
Copy link
Author

我这里是必现的,我断点发现问题出在Cantor这个类上。
经测试,当返回ViewType比较大的时候,getCantor返回的值经过reverseCantor后不能得到正确的值。

测试代码:
输入:

        public static void main(String[] args) {
		long cantor = Cantor.getCantor(1000052, 0);
		long[] result = new long[2];
		Cantor.reverseCantor(cantor, result);
		System.out.println("index = " + result[1] + ", type = " + result[0]);
	}

输出结果是:

index = -2147483648, type = -2146483596

你好,请问这个问题你那边还有再出现过么?怎么解决的?,谢谢

@peerless2012
Copy link

我这里是必现的,我断点发现问题出在Cantor这个类上。
经测试,当返回ViewType比较大的时候,getCantor返回的值经过reverseCantor后不能得到正确的值。
测试代码:
输入:

        public static void main(String[] args) {
		long cantor = Cantor.getCantor(1000052, 0);
		long[] result = new long[2];
		Cantor.reverseCantor(cantor, result);
		System.out.println("index = " + result[1] + ", type = " + result[0]);
	}

输出结果是:

index = -2147483648, type = -2146483596

你好,请问这个问题你那边还有再出现过么?怎么解决的?,谢谢

自己转换一下

public class ViewNodeTypeHelper {

    private static final SparseIntArray VIEW_TYPE_MAPPING = new SparseIntArray(30);

    private static final SparseIntArray VIEW_TYPE_UN_MAPPING = new SparseIntArray(30);

    private static AtomicInteger ENCODED_VIEW_TYPE = new AtomicInteger(1);

    public static int encode(int viewType) {
        int encodedViewType = VIEW_TYPE_MAPPING.get(viewType);
        if (encodedViewType <= 0) {
            encodedViewType = ENCODED_VIEW_TYPE.getAndIncrement();
            VIEW_TYPE_MAPPING.put(viewType, encodedViewType);
            VIEW_TYPE_UN_MAPPING.put(encodedViewType, viewType);
        }
        return encodedViewType;
    }

    public static int decode(int encodedViewType) {
        return VIEW_TYPE_UN_MAPPING.get(encodedViewType);
    }

}

@raulbest
Copy link
Author

@peerless2012 你好,方便加下你WX或QQ么?可能还有几个点想请教你一下(447626696)

@raulbest
Copy link
Author

raulbest commented Dec 14, 2018

我这里是必现的,我断点发现问题出在Cantor这个类上。
经测试,当返回ViewType比较大的时候,getCantor返回的值经过reverseCantor后不能得到正确的值。
测试代码:
输入:

        public static void main(String[] args) {
		long cantor = Cantor.getCantor(1000052, 0);
		long[] result = new long[2];
		Cantor.reverseCantor(cantor, result);
		System.out.println("index = " + result[1] + ", type = " + result[0]);
	}

输出结果是:

index = -2147483648, type = -2146483596

你好,请问这个问题你那边还有再出现过么?怎么解决的?,谢谢

自己转换一下

public class ViewNodeTypeHelper {

    private static final SparseIntArray VIEW_TYPE_MAPPING = new SparseIntArray(30);

    private static final SparseIntArray VIEW_TYPE_UN_MAPPING = new SparseIntArray(30);

    private static AtomicInteger ENCODED_VIEW_TYPE = new AtomicInteger(1);

    public static int encode(int viewType) {
        int encodedViewType = VIEW_TYPE_MAPPING.get(viewType);
        if (encodedViewType <= 0) {
            encodedViewType = ENCODED_VIEW_TYPE.getAndIncrement();
            VIEW_TYPE_MAPPING.put(viewType, encodedViewType);
            VIEW_TYPE_UN_MAPPING.put(encodedViewType, viewType);
        }
        return encodedViewType;
    }

    public static int decode(int encodedViewType) {
        return VIEW_TYPE_UN_MAPPING.get(encodedViewType);
    }

}
``

你好,你是直接把他们Vlayout项目的源码改掉(用ViewNodeTypeHelper替换掉Cantor这个?),然后直接用Module的形式依赖到你们自己的项目中的么?如果是module的话可以打包发我一下么?谢谢(raulbest@qq.com

@peerless2012
Copy link

我这里是必现的,我断点发现问题出在Cantor这个类上。
经测试,当返回ViewType比较大的时候,getCantor返回的值经过reverseCantor后不能得到正确的值。
测试代码:
输入:

        public static void main(String[] args) {
		long cantor = Cantor.getCantor(1000052, 0);
		long[] result = new long[2];
		Cantor.reverseCantor(cantor, result);
		System.out.println("index = " + result[1] + ", type = " + result[0]);
	}

输出结果是:

index = -2147483648, type = -2146483596

你好,请问这个问题你那边还有再出现过么?怎么解决的?,谢谢

自己转换一下

public class ViewNodeTypeHelper {

    private static final SparseIntArray VIEW_TYPE_MAPPING = new SparseIntArray(30);

    private static final SparseIntArray VIEW_TYPE_UN_MAPPING = new SparseIntArray(30);

    private static AtomicInteger ENCODED_VIEW_TYPE = new AtomicInteger(1);

    public static int encode(int viewType) {
        int encodedViewType = VIEW_TYPE_MAPPING.get(viewType);
        if (encodedViewType <= 0) {
            encodedViewType = ENCODED_VIEW_TYPE.getAndIncrement();
            VIEW_TYPE_MAPPING.put(viewType, encodedViewType);
            VIEW_TYPE_UN_MAPPING.put(encodedViewType, viewType);
        }
        return encodedViewType;
    }

    public static int decode(int encodedViewType) {
        return VIEW_TYPE_UN_MAPPING.get(encodedViewType);
    }

}
``

你好,你是直接把他们Vlayout项目的源码改掉(用ViewNodeTypeHelper替换掉Cantor这个?),然后直接用Module的形式依赖到你们自己的项目中的么?如果是module的话可以打包发我一下么?谢谢(raulbest@qq.com

核心就是这个类,就是在你的Adapter的public int getItemViewType(int position)中返回encode的值,然后createViewHolder()的时候decode一下就好了。

@Attect
Copy link

Attect commented Jan 22, 2019

我这里是必现的,我断点发现问题出在Cantor这个类上。
经测试,当返回ViewType比较大的时候,getCantor返回的值经过reverseCantor后不能得到正确的值。
测试代码:
输入:

        public static void main(String[] args) {
		long cantor = Cantor.getCantor(1000052, 0);
		long[] result = new long[2];
		Cantor.reverseCantor(cantor, result);
		System.out.println("index = " + result[1] + ", type = " + result[0]);
	}

输出结果是:

index = -2147483648, type = -2146483596

你好,请问这个问题你那边还有再出现过么?怎么解决的?,谢谢

自己转换一下

public class ViewNodeTypeHelper {

    private static final SparseIntArray VIEW_TYPE_MAPPING = new SparseIntArray(30);

    private static final SparseIntArray VIEW_TYPE_UN_MAPPING = new SparseIntArray(30);

    private static AtomicInteger ENCODED_VIEW_TYPE = new AtomicInteger(1);

    public static int encode(int viewType) {
        int encodedViewType = VIEW_TYPE_MAPPING.get(viewType);
        if (encodedViewType <= 0) {
            encodedViewType = ENCODED_VIEW_TYPE.getAndIncrement();
            VIEW_TYPE_MAPPING.put(viewType, encodedViewType);
            VIEW_TYPE_UN_MAPPING.put(encodedViewType, viewType);
        }
        return encodedViewType;
    }

    public static int decode(int encodedViewType) {
        return VIEW_TYPE_UN_MAPPING.get(encodedViewType);
    }

}
``

你好,你是直接把他们Vlayout项目的源码改掉(用ViewNodeTypeHelper替换掉Cantor这个?),然后直接用Module的形式依赖到你们自己的项目中的么?如果是module的话可以打包发我一下么?谢谢(raulbest@qq.com

直接改DelegateAdapter

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (mHasConsistItemType) {
            Adapter adapter = mItemTypeAry.get(viewType);
            if (adapter != null) {
                return adapter.onCreateViewHolder(parent, viewType);
            }

            return null;
        }


        // reverse Cantor Function
        Cantor.reverseCantor(viewType, cantorReverse);

        int index = (int) cantorReverse[1];
        int subItemType = ViewNodeTypeHelper.decode((int) cantorReverse[0]);

        Adapter adapter = findAdapterByIndex(index);
        if (adapter == null) {
            return null;
        }

        return adapter.onCreateViewHolder(parent, subItemType);
    }
    public int getItemViewType(int position) {
        Pair<AdapterDataObserver, Adapter> p = findAdapterByPosition(position);
        if (p == null) {
            return RecyclerView.INVALID_TYPE;
        }

        int subItemType = p.second.getItemViewType(position - p.first.mStartPosition);

        if (subItemType < 0) {
            // negative integer, invalid, just return
            return subItemType;
        }
        subItemType = ViewNodeTypeHelper.encode(subItemType);
        if (mHasConsistItemType) {
            mItemTypeAry.put(subItemType, p.second);
            return subItemType;
        }


        int index = p.first.mIndex;

        return (int) Cantor.getCantor(subItemType, index);
    }

我这边这样后就好了

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants