You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
    }
}
额外注意事项
  • 永远不要手动new Activity实例,所有Activity必须通过Intent由系统启动,才能保证生命周期正常运行。
  • 建议把Intent的key(比如"SELECTED_AVATAR")定义成常量,避免拼写错误,比如在MainActivity里加public static final String EXTRA_AVATAR = "selected_avatar";,然后两边都用这个常量。
  • 给getIntExtra设置合理的默认值,能处理用户未选头像就启动游戏的边界情况。

内容的提问来源于stack exchange,提问作者Paris B. G.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:43:49