Android Java中draw()触发isRecycled()空指针异常求助
嘿,我帮你揪出空指针异常的根源啦!咱们一步步拆解问题,再给你解决办法:
问题根源分析
你的空指针异常完全是因为错误创建Activity实例导致的,具体看这里:
在PlayerShip的setBitmap方法里,你写了shipType = new MainActivity();——这是Android开发里的典型错误!
- Android的Activity实例不能手动
new出来,这种方式创建的Activity没有经过系统的生命周期初始化,它的avatar变量还是默认值0。 - 当你用
BitmapFactory.decodeResource(context.getResources(), 0)时,找不到对应的资源,返回的Bitmap就是null。最后在TDView的draw方法里调用canvas.drawBitmap(player.getBitmap(), ...)时,就触发了空指针(因为null的Bitmap会触发系统内部的isRecycled()调用,自然报错)。
为什么必须用Intent传递avatar?
当然需要!因为MainActivity和GameActivity是两个独立的组件,它们的实例由系统分别创建,MainActivity里的avatar变量无法直接被GameActivity或PlayerShip访问。Intent就是Android组件之间传递数据的标准方式,能安全把你选中的头像资源ID从MainActivity传到GameActivity,再传给PlayerShip。
具体修改步骤
1. 修改MainActivity,通过Intent传递avatar
private void startGame() { Intent i = new Intent(MainActivity.this, GameActivity.class); // 把选中的头像资源ID存入Intent i.putExtra("SELECTED_AVATAR", avatar); startActivity(i); finish(); }
2. 修改GameActivity,接收Intent参数并传给TDView
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 获取传递过来的头像ID,第二个参数是默认值(防止没传值的情况) int selectedAvatar = getIntent().getIntExtra("SELECTED_AVATAR", R.drawable.ship); gameView = new TDView(this, selectedAvatar); setContentView(gameView); }
3. 修改TDView的构造方法,接收头像ID并传给PlayerShip
private PlayerShip player; // ...其他变量保持不变 public TDView(Context context, int avatarResId) { super(context); ourHolder = getHolder(); paint = new Paint(); // 把头像ID传给PlayerShip player = new PlayerShip(context, avatarResId); }
4. 重构PlayerShip,去掉错误的Activity实例创建
public class PlayerShip { private Bitmap bitmap; private int x, y; private int speed = 0; // 修改构造方法,直接接收头像资源ID public PlayerShip(Context context, int avatarResId) { x = 50; y = 50; speed = 1; setBitmap(context, avatarResId); } public void update() { x++; } // 其他getter方法保持不变... // 修改setBitmap方法,直接用传递过来的资源ID解码 public void setBitmap(Context context, int avatarResId) { bitmap = BitmapFactory.decodeResource(context.getResources(), avatarResId); } }
额外注意事项
- 永远不要手动
newActivity实例,所有Activity必须通过Intent由系统启动,才能保证生命周期正常运行。 - 建议把Intent的key(比如
"SELECTED_AVATAR")定义成常量,避免拼写错误,比如在MainActivity里加public static final String EXTRA_AVATAR = "selected_avatar";,然后两边都用这个常量。 - 给
getIntExtra设置合理的默认值,能处理用户未选头像就启动游戏的边界情况。
内容的提问来源于stack exchange,提问作者Paris B. G.
相关产品推荐
相关产品推荐

