安卓应用模拟器运行正常,华为Nova 4e打开Activity报android.os.RemoteException崩溃
问题根因
- 报错
java.lang.IllegalArgumentException: File descriptors passed in Bundle是华为ROM特有的校验逻辑触发的:系统在执行Activity停止逻辑时,会校验保存状态的Bundle中是否携带非法的文件描述符,原生Android模拟器无此强校验,所以仅在华为设备崩溃。 - 你的代码中存在资源泄露问题,未正确释放View关联的文件句柄,最终导致非法描述符被写入系统Bundle触发崩溃。
需修复的问题点及对应代码
1. 修复PagerAdapter错误的销毁逻辑
你在destroyItem方法中错误地将返回的View强转为CustomScrollView,如果布局根节点不是该类型,会导致View移除失败,关联的图片、动画资源无法释放。
// 修复前 @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((CustomScrollView) object); } // 修复后 @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); }
2. 优化Firebase数据回调逻辑,避免重复创建适配器
你目前在onDataChange的循环中每匹配到一张图片就重新创建适配器并设置给ViewPager,会导致大量旧资源无法及时释放,修改为循环结束后统一设置适配器:
@Override public void onDataChange(@NonNull DataSnapshot snapshot) { allimages.clear(); String checkType = IRCorTaskCard(Engineerproofimage.this); for (DataSnapshot snapss : snapshot.getChildren()) { String key = snapss.getKey(); if (key == null || key.length() < 3) continue; // 避免substring越界 String sub = key.substring(0, 3); boolean isMatch = false; if ("TASKCARD".equals(checkType)) { isMatch = key.contains(keys) && !sub.contains("IRC"); } else if ("IRC".equals(checkType)) { isMatch = key.contains(keys) && sub.contains("IRC"); } if (isMatch) { String name = snapss.child("Name").getValue(String.class); String ImageUri = snapss.child("Uri").getValue(String.class); String date = snapss.child("Date").getValue(String.class); String time = snapss.child("Time").getValue(String.class); String location = snapss.child("Location").getValue(String.class); allimages.add(new GalleryModel(ImageUri, name, date, time, location)); } } // 循环结束统一处理 if (allimages.isEmpty()) { Toast.makeText(getApplicationContext(), "Image not found.", Toast.LENGTH_SHORT).show(); return; } vpAdapter = new VPAdapterE(Engineerproofimage.this, allimages); MainvPager.setAdapter(vpAdapter); int prevpos = GalleryAdapter.getpos(); if (prevpos >= 0 && prevpos < allimages.size()) { MainvPager.setCurrentItem(prevpos); } }
3. 移除Picasso多余的加载请求
连续两次调用load加载同一张图片会重复打开文件流,多余的fetch调用可以直接删除:
// 删除多余的fetch调用 // Picasso.get().load(item.getImage_id()).fetch(); Picasso.get().load(item.getImage_id()).into(imageView, new Callback() { @Override public void onSuccess() { loadanim.pauseAnimation(); loadanim.setVisibility(View.GONE); } @Override public void onError(Exception e) { loadanim.pauseAnimation(); loadanim.setVisibility(View.GONE); Toast.makeText(getApplicationContext(), "Failed to load images.", Toast.LENGTH_SHORT).show(); } });
4. 补充Intent参数空校验
避免getExtras()为空时触发空指针:
Intent intent = getIntent(); Bundle extras = intent.getExtras(); if (extras != null) { Key = extras.getString("KEYINDV"); UID = extras.getString("UIDE"); }
可选优化
VPAdapterE中不要用全局成员变量Position存储当前位置,多页面滑动时会出现值错乱,如有需要可通过ViewPager的getCurrentItem()方法获取当前位置。
内容的提问来源于stack exchange,提问作者Mr Learning
相关产品推荐
相关产品推荐

