2D游戏中Bitmap设置Rect图片遇空指针,如何正确使用decodeResource?
嘿,这个空指针错误我太熟悉了!你碰到的Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference,本质就是你代码里的context对象是null,导致调用getResources()时直接崩溃了。咱们来一步步修复:
1. 先确保Context被正确持有和初始化
首先,你得保证使用的Context是有效的、非空的。比如在自定义的SurfaceView或者View里,一定要在构造函数中把传入的Context保存下来,而不是随便用一个可能为空的Context:
public class GameRenderView extends SurfaceView { private Context mValidContext; // 保存有效的Context引用 public GameRenderView(Context context) { super(context); mValidContext = context; // 在这里初始化,确保Context非空 initGameResources(); // 提前加载资源 } }
如果是在Activity里调用,直接用this(Activity本身就是Context),但要注意不要在Activity销毁后还持有这个引用。
2. 提前预加载Bitmap,不要在draw方法里实时解码
你现在的代码是在canvas.drawBitmap()里实时调用BitmapFactory.decodeResource(),这不仅会导致频繁的IO操作拖慢渲染速度,还容易因为Context临时为空出问题。建议在View初始化或者onAttachedToWindow()阶段就加载好Bitmap:
private Bitmap mAsteroidBitmap; private void initGameResources() { // 用之前保存的有效Context加载资源 mAsteroidBitmap = BitmapFactory.decodeResource(mValidContext.getResources(), R.drawable.asteroid); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 绘制前先做非空判断,防止Bitmap加载失败或者rectangle为空 if (mAsteroidBitmap != null && rectangle != null) { canvas.drawBitmap(mAsteroidBitmap, null, rectangle, paint); } }
加个空判断能避免很多意外崩溃,比如资源加载失败的情况。
3. 避免使用已销毁的Context
如果你的Context来自Activity或者Fragment,一定要注意它们的生命周期:
- 不要在Activity的
onDestroy()之后还持有它的Context - 用Fragment的
getActivity()时,先判断getActivity() != null再使用 - 如果不需要和特定UI绑定,优先用Application Context(生命周期更长,不容易被回收):
Context appContext = mValidContext.getApplicationContext(); mAsteroidBitmap = BitmapFactory.decodeResource(appContext.getResources(), R.drawable.asteroid);
4. 额外检查:资源ID是否正确
虽然这个错误是Context为空,但也顺便确认下R.drawable.asteroid是不是存在,有没有拼写错误,或者资源有没有被正确打包到APK里——有时候资源找不到也会间接引发奇怪的问题。
按照这些步骤来,应该就能解决你的空指针问题啦!
内容的提问来源于stack exchange,提问作者popi

