我想开发一个用于将流视频从客户端发送到服务器的应用程序。我的客户端应用程序有一些问题:当我尝试在日志猫的客户端线程中写入从摄像机捕获的图像时,会抛出此错误:
err: java.lang.NullPointerException
err: ClientThread.doInBackground(ClientThread.java:38)
err: at clientcamerasource.ClientThread.doInBackground(ClientThread.java:12)
err: at android.os.AsyncTask$2.call(AsyncTask.java:288)
err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
err: at java.lang.Thread.run(Thread.java:841)
通常找不到在mainActivity中定义的mPreview(MyCameraView的对象)。这是MainActivity:
public class MainActivity extends AppCompatActivity {
private Camera mCamera;
public MyCameraView mPreview;
public TextView serverStatus;
public static String SERVERIP = "192.168.1.9";
private Handler handler = new Handler();
public static final int SERVERPORT = 8080;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCamera = getCameraInstance();
mPreview = new MyCameraView(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
ClientThread myClient = new ClientThread(SERVERIP,SERVERPORT,mPreview,handler);
myClient.execute();
}
public static Camera getCameraInstance()
{
Camera c=null;
try{
c=Camera.open(1);
}catch(Exception e){
e.printStackTrace();
}
return c;
}
}
这是MyCameraView类,用于在视图上添加摄像机流:
public class MyCameraView extends SurfaceView implements SurfaceHolder.Callback,Camera.PreviewCallback{
private SurfaceHolder mHolder;
private Camera mCamera;
private int width;
private int height;
public ByteArrayOutputStream mFrameBuffer;
private Context con;
/**
* Constructor of the MyCameraView
* @param context
* @param camera
*/
public MyCameraView(Context context,Camera camera){
super(context);
con=context;
mCamera=camera;
mHolder=getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
/**
* set preview to the camera
* @param holder
*/
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* surface destroyed function
* @param holder
*/
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera=null;
}
/**
* surface changed function
* @param holder
* @param format
* @param w
* @param h
*/
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
try{
mCamera.stopPreview();
} catch (Exception e){
e.printStackTrace();
}
try{
//Configration Camera Parameter(full-size)
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(320,240);
this.width=parameters.getPreviewSize().width;
this.height=parameters.getPreviewSize().height;
parameters.setPreviewFormat(ImageFormat.NV21);
mCamera.setParameters(parameters);
// mCamera.setDisplayOrientation(90);
mCamera.setPreviewCallback(this);
mCamera.startPreview();
}catch(Exception e){
e.printStackTrace();
}
}
/**
* frame call back function
* @param data
* @param camera
*/
public void onPreviewFrame(byte[] data,Camera camera){
try{
//convert YuvImage(NV21) to JPEG Image data
YuvImage yuvimage=new YuvImage(data,ImageFormat.NV21,this.width,this.height,null);
System.out.println("WidthandHeight"+yuvimage.getHeight()+"::"+yuvimage.getWidth());
ByteArrayOutputStream baos=new ByteArrayOutputStream();
yuvimage.compressToJpeg(new Rect(0,0,this.width,this.height),100,baos);
mFrameBuffer = baos;
}catch(Exception e){
Log.d("parse","error");
}
}
}
这是客户端线程类:
public class ClientThread extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
MyCameraView myPreview;
private Handler mHandler;
Socket socket;
ClientThread(String addr, int port, MyCameraView myPreview, Handler handler) {
dstAddress = addr;
dstPort = port;
mHandler = handler;
this.myPreview = myPreview;
}
@Override
protected Void doInBackground(Void... arg0) {
try {
socket = new Socket(dstAddress, dstPort);
try {
System.out.println("Socket creato");
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeInt(4);
dos.writeUTF("#@@#");
dos.writeInt(myPreview.mFrameBuffer.size());
dos.writeUTF("-@@-");
dos.flush();
System.out.println("SIZE: " + myPreview.mFrameBuffer.size());
dos.write(myPreview.mFrameBuffer.toByteArray());
dos.flush();
Thread.sleep(1000 / 15);
} catch (Exception e2) {
e2.printStackTrace();
}
} catch (Exception e) {
Log.d("ServerThread", "run: erro");
}finally
{
//Closing the socket
try
{
socket.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
return null;
}
}
为什么我的程序在客户端线程中找不到mPreview对象?