// ////////////////////////////////////////////////////////////////////////////
 // // Drawing Thread Inner Class
 // //////////////////////////////////////////////
 // ////////////////////////////////////////////////////////////////////////////
 class DrawThread extends Thread {
  boolean bExit;
  SurfaceHolder holder;
  DrawThread(SurfaceHolder Holder) {
   holder = Holder;
   bExit = false;
  }
  @Override
  public void run() {
//   Log.d("FLOW", "Thread, run");
   while (!Thread.currentThread().isInterrupted()) {
    Canvas c = null;
    try {
     c = holder.lockCanvas(null);
     synchronized (holder) {
      doDraw(c);
     }
     Thread.sleep(50);
    } catch (InterruptedException e) {
     e.printStackTrace();
    } finally {
     if (c != null) {
      holder.unlockCanvasAndPost(c);
     }
    }
   }
  }
  private void doDraw(final Canvas cv) throws NullPointerException {
   long posX = 0, posY = 0;
   byte flag;
   
   final Paint paint = new Paint();
   paint.setAntiAlias(true);
   cv.drawColor(Color.TRANSPARENT, Mode.CLEAR);
   
   // draw if current positions are updated
   for( int i=0 ; i<9 ; i++ ){
    if( drawTable[i].iIndex != -1 ){
     if( drawTable[i].bShown ){
      posX = (long)(0.01 * drawTable[i].dCurProg * (Center.x-drawTable[i].Origin.x)) + drawTable[i].Origin.x;
//      Log.d("FLOW", "[doDraw] i="+i+"  prog:" + drawTable[i].dCurProg + 
//        "Center.x:" + Center.x + "Origin.x:" + drawTable[i].Origin.x +"posX:" + posX );
      posY = (long)(0.01 * drawTable[i].dCurProg * (Center.y-drawTable[i].Origin.y)) + drawTable[i].Origin.y;
      if(!(drawTable[i].iIndex==0 || drawTable[i].iIndex==5)) {
       cv.drawBitmap(padTable[drawTable[i].iIndex].Icon, posX, posY, null);
      }
     }
    }
   }
   
   // update current positions in animation
   for( int i=0 ; i<9 ; i++ ){
    flag = drawTable[i].InAnimation;
    if( (flag & 0x01) == 0x01 ){  // Arriving (0x01)
     if( drawTable[i].dCurProg < 100.0 ){
      drawTable[i].dCurProg = Math.max( drawTable[i].dCurProg + dArrivingSpeed, 100.0 );
      Log.d("FLOW", "[doDraw] InArriving, i=" + i + ", dCurProg:" + drawTable[i].dCurProg + "  InAni:" + drawTable[i].InAnimation );
     } else {
      Log.d("FLOW", "[doDraw] before Pangali, i=" + i + ", dCurProg:" + drawTable[i].dCurProg + "  InAni:" + drawTable[i].InAnimation );
      drawTable[i].InAnimation = (byte)(drawTable[i].InAnimation & 0xFE);
      setKoreanNextDrawingTable(i); //Pangali('c')
      Log.d("FLOW", "[doDraw] Pangali, i=" + i + ", dCurProg:" + drawTable[i].dCurProg + "  InAni:" + drawTable[i].InAnimation );
     }
    } else if ( (flag & 0x02) == 0x02 ){ // Breaking 0x02
     if( drawTable[i].dCurProg > 0.0 ){
      drawTable[i].dCurProg = Math.min( drawTable[i].dCurProg - dBreakingSpeed, 0.0 );
      Log.d("FLOW", "[doDraw] InBreaking i=" + i + ", dCurProg:" + drawTable[i].dCurProg + "  InAni:" + drawTable[i].InAnimation );      
     } else {
      drawTable[i].InAnimation = (byte)(drawTable[i].InAnimation & 0xFD);
     }
    } else if ( (flag & 0x04) == 0x04 ){ // Canceling 0x04
     if( drawTable[i].dCurProg > 0.0 ){
      drawTable[i].dCurProg = Math.min( drawTable[i].dCurProg - dCancelingSpeed, 0.0 );
      Log.d("FLOW", "[doDraw] InBreaking i=" + i + ", dCurProg:" + drawTable[i].dCurProg + "  InAni:" + drawTable[i].InAnimation );
     } else {
      drawTable[i].InAnimation = (byte)(drawTable[i].InAnimation & 0xFB);
     }
    }
    else if ( flag != 0x00 ){
     Log.d("FLOW", "flag:" + flag );
    }
   }
  }
 }


 

 

메인 액티비티에서 서피스 뷰를 상속한 클래스를 불러와 손가락 닿는 대로 그림을 옮겨 그리는 프로그램을 만들고 있습니다.

 

위 코드는 서피스 뷰 내부의 쓰레드로, 메인 쓰레드와 함께 돌며 좌표가 갱신되면 계속 다시 그림을 그려줍니다.

 

그런데  18번 줄 cv.drawBitmap(padTable[drawTable[i].iIndex].Icon, posX, posY, null); 이부분에서 종종

 

09-26 14:05:47.387: E/AndroidRuntime(21758): FATAL EXCEPTION: Thread-673
09-26 14:05:47.387: E/AndroidRuntime(21758): java.lang.ArrayIndexOutOfBoundsException: length=100; index=-1
09-26 14:05:47.387: E/AndroidRuntime(21758):  at edu.esrc.crossK.AnEventMove$DrawThread.doDraw(AnEventMove.java:849)
09-26 14:05:47.387: E/AndroidRuntime(21758):  at edu.esrc.crossK.AnEventMove$DrawThread.run(AnEventMove.java:818)

또는

09-26 14:14:25.145: E/AndroidRuntime(22166): FATAL EXCEPTION: Thread-679
09-26 14:14:25.145: E/AndroidRuntime(22166): java.lang.ArrayIndexOutOfBoundsException: length=100; index=-1
09-26 14:14:25.145: E/AndroidRuntime(22166):  at edu.esrc.crossK.AnEventMove.setKoreanNextDrawingTable(AnEventMove.java:415)
09-26 14:14:25.145: E/AndroidRuntime(22166):  at edu.esrc.crossK.AnEventMove$DrawThread.doDraw(AnEventMove.java:872)
09-26 14:14:25.145: E/AndroidRuntime(22166):  at edu.esrc.crossK.AnEventMove$DrawThread.run(AnEventMove.java:818)

라고 이셉션이 뜹니다.

 

 

매번 뜨는 것은 아니고 어떤 때는 잘 동작하다가 어떤 때는 줄창 뜨네요...

 

뭐가 문제인지 도저히 모르겠습니다.ㅠㅠ

 

padTable의 length가 100인데 -1이 계속 들어간대서 padTable의 인덱스를 넣어줄때마다 로그를 찍어봐도 -1이 들어가는 건 없네요.

 

이셉션 발생 후에도 로그에는 -1이 아닌 정상 숫자가 들어가 있습니다...

 

 

 

아래는 간혹 같이 이셉션 부분에 걸리는 korean Next Drawing Table 함수입니다.

 

  public void setKoreanNextDrawingTable( int dir ){
  // not synchronized since it is called only in doDraw()
  int n = drawTable[dir].iIndex;
  for (int i=0 ; i<5 ; i++ ){
   drawTable[i].bShown = false;
   drawTable[i].InAnimation = 0;
   drawTable[i].dCurProg = 0.0;
   drawTable[i].iIndex = -1; // make it empty first
  }
  for (int i=0 ; i<padTable[n].iNumChild ; i++ ){
   if(n>0 && padTable[n].Children[i]>0) {
    int m = padTable[n].Children[i];
    drawTable[padTable[m].iDir].iIndex = m;
    drawTable[padTable[m].iDir].bShown= true;
    drawTable[padTable[m].iDir].dCurProg= 80.0;
    drawTable[padTable[m].iDir].InAnimation = 0x02;
   }
  }
 }

 

로그상으론 역시 padTable의 인덱스로 -1이 들어가는 부분은 없습니다.

 

 

제가 뭔가를 간과하고 있는지, 아니면 혹시 drawBitmap 함수 자체에서 규정(?)해놓은 게 있는지 궁금합니다.