1

我正在使用 SurfaceView 开发绘画应用程序。我在我的应用程序中发现了一些问题:

1.当我接到电话或转到其他应用程序并返回我的应用程序时,我的应用程序出现运行时错误。

2.绘制时我收到闪烁效果,之后只有我得到颜色

3.我无法在 DrawingSurface.java 中将位图设置到画布中


//绘图活动.java

  import android.R.string;
    import android.app.Activity;`
    import android.app.AlertDialog;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.content.res.Configuration;
    import android.graphics.Bitmap;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.PixelFormat;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.view.LayoutInflater;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup.LayoutParams;
    import android.view.animation.Animation;
    import android.view.animation.AnimationUtils;
    import android.widget.Button;
    import android.widget.RelativeLayout;
    import android.widget.Toast;

    import com.almondmendoza.Main;
    import com.almondmendoza.R;
    import com.almondmendoza.drawings.brush.Brush;
    import com.almondmendoza.drawings.brush.CircleBrush;
    import com.almondmendoza.drawings.brush.PenBrush;

    import java.io.File;
    import java.io.FileOutputStream;



    public class DrawingActivity extends Activity implements View.OnTouchListener{
        private DrawingSurface drawingSurface;
        private DrawingPath currentDrawingPath;
        private Paint currentPaint;

        private Button redbtn,bluebtn,greenbtn,undobtn,redobtn,savebtn,pathbtn,circlebtn;


        private Brush currentBrush;

        private File APP_FILE_PATH = new File("/sdcard/TutorialForAndroidDrawings");

        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.drawing_activity);


            final LayoutInflater  inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);

               //RelativeLayout b = (RelativeLayout)inflater.inflate(R.layout.drawing_activity,
              //      null);


          /*  LayoutParams layoutParamsControl1 = new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);
            this.addContentView(b, layoutParamsControl1);*/


            setCurrentPaint();
            currentBrush = new PenBrush();

            drawingSurface = (DrawingSurface) findViewById(R.id.drawingSurface);

            drawingSurface.setOnTouchListener(this);
           drawingSurface.previewPath = new DrawingPath();
           drawingSurface.previewPath.path = new Path();
            drawingSurface.previewPath.paint = getPreviewPaint();


            redbtn = (Button) findViewById(R.id.colorRedBtn);
            redbtn.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
             currentPaint = new Paint();
                 currentPaint.setDither(true);
                  currentPaint.setColor(0xFFFF0000);
                  currentPaint.setStyle(Paint.Style.STROKE);
                  currentPaint.setAntiAlias(true);
                 currentPaint.setStrokeJoin(Paint.Join.ROUND);
                  currentPaint.setStrokeCap(Paint.Cap.ROUND);
                  currentPaint.setStrokeWidth(3);
             }
            });
            greenbtn = (Button) findViewById(R.id.colorGreenBtn);

            greenbtn.setOnClickListener(new OnClickListener() {
              @Override
              public void onClick(View v) {
             currentPaint = new Paint();
                 currentPaint.setDither(true);

                 currentPaint.setColor(0xFF00FF00);
                 currentPaint.setAntiAlias(true);
                 currentPaint.setStyle(Paint.Style.STROKE);
                 currentPaint.setStrokeJoin(Paint.Join.ROUND);
                 currentPaint.setStrokeCap(Paint.Cap.ROUND);
                 currentPaint.setStrokeWidth(10);

              }
             });
            bluebtn = (Button) findViewById(R.id.colorBlueBtn);

            bluebtn.setOnClickListener(new OnClickListener() {
              @Override
              public void onClick(View v) {
               currentPaint = new Paint();
                  currentPaint.setDither(true);
                   currentPaint.setColor( 0xFF0000FF);
                 currentPaint.setStyle(Paint.Style.STROKE);
                  currentPaint.setStrokeJoin(Paint.Join.ROUND);
                 currentPaint.setStrokeCap(Paint.Cap.ROUND);
                  currentPaint.setStrokeWidth(3);

              }
             });
            undobtn = (Button) findViewById(R.id.undoBtn);
            undobtn.setOnClickListener(new OnClickListener() {
              @Override
              public void onClick(View v) {
             drawingSurface.undo();
                 if( drawingSurface.hasMoreUndo() == false ){
                     undobtn.setEnabled( false );
                 }
                 redobtn.setEnabled( true );
              }
             });
            redobtn = (Button) findViewById(R.id.redoBtn);
            redobtn.setOnClickListener(new OnClickListener() {
              @Override
              public void onClick(View v) {
             drawingSurface.redo();
                 if( drawingSurface.hasMoreRedo() == false ){
                     redobtn.setEnabled( false );
                 }

                 undobtn.setEnabled( true );
              }
             });
            savebtn = (Button) findViewById(R.id.saveBtn);
            savebtn.setOnClickListener(new OnClickListener() {
              @Override
              public void onClick(View v) {
             final Activity currentActivity  = DrawingActivity.this;
                 Handler saveHandler = new Handler(){
                     @Override
                     public void handleMessage(Message msg) {
                         final AlertDialog alertDialog = new AlertDialog.Builder(currentActivity).create();
                         alertDialog.setTitle("Saved 1");
                         alertDialog.setMessage("Your drawing had been saved :)");
                         alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                             public void onClick(DialogInterface dialog, int which) {
                                 return;
                             }
                         });
                         alertDialog.show();
                     }
                 } ;
               // new ExportBitmapToFile(DrawingActivity.this,saveHandler, drawingSurface.getBitmap()).execute();
              }
             });
            pathbtn = (Button) findViewById(R.id.pathBtn);
            pathbtn.setOnClickListener(new OnClickListener() {
              @Override
              public void onClick(View v) {
             currentBrush = new PenBrush();
              }
             });
            circlebtn = (Button) findViewById(R.id.circleBtn);
            circlebtn.setOnClickListener(new OnClickListener() {
              @Override
              public void onClick(View v) {
             currentBrush = new CircleBrush();
              }
             });


            redobtn.setEnabled(false);
            undobtn.setEnabled(false);
        }

        private void setCurrentPaint(){
            currentPaint = new Paint();
            currentPaint.setDither(true);
            currentPaint.setColor(0xFFFFFF00);
            currentPaint.setStyle(Paint.Style.STROKE);
            currentPaint.setAntiAlias(true);
            currentPaint.setStrokeJoin(Paint.Join.ROUND);
            currentPaint.setStrokeCap(Paint.Cap.ROUND);
            currentPaint.setStrokeWidth(3);

        }

      private Paint getPreviewPaint(){
            final Paint previewPaint = new Paint();
            previewPaint.setColor(Color.GREEN);
            previewPaint.setStyle(Paint.Style.STROKE);
            previewPaint.setAntiAlias(true);
            previewPaint.setStrokeJoin(Paint.Join.ROUND);
            previewPaint.setStrokeCap(Paint.Cap.ROUND);
            previewPaint.setStrokeWidth(10);
            return previewPaint;
        }
      @Override
      public void onConfigurationChanged(Configuration newConfig) {
          super.onConfigurationChanged(newConfig);

      }



        public boolean onTouch(View view, MotionEvent motionEvent) {
            if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
                drawingSurface.isDrawing = true;

                currentDrawingPath = new DrawingPath();
                currentDrawingPath.paint = currentPaint;
                currentDrawingPath.path = new Path();
                currentBrush.mouseDown(currentDrawingPath.path, motionEvent.getX(), motionEvent.getY());
                currentBrush.mouseDown(drawingSurface.previewPath.path, motionEvent.getX(), motionEvent.getY());


            }else if(motionEvent.getAction() == MotionEvent.ACTION_MOVE){
                drawingSurface.isDrawing = true;
                currentBrush.mouseMove( currentDrawingPath.path, motionEvent.getX(), motionEvent.getY() );
                currentBrush.mouseMove(drawingSurface.previewPath.path, motionEvent.getX(), motionEvent.getY());


            }else if(motionEvent.getAction() == MotionEvent.ACTION_UP){


                currentBrush.mouseUp(drawingSurface.previewPath.path, motionEvent.getX(), motionEvent.getY());
                drawingSurface.previewPath.path = new Path();
                drawingSurface.addDrawingPath(currentDrawingPath);

                currentBrush.mouseUp( currentDrawingPath.path, motionEvent.getX(), motionEvent.getY() );

                undobtn.setEnabled(true);
                redobtn.setEnabled(false);

            }

            return true;
        }


      /*  public void onClick(View view){
            switch (view.getId()){
                case R.id.colorRedBtn:
                    currentPaint = new Paint();
                    currentPaint.setDither(true);
                    currentPaint.setColor(0xFFFF0000);
                    currentPaint.setStyle(Paint.Style.STROKE);
                    currentPaint.setStrokeJoin(Paint.Join.ROUND);
                    currentPaint.setStrokeCap(Paint.Cap.ROUND);
                    currentPaint.setStrokeWidth(3);
                break;
                case R.id.colorBlueBtn:
                    currentPaint = new Paint();
                    currentPaint.setDither(true);
                    currentPaint.setColor(0xFF00FF00);
                    currentPaint.setStyle(Paint.Style.STROKE);
                    currentPaint.setStrokeJoin(Paint.Join.ROUND);
                    currentPaint.setStrokeCap(Paint.Cap.ROUND);
                    currentPaint.setStrokeWidth(3);
                break;
                case R.id.colorGreenBtn:
                    currentPaint = new Paint();
                    currentPaint.setDither(true);
                    currentPaint.setColor(0xFF0000FF);
                    currentPaint.setStyle(Paint.Style.STROKE);
                    currentPaint.setStrokeJoin(Paint.Join.ROUND);
                    currentPaint.setStrokeCap(Paint.Cap.ROUND);
                    currentPaint.setStrokeWidth(3);
                break;

                case R.id.undoBtn:
                    drawingSurface.undo();
                    if( drawingSurface.hasMoreUndo() == false ){
                        undoBtn.setEnabled( false );
                    }
                    redoBtn.setEnabled( true );
                break;

                case R.id.redoBtn:
                    drawingSurface.redo();
                    if( drawingSurface.hasMoreRedo() == false ){
                        redoBtn.setEnabled( false );
                    }

                    undoBtn.setEnabled( true );
                break;
                case R.id.saveBtn:
                    final Activity currentActivity  = this;
                    Handler saveHandler = new Handler(){
                        @Override
                        public void handleMessage(Message msg) {
                            final AlertDialog alertDialog = new AlertDialog.Builder(currentActivity).create();
                            alertDialog.setTitle("Saved 1");
                            alertDialog.setMessage("Your drawing had been saved :)");
                            alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int which) {
                                    return;
                                }
                            });
                            alertDialog.show();
                        }
                    } ;
                   new ExportBitmapToFile(this,saveHandler, drawingSurface.getBitmap()).execute();
                break;
                case R.id.circleBtn:
                    currentBrush = new CircleBrush();
                break;
                case R.id.pathBtn:
                    currentBrush = new PenBrush();
                break;
            }
        }*/

       //new ExportBitmapToFile(DrawingActivity.this,saveHandler, drawingSurface.getBitmap()).execute();

        /*private class ExportBitmapToFile extends AsyncTask<Intent,Void,Boolean> {
            private Context mContext;
            private Handler mHandler;
            private Bitmap nBitmap;

            public ExportBitmapToFile(Context context,Handler handler,Bitmap bitmap) {
                mContext = context;
                nBitmap = bitmap;
                mHandler = handler;
            }

            @Override
            protected Boolean doInBackground(Intent... arg0) {
                try {
                    if (!APP_FILE_PATH.exists()) {
                        APP_FILE_PATH.mkdirs();
                    }

                    final FileOutputStream out = new FileOutputStream(new File(APP_FILE_PATH + "/myAwesomeDrawing.png"));
                    nBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
                    out.flush();
                    out.close();
                    return true;
                }catch (Exception e) {
                    e.printStackTrace();
                }
                //mHandler.post(completeRunnable);
                return false;
            }


             @Override
           protected void onPostExecute(Boolean bool) {
                super.onPostExecute(bool);
                if ( bool ){
                    mHandler.sendEmptyMessage(1);
                }
            }
        }*/
    }

//DrawingSurface.java

 import android.R;
    import android.app.Activity;
    import android.content.Context;
    import android.content.res.Resources;
    import android.graphics.*;
    import android.os.Handler;
    import android.os.Message;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;


    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Iterator;
    import java.util.List;



    public class DrawingSurface extends SurfaceView implements SurfaceHolder.Callback {
        private Boolean _run;
        protected DrawThread thread;
        private Bitmap mBitmap;
        public boolean isDrawing = true;
        public DrawingPath previewPath;



        private CommandManager commandManager;

        public DrawingSurface(Context context, AttributeSet attrs) {
            super(context, attrs);




            getHolder().addCallback(this);


            commandManager = new CommandManager();
            thread = new DrawThread(getHolder());
        }

        private Handler previewDoneHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                isDrawing = false;
            }
        };




        class DrawThread extends  Thread{
            private SurfaceHolder mSurfaceHolder;


            public DrawThread(SurfaceHolder surfaceHolder){
                mSurfaceHolder = surfaceHolder;





            }

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


            @Override
            public void run() {
                Canvas canvas = null;
                while (_run){
                   if(isDrawing == true){
                        try{
                          canvas = mSurfaceHolder.lockCanvas(null);


                        if(mBitmap == null){


                         mBitmap =  Bitmap.createBitmap (1, 1, Bitmap.Config.ALPHA_8);
                            }
                          final Canvas c = new Canvas (mBitmap);


                        c.drawColor(0, PorterDuff.Mode.CLEAR);
                        canvas.drawColor(0, PorterDuff.Mode.CLEAR);




                        canvas.drawColor(Color.WHITE);


                          commandManager.executeAll(c,previewDoneHandler);
                          previewPath.draw(c);

                          canvas.drawBitmap (mBitmap, 0,  0,null);
                        } finally {
                            mSurfaceHolder.unlockCanvasAndPost(canvas);
                        }


                    }

                }

            }
        }


        public void addDrawingPath (DrawingPath drawingPath){
            commandManager.addCommand(drawingPath);
        }

        public boolean hasMoreRedo(){
            return commandManager.hasMoreRedo();
        }

        public void redo(){
            isDrawing = true;
            commandManager.redo();


        }

        public void undo(){
            isDrawing = true;
            commandManager.undo();
        }

        public boolean hasMoreUndo(){
            return commandManager.hasMoreUndo();
        }

        public Bitmap getBitmap(){
            return mBitmap;
        }


        public void surfaceChanged(SurfaceHolder holder, int format, int width,  int height) {
            // TODO Auto-generated method stub
            mBitmap =  Bitmap.createBitmap (width, height, Bitmap.Config.ARGB_8888);;
        }


        public void surfaceCreated(SurfaceHolder holder) {
            // TODO Auto-generated method stub
            thread.setRunning(true);
            thread.start();
        }





        public void surfaceDestroyed(SurfaceHolder holder) {
            // TODO Auto-generated method stub
            boolean retry = true;
            thread.setRunning(false);
            while (retry) {
                try {
                    thread.join();
                    retry = false;
                } catch (InterruptedException e) {
                    // we will try it again and again...
                }
            }
        }



        }

//Logcat 报告

 ): java.lang.IllegalThreadStateException: Thread already 
       at java.lang.Thread.start
       com.almondmendoza.drawings.DrawingSurface.surfaceCreated(DrawingSurface.java:154)
android.view.SurfaceView.updateWindow(SurfaceView.java:552)
android.view.SurfaceView.onWindowVisibilityChanged
android.view.View.dispatchWindowVisibilityChanged
android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
android.view.ViewRoot.performTraversals(ViewRoot.java:788)
android.view.ViewRoot.handleMessage(ViewRoot.java:1865)
android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
at dalvik.system.NativeStart.main(Native Method)

//错误在以下方法的 DrawingSurface.java 类中显示

public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        thread.setRunning(true);
        thread.start();
    }
4

0 回答 0