int android.view.View.getImportantForAccessibility()

本文详细解析了在Adapter的getView方法中返回null时触发的NullPointerException异常原因,及如何避免此异常的发生,确保Android应用的稳定运行。

在这里插入图片描述
在adapter中getView的View返回null的时候就报这个异常
java.lang.NullPointerException: Attempt to invoke virtual method ‘int android.view.View.getImportantForAccessibility()’ on a null object reference

package com.st.launcher.util; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import androidx.viewpager.widget.ViewPager; public class ControlSlideViewPager extends ViewPager { public ControlSlideViewPager(Context context) { super(context); } public ControlSlideViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return false; } @Override public boolean onTouchEvent(MotionEvent ev) { return false; } } public ViewPager(@NonNull Context context) { super(context); initViewPager(); } public ViewPager(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); initViewPager(); } void initViewPager() { setWillNotDraw(false); setDescendantFocusability(FOCUS_AFTER_DESCENDANTS); setFocusable(true); final Context context = getContext(); mScroller = new Scroller(context, sInterpolator); final ViewConfiguration configuration = ViewConfiguration.get(context); final float density = context.getResources().getDisplayMetrics().density; mTouchSlop = configuration.getScaledPagingTouchSlop(); mMinimumVelocity = (int) (MIN_FLING_VELOCITY * density); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); mLeftEdge = new EdgeEffect(context); mRightEdge = new EdgeEffect(context); mFlingDistance = (int) (MIN_DISTANCE_FOR_FLING * density); mCloseEnough = (int) (CLOSE_ENOUGH * density); mDefaultGutterSize = (int) (DEFAULT_GUTTER_SIZE * density); ViewCompat.setAccessibilityDelegate(this, new MyAccessibilityDelegate()); if (ViewCompat.getImportantForAccessibility(this) == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO) { ViewCompat.setImportantForAccessibility(this, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES); } ViewCompat.setOnApplyWindowInsetsListener(this, new androidx.core.view.OnApplyWindowInsetsListener() { private final Rect mTempRect = new Rect(); @Override public WindowInsetsCompat onApplyWindowInsets(final View v, final WindowInsetsCompat originalInsets) { // First let the ViewPager itself try and consume them... final WindowInsetsCompat applied = ViewCompat.onApplyWindowInsets(v, originalInsets); if (applied.isConsumed()) { // If the ViewPager consumed all insets, return now return applied; } // Now we'll manually dispatch the insets to our children. Since ViewPager // children are always full-height, we do not want to use the standard // ViewGroup dispatchApplyWindowInsets since if child 0 consumes them, // the rest of the children will not receive any insets. To workaround this // we manually dispatch the applied insets, not allowing children to // consume them from each other. We do however keep track of any insets // which are consumed, returning the union of our children's consumption final Rect res = mTempRect; res.left = applied.getSystemWindowInsetLeft(); res.top = applied.getSystemWindowInsetTop(); res.right = applied.getSystemWindowInsetRight(); res.bottom = applied.getSystemWindowInsetBottom(); for (int i = 0, count = getChildCount(); i < count; i++) { final WindowInsetsCompat childInsets = ViewCompat .dispatchApplyWindowInsets(getChildAt(i), applied); // Now keep track of any consumed by tracking each dimension's min // value res.left = Math.min(childInsets.getSystemWindowInsetLeft(), res.left); res.top = Math.min(childInsets.getSystemWindowInsetTop(), res.top); res.right = Math.min(childInsets.getSystemWindowInsetRight(), res.right); res.bottom = Math.min(childInsets.getSystemWindowInsetBottom(), res.bottom); } // Now return a new WindowInsets, using the consumed window insets return applied.replaceSystemWindowInsets( res.left, res.top, res.right, res.bottom); } }); } ------------------------ 这是viewpager的代码 package com.st.launcher.util; import android.content.Context; import android.content.res.Resources; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.MotionEvent; import android.view.ViewConfiguration; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import static org.junit.Assert.assertFalse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.contains; import static org.powermock.api.mockito.PowerMockito.mock; import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; import androidx.viewpager.widget.ViewPager; import java.lang.reflect.Field; @RunWith(org.powermock.modules.junit4.PowerMockRunner.class) @org.powermock.core.classloader.annotations.PrepareForTest({ControlSlideViewPager.class, ViewConfiguration.class}) public class ControlSlideViewPagerTest { @Test public void testOnInterceptTouchEvent_ReturnsFalse() throws Exception{ mockStatic(ViewConfiguration.class); // 创建一个 mock 的 Context(虽然不会实际使用) Context mockContext = Mockito.mock(Context.class); when(ViewConfiguration.get(any())).thenReturn(mock(ViewConfiguration.class)); ViewPager mockViewPager = mock(ViewPager.class); Context mock = mock(Context.class); DisplayMetrics displayMetrics = mock(DisplayMetrics.class); Resources resources = mock(Resources.class); when(mockViewPager.getContext()).thenReturn(mock); when(mock.getResources()).thenReturn(resources); when(resources.getDisplayMetrics()).thenReturn(displayMetrics); Field declaredField = DisplayMetrics.class.getDeclaredField("density"); declaredField.setAccessible(true); declaredField.set(displayMetrics,1); // 构造被测试的对象 ControlSlideViewPager viewPager = new ControlSlideViewPager(mockContext); // 调用方法 MotionEvent mockEvent = Mockito.mock(MotionEvent.class); boolean result = viewPager.onInterceptTouchEvent(mockEvent); // 验证返回值 assertFalse(result); } @Test public void testOnTouchEvent_ReturnsFalse() { // 创建一个 mock 的 Context Context mockContext = Mockito.mock(Context.class); // 构造被测试的对象 ControlSlideViewPager viewPager = new ControlSlideViewPager(mockContext); // 调用方法 MotionEvent mockEvent = Mockito.mock(MotionEvent.class); boolean result = viewPager.onTouchEvent(mockEvent); // 验证返回值 assertFalse(result); } @Test public void testConstructor_TwoParams_DoesNotThrow() { // 创建 mocks Context mockContext = Mockito.mock(Context.class); AttributeSet mockAttrs = Mockito.mock(AttributeSet.class); // 构造对象 ControlSlideViewPager viewPager = new ControlSlideViewPager(mockContext, mockAttrs); // 如果没有抛出异常,则测试通过 } } 为什么这样mock还是会报错
07-30
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值