【问题标题】:Android SurfaceView IllegalArgumentException lockCanvasAndroid SurfaceView IllegalArgumentException lockCanvas
【发布时间】:2015-12-16 09:19:30
【问题描述】:

我正在制作SurfaceView 的视频。 我的目标是获得正在运行的视频的循环位图。 这是我的自定义实现:

private static final String TAG = "XXX";
private Activity activity;
private SurfaceHolder mSurface;
private MediaPlayer mMediaPlayer;
private SurfaceHolder mActiveSurface;
public ImageView imageView;

boolean locked, locked1;
private boolean isCreated;


public AlphaSurfaceView(Context context,Activity activity) {
    super(context);
    getHolder().addCallback(this);
    setWillNotDraw(false);
    this.activity = activity;
}

public AlphaSurfaceView(Context context, AttributeSet attrs) {
    super(context, attrs);

}

public AlphaSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}


@Override
public void draw(Canvas canvas) {
    super.draw(canvas);
}

@Override
public void onDraw(Canvas canvas) {
    //super.onDraw(canvas);
    if(isCreated){
        if(getHolder() != null && getHolder().getSurface().isValid()){
            Canvas c = null;
            try {
                if(!locked){
                    try {
                        c = getHolder().lockCanvas();
                        locked = true;
                    }catch (IllegalArgumentException e){
                        e.printStackTrace();
                        locked = false;
                    }
                    BitmapDrawable bdrawable = new BitmapDrawable();
                    bdrawable.draw(c);
                }

            }catch (Exception e){
                e.printStackTrace();
                locked = false;
            }finally {
                if(c != null && locked){
                    getHolder().unlockCanvasAndPost(c);
                    locked = false;
                }
            }
        }
    }else{
        super.onDraw(canvas);
    }
    invalidate();

}



@Override
public void surfaceCreated(SurfaceHolder holder) {
    mSurface = holder;
    mMediaPlayer = MediaPlayer.create(getContext(), Uri.parse("XX"), mSurface);
    mActiveSurface = mSurface;
    try {
        mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mMediaPlayer.start();
                mMediaPlayer.setLooping(true);
            }
        });

    } catch (Exception e) {
        e.printStackTrace();
    }
    this.isCreated = true;

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    Log.d(TAG, "surfacechanged");

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    mMediaPlayer.stop();
}

@Override
protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    mMediaPlayer.stop();
}

问题是 lockCanvas() 方法发生了 IllegalArgumentException。

我尝试了很多可能性:

  • 添加一些布尔值(锁定和创建表面视图)
  • 测试表面是否有效
  • 甚至在 Manifest 的 xml 中的目标活动中添加exported="true"

顺便说一下,第一个想法是使用getDrawingCache(),但即使我添加了setCacheEnabled(true),返回也是null。

那么如何解决这个异常或者使用其他方式获取每一帧呢?​​

谢谢!

【问题讨论】:

    标签: android android-canvas surfaceview android-bitmap illegalargumentexception


    【解决方案1】:

    您不能在 Surface 上绘图向其发送视频。 Surface 是生产者-消费者对的生产者端,一次只能有一个生产者。

    让 Canvas 与 SurfaceView Surface 重叠的最简单方法是在 SurfaceView 的 View 部分上进行绘制。将视频发送到 Surface,并使用onDraw()(如custom view)在视图上绘图。

    请记住,Surface 是位于 View UI 层后面的单独层,因此您需要在具有透明度的 View 上绘图才能看到 Surface 内容。

    另一种方法是使用多个重叠的 SurfaceView,但这种方法效率较低且受到更多限制。在Grafika's multi-surface test Activity 中可以找到三个重叠 Surface 的示例。

    【讨论】:

      【解决方案2】:
      surfaceHolder.addCallback(new SurfaceHolder.Callback() {
              @Override
              public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
                  Log.e("video","surfaceChanged");
              }
              @Override
              public void surfaceCreated(SurfaceHolder arg0) {
                  Log.e("video","surfaceCreated");
                  mediaPlayer.setDisplay(surfaceHolder);
              }
              @Override
              public void surfaceDestroyed(SurfaceHolder arg0) {
                  Log.e("video","surfaceDestroyed");
                  if (mediaPlayer != null) mediaPlayer.release();
              }
          });
      

      这应该会有所帮助。 让 MediaPlayer 进行绘图。

      【讨论】:

        猜你喜欢
        • 2013-10-30
        • 2023-03-24
        • 2012-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-08
        相关资源
        最近更新 更多