如果在按下主页按钮时调用surfaceDestroyed(),则线程将运行

时间:2012-12-05 13:06:38

标签: android multithreading surfaceview rdp surfaceholder

我是Android Surfaceview实现的新手。我在android3.0中开发RDP客户端应用程序。我从套接字获取图像流,使用Surfaceview和Thread将此图像绘制到表面。

表面视图的示例代码:

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;

        }
}
}

问题是

1)如果按主页按钮,则会调用surfaceDestroyed()thread 已终止

但是我需要继续线程并在按下主页按钮后打开应用程序来更新图像(来自套接字的输入流)。

2)如果我将doubletap活动中的活动称为儿童活动,则会调用surfaceDestroyed()Thread 已终止

从儿童活动返回后,我需要继续显示图像。

在这两种情况下,我都会因java.lang.IllegalThreadStateException: 线程已经开始而异常

可以请求帮助如何运行相同的线程而不终止主页按钮或调用其他子活动?

谢谢&amp;问候 雅米妮(Yamini)

0 个答案:

没有答案