3

我的视图是一堆普通的小部件和一个表面视图。我不知道为什么在我得到surfaceholderSurfaceView 并getSurface()在持有人上再次使用后,我总是会返回 null。

这是我的示例代码:

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.view);
    }

    @Override
    public void onResume() {
        super.onResume();
        surface = (SurfaceView) findViewById(R.id.surfaceView);
        this.holder = surface.getHolder();

         if (holder.getSurface().isValid()){  // get surface again
             Log.i("Notice","Surface holder is valid");
         }
         else
             Log.i("Notice","Surface holder ISNOT valid");  //Always receive this
        }

当我看到 Android 文档的getSurface()方法时。它是这样说的:

直接访问表面对象。Surface 可能并不总是可用——例如,当使用 SurfaceView 时,在视图附加到窗口管理器并执行布局以确定 Surface 的尺寸和屏幕位置之前,不会创建持有者的 Surface。因此,您通常需要实现 Callback.surfaceCreated 以了解 Surface 何时可用。

我不太了解这一点,但我知道我错过了一些东西。请为我解释一下,并告诉我Callback.surfaceCreated手段,以及如何实施?

谢谢 :)

4

2 回答 2

13

您正在尝试使用尚不可用的表面。没关系,它在您的Activity.onCreateorActivity.onResume方法中不可用,因为实际上表面放置在您的 Activity 窗口后面的单独窗口中并且有自己的生命周期。您需要实现SurfaceHolder.Callback以接收有关Surface可用性的事件并从单独的线程进行绘图。查看 Android SDK 示例文件夹中的 LunarLander 项目,那里展示了如何正确使用 SurfaceView。

您的回调将如下所示:

public class MyCallback implements SurfaceHolder.Callback {
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, 
        int width, int height) {    
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // you need to start your drawing thread here
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {  
        // and here you need to stop it
    }
}

并且您需要将此回调设置为 SurfaceHolder:

surface.getHolder().addCallback(new MyCallback());
于 2012-07-15T11:45:15.617 回答
0

我找到了解决方案,这对我有用,感染错误在于选择正确的尺寸,因此在使用 MediaRecorder.setVideoSize() 时使用此方法选择最佳尺寸

private static Size chooseOptimalSize(Size[] choices, int width, int height) {
        Size bigEnough = null;
        int minAreaDiff = Integer.MAX_VALUE;
        for (Size option : choices) {
            int diff = (width*height)-(option.getWidth()*option.getHeight()) ;
            if (diff >=0 && diff < minAreaDiff &&
                    option.getWidth() <= width &&
                    option.getHeight() <= height) {
                minAreaDiff = diff;
                bigEnough = option;
            }
        }
        if (bigEnough != null) {
            return bigEnough;
        } else {
            Arrays.sort(choices,new CompareSizeByArea());
            return choices[0];
        }

    }
于 2019-01-21T17:28:23.150 回答