在SurfaceView加载Camera Preview时显示我的布局

我有一个简单的屏幕,一个开始button。 当按下“开始”button时,我想要使用SurfaceView转到新的屏幕以显示相机。

一切工作正常,但相机需要一段时间来加载,这给了我一个黑屏。 我想要加载新的布局。 而且,它已经加载后启动相机…

因此,我做的所有相机加载在后台线程,但仍然,我得到一个黑屏…这是我的布局:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:id="@+id/RelativeLayout1" xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/blue_bg"> <SurfaceView android:id="@+id/surface_camera" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginLeft="25dp" android:layout_marginRight="25dp" android:layout_below="@id/scan_header" android:layout_above="@id/scan_footer"> </SurfaceView> </RelativeLayout> 

这里是我的活动,加载新视图的方法:

 private void setContent() { setContentView(R.layout.scan) Thread t = new Thread() { public void run() { final SurfaceView mSurfaceView = (SurfaceView)findViewById(R.id.surface_camera); final SurfaceHolder mSurfaceHolder = mSurfaceView.getHolder(); try { cameraView = new CameraView(); mSurfaceHolder.addCallback(cameraView); cameraView.setPictureListener(SunpluggedActivity.this); mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } catch(Exception e) { Log.d(TAG, "Another exception"); e.printStackTrace(); } } }; t.start(); } 

怎么来,新的布局没有显示,直到线程完成加载相机?

编辑:我已经尝试Thread.sleep(200)内的线程睡觉一段时间…当我这样做,新的布局显示,但相机永远不会启动…

Solutions Collecting From Web of "在SurfaceView加载Camera Preview时显示我的布局"

好吧,问题是我在xml布局中使用了我的SurfaceView。 你调用的时候:setContentView(your_layout) – > XML文件被夸大了。 这意味着,SurfaceView也被夸大了。 这又意味着SurfaceView onSurfaceCreated方法被调用,这触发打开相机等。

所以,这整个过程需要一段时间,因此,您以前的活动(例如,使用SurfaceView启动活动的活动)似乎没有响应…

我在BG线程中创buildCameraView的解决scheme解决了无法响应的问题。 但未能在SurfaceView中显示相机输出。

解决的办法是从你的XML中删除你的SurfaceView。 这会立即开始你的活动(因为SurfaceView&Camera没有实例化)。 加载新的“活动”布局后,可以通过编程将新的SurfaceView添加到屏幕上。 当然,这也需要花费时间,但是您的UI会快速切换到新的活动,并且可以在SurfaceView和Camera加载的同时显示加载器!

所以:从XML中删除SURFACEVIEW – >按程序添加:启动活动:

 public class Launch extends Activity implements OnClickListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btn = (Button)findViewById(R.id.button1); btn.setOnClickListener(this); } @Override public void onClick(View v) { Intent intent = new Intent(Launch.this, SurfaceTestActivity.class); startActivity(intent); } } 

Main.xml(只是一个button来启动新的活动)

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:id="@+id/RelativeLayout1" xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ff6600"> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> </RelativeLayout> 

这是第二个活动(其中包含SurfaceView)

 public class SurfaceTestActivity extends Activity { private Context mContext; private CameraView cameraView; private Handler mHandler = new Handler(); private final Runnable mLoadCamera = new Runnable() { public void run() { startCamera(); } }; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContent(); mContext = getApplicationContext(); } private void startCamera() { RelativeLayout rl = (RelativeLayout)findViewById(R.id.surface_camera); SurfaceView surfaceView = new SurfaceView(mContext); final SurfaceHolder mSurfaceHolder = surfaceView.getHolder(); try { cameraView = new CameraView(); mSurfaceHolder.addCallback(cameraView); mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } catch(Exception e) { Log.d("debug", "Another exception"); e.printStackTrace(); } if(rl != null && surfaceView != null) rl.addView(surfaceView); } private void setContent() { setContentView(R.layout.scan); // Post the Runnable with a Slight delay -> than your layout will be // shown. Without the delay -> your UI will feel inresponsive mHandler.postDelayed(mLoadCamera, 100); } } 

这里是第二个Activity的布局(没有SURFACEVIEW)

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:id="@+id/RelativeLayout1" xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ff6600"> <RelativeLayout android:id="@+id/header" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Explanation Txt"></TextView> </RelativeLayout> <RelativeLayout android:id="@+id/footer" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Explanation Txt"></TextView> </RelativeLayout> <RelativeLayout android:id="@+id/surface_camera" android:layout_width="fill_parent" android:layout_height="match_parent" android:layout_above="@+id/footer" android:layout_below="@+id/header" android:background="#ff0066"> </RelativeLayout> </RelativeLayout> 

最后,要完成答案,下面是CameraView()的代码。 打开相机和显示内容真的只是一个简单的实现:

 public class CameraView implements SurfaceHolder.Callback{ // Variables private Camera mCamera = null; private boolean mPreviewRunning = false; private boolean mProcessing = false; private int mWidth = 0; private int mHeight = 0; @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if(mPreviewRunning ) { mCamera.stopPreview(); } // Store width and height mWidth = width; mHeight = height; // Set camera parameters Camera.Parameters p = mCamera.getParameters(); mCamera.setParameters(p); if(android.os.Build.VERSION.SDK_INT >= 8) { // If API >= 8 -> rotate display... mCamera.setDisplayOrientation(90); } try { mCamera.setPreviewDisplay(holder); } catch(IOException e) { e.printStackTrace(); } mCamera.startPreview(); mPreviewRunning = true; } @Override public void surfaceCreated(final SurfaceHolder holder) { try { mCamera = Camera.open(); mCamera.setPreviewDisplay(holder); } catch (IOException e) { mCamera.release(); mCamera = null; e.printStackTrace(); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { if(mCamera != null) { mCamera.setPreviewCallback(null); mCamera.stopPreview(); mCamera.setPreviewCallback(null); mPreviewRunning = false; mCamera.release(); mCamera = null; } } }