1

I am new to android Surfaceview implementation. I am developing RDP client application in android3.0. I getting the image stream from socket, drawing this image to surface using Surfaceview and Thread.

The sample code of surface view:

class mySurfaceView extends SurfaceView implements SurfaceHolder.Callback 
{
      private TutorialThread _thread;
      Canvas c=null;

      public mySurfaceView(Context context) 
        {
            super(context);

            getHolder().addCallback(this);
            _thread = new TutorialThread(getHolder(), this);            

            matrix= new Matrix();
                    m = new float[9];
                        paint = new Paint();
        }

               public void surfaceCreated(SurfaceHolder arg0) {
            //setWillNotDraw(false) ;
            Log.e("surfaceCreated","surfaceCreated");
              if(_thread==null  ){
                  Log.e("_thread.created","thread created");
                  _thread = new TutorialThread(getHolder(),this); 
                  _thread.setRunning(true);
                        _thread.start();
             // <-- added fix
                 }else {
                     Log.e("_thread.getState()",_thread.getState()+"");
             _thread.setRunning(true);  //original code
             _thread.start();           //original code
                 }



        }

        public void surfaceDestroyed(SurfaceHolder arg0) {
            Log.e("surfaceDestroyed","surfaceDestroyed");

            boolean retry = true;
            _thread.setRunning(false);
            while (retry) {
                try {
                    _thread.join();
                    retry = false;
                } catch (InterruptedException e) {
                }
            }
        } 
               public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
                int arg3) {


        }


       class TutorialThread extends Thread 
    {
        private SurfaceHolder _surfaceHolder;
        private mySurfaceView _panel;
        private boolean _run = false;
        private InputStream is;
        private Socket socket;
        Bitmap resizeBmp;


        public TutorialThread(SurfaceHolder surfaceHolder,mySurfaceView panel) 
        {
            Log.e("TutorialThread","TutorialThread-->Constructor");
            _surfaceHolder = surfaceHolder;
            _panel = panel;
        }

        public void setRunning(boolean run) {
            _run = run;
        }

        @Override
        public void run() 
        {
            Log.e("TutorialThread","TutorialThread-->run()");

                try 
                {

                    socket = new Socket("172.19.1.144", 4444);
                    is = socket.getInputStream();
                    DataInputStream inputputStream = new DataInputStream(is);

                    //long time = System.currentTimeMillis();                   

                    int i=0;

                    while (socket.isConnected() ) 
                    {

                        Log.e("tutorial thread","While running");
                        c = null;                   

                        i++;
                        if(i==10){
                            System.gc();
                            i=0;
                        }
                        Log.e("BEFORE","BEFORE");
                        synchronized (_surfaceHolder) 
                        {
                            Log.e("AFTER","AFTER");
                            ByteBuffer inputHeaderBuffer = ByteBuffer.allocate(20);
                            inputHeaderBuffer.order(ByteOrder.LITTLE_ENDIAN);
                            inputputStream.readFully(inputHeaderBuffer.array());
                            SurfaceViewPinchZoom.serverWidth=inputHeaderBuffer.getInt();
                            SurfaceViewPinchZoom.serverHeight=inputHeaderBuffer.getInt();
                            //Log.e("serverWidth","serverWidth   "+ SurfaceViewPinchZoom.serverWidth+"serverHeight===="+SurfaceViewPinchZoom.serverHeight);
                            SurfaceViewPinchZoom.left=inputHeaderBuffer.getInt();
                            SurfaceViewPinchZoom.top=inputHeaderBuffer.getInt();

                            int dataLength = inputHeaderBuffer.getInt();
                            ByteBuffer imageDataCompress = ByteBuffer.allocate(dataLength);
                            imageDataCompress.order(ByteOrder.LITTLE_ENDIAN);
                            inputputStream.readFully(imageDataCompress.array());
                            byte[] imagedata = new byte[imageDataCompress.remaining()];
                            imageDataCompress.get(imagedata);

                            //Decompress the image
                            //Log.e("imagedata.length::::::::::",imagedata.length+"");

                                // Create the decompressor and give it the data to compress
                                Inflater decompressor = new Inflater();
                                decompressor.setInput(imagedata);

                                // Create an expandable byte array to hold the decompressed data
                                ByteArrayOutputStream bos = new ByteArrayOutputStream(imagedata.length);

                                // Decompress the data
                                byte[] buf = new byte[1024];
                                while (!decompressor.finished()) {
                                    try {
                                        int count = decompressor.inflate(buf);
                                        bos.write(buf, 0, count);
                                    } catch (DataFormatException e) {
                                    }
                                }
                                try {
                                    bos.close();
                                } catch (IOException e) {
                                }

                                // Get the decompressed data
                                byte[] decompressedData = bos.toByteArray();

                            /
                            BitmapFactory.Options options=new BitmapFactory.Options();
                            options.inJustDecodeBounds=true;

                        //  Log.e("decompressedData.length::::::::::",decompressedData.length+"");
                            /*SurfaceViewPinchZoom.*/bmp = BitmapFactory.decodeByteArray(decompressedData, 0,decompressedData.length,options);
                            options.inDither=true;
                            /*scaleX=(float)screen_width/bmp.getWidth();
                            scaleY=(float)screen_height/bmp.getHeight();
                            matrix.setScale(scaleX, scaleY);*/
                             // Calculate inSampleSize
                            options.inSampleSize = calculateInSampleSize(options, screen_width, screen_height);

                            // Decode bitmap with inSampleSize set
                            options.inJustDecodeBounds = false;

                            /*SurfaceViewPinchZoom.*/bmp= BitmapFactory.decodeByteArray(decompressedData, 0,decompressedData.length,options);


                            bmp=BitmapFactory.decodeByteArray(decompressedData, 0,decompressedData.length,options);

                                c  = _surfaceHolder.lockCanvas();
                                c.drawBitmap(bmp, matrix, paint);

                                //draw(c);
                                //postInvalidate();
                                onDraw(c);


                            inputHeaderBuffer.clear();
                            imageDataCompress.clear();
                            inputHeaderBuffer = null;
                            imageDataCompress = null;
                            imagedata = null;



                        }
                        if (c != null)
                        {
                            _surfaceHolder.unlockCanvasAndPost(c);
                        }

                    }


                } 

                catch (ArrayIndexOutOfBoundsException ae) 
                {

                    ae.printStackTrace();

                } 
                catch (Exception e) 
                {

                    e.printStackTrace();


                }
                finally {
                    if (c != null) {
                        _surfaceHolder.unlockCanvasAndPost(c);
                    }
                }
            }

        private int calculateInSampleSize(Options options, int screen_width,
                int screen_height) {
             // Raw height and width of image
            final int height = options.outHeight;
            final int width = options.outWidth;
            int inSampleSize = 1;

            if (height > screen_height || width > screen_width) {
                if (width > height) {
                    inSampleSize = Math.round((float)height / (float)screen_height);
                } else {
                    inSampleSize = Math.round((float)width / (float)screen_width);
                }
            }
            return inSampleSize;

        }
}
}

The problems are

1) if I press home button then surfaceDestroyed() is called and thread is terminated.

But I need to continue the Thread and update the images(input stream from socket) after open the application from home button is pressed.

2) if I call the activity on doubletap event as child activity, surfaceDestroyed() is called and Thread is terminated.

Where I need to continue the images display after returning from child activity.

In both the case I am getting exception as java.lang.IllegalThreadStateException: Thread already started.

Could please help how to run the same thread without terminating on home button is pressed or another child activity is called?

Thanks & Regards Yamini

Miral Dhokiya
  • 1,720
  • 13
  • 26
mini
  • 855
  • 4
  • 15
  • 22
  • I am not able to get your complete question. But I think `service` is the thing you should look for. As Service is design for long background works. – Mohsin Naeem Dec 05 '12 at 17:31
  • can we work service with surfaceview? – mini Dec 06 '12 at 05:07
  • My question is, if I relaunch the application after home button is pressed, I need to continue previously created thread object. Now if I pressed home button then surfaceDestroyed() is called and Thread is termiated. relaunching the application then surfaceCreated() is called and new Thread object is created, where the thread status is "Terminated". So Could please help me how do we continue with previously created thread object? – mini Dec 06 '12 at 05:09

0 Answers0