好吧,问题是我在xml布局中使用了SurfaceView.
你打电话的那一刻:setContentView(your_layout) – > XML文件被夸大了.
这意味着,SurfaceView也会膨胀.这再次意味着调用SurfaceView onSurfaceCreated方法,触发打开相机等.
因此,整个过程需要一段时间,因此,您之前的Activity(例如,使用SurfaceView启动Activity的那个)似乎没有响应……
我在BG线程中创建CameraView的解决方案解决了无响应问题.但未能在SurfaceView中显示Camera输出.
解决方案是从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(只是一个启动新活动的按钮)
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">
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
这是第二个活动(包含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)
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">
android:id="@+id/header"
android:layout_width="fill_parent" android:layout_height="wrap_content">
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Explanation Txt">
android:id="@+id/footer"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Explanation Txt">
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">
最后,为了完成答案,这里是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;
}
}
}