2014-05-21 43 views
0

在我的第一個Android應用程序中,我的線程出現問題。事實上,當我觸摸屏幕時,我希望它可以像我想要的那樣發射許多恆星(投射物)。但目前,一觸之後,我有一條消息告訴我,該應用程序'沒有響應...使用線程在Android中移動多個位圖

我沒有找到解決方案。

這裏是我的代碼:(注:也有法國的意見,只是忽略它)

package com.example.slider; 

import java.util.Stack; 
import android.app.Activity; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.SurfaceHolder; 
import android.view.View; 
import android.view.View.OnTouchListener; 
import android.view.WindowManager; 

public class TirMissile extends Activity implements OnTouchListener { 

BringBackSurface aBackSurface; 
float x, y, sX, sY, fX, fY; // s=Starting f=Final 
int i; 
Bitmap test, test1; 
ThreadProjectile aTP; 
Stack<Projectile> aProjectileAttente; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    aBackSurface = new BringBackSurface(this); 
    aBackSurface.setOnTouchListener(this); 

    x = 0; y = 0; sX = 0; sY = 0; fX = 0; fY = 0; 
    i=0; 

    test = BitmapFactory.decodeResource(getResources(), android.R.drawable.btn_star_big_on); 
    test1 = BitmapFactory.decodeResource(getResources(), android.R.drawable.btn_star_big_off); 

    //full screen 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
    setContentView(aBackSurface); 


    Log.d("TEST","test01"); 

} 

@Override 
protected void onPause() { 
    super.onPause(); 
    aBackSurface.pause(); 
} 

@Override 
protected void onResume() { 
    super.onResume();  
    aBackSurface.resume(); 
    Log.d("TEST","test0"); 
    aBackSurface.getHolder().addCallback(new MyCallback()); 

} 

@Override 
public boolean onTouch(View v, MotionEvent event) { // event = down/up/right/release/value/etc... 
    try { 
     Thread.sleep(50); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

    x = event.getX(); 
    y = event.getY(); 

    switch(event.getAction()) { 

    case MotionEvent.ACTION_UP: 
     fX = event.getX(); 
     fY = event.getY(); 

     Projectile vProjectile = new Projectile(50,50,fX,fY,50,test); 

     if(i==0){ 
      this.aProjectileAttente = new Stack<Projectile>(); 
     } 

     this.aProjectileAttente.push(vProjectile); 

     if(i==0){ 
      this.aTP.setStack(this.aProjectileAttente); 
      aBackSurface.resume(); 
      aTP.run(); 
      i++; 
     }   

     Log.d("TEST","test10"); 

    } 

    return true; // si true, x et y seront constament mesurés tant qu'on maintient le doight sur l'écran 
} 


public class MyCallback implements SurfaceHolder.Callback { 
    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){ 
     Canvas canvas= holder.lockCanvas(); 
     canvas.drawRGB(02, 02, 150); 
     holder.unlockCanvasAndPost(canvas); 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     Canvas canvas= holder.lockCanvas(); 
     canvas.drawRGB(02, 02, 150); 
     holder.unlockCanvasAndPost(canvas);   
     aTP = new ThreadProjectile(aBackSurface); 
     Log.d("TEST","test110");    
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     // TODO Auto-generated method stub 

    } 
} 
    } 

第二類:

package com.example.slider; 

    import java.util.ArrayList; 
    import java.util.Iterator; 
    import java.util.Stack; 
    import android.graphics.Canvas; 
    import android.util.Log; 
    import com.example.slider.BringBackSurface; 

    public class ThreadProjectile implements Runnable{ 


private ArrayList<Projectile> aALprojectile; 
private BringBackSurface aBBS; 
private Stack<Projectile> aProjectileAttente; 


public ThreadProjectile(final BringBackSurface BBS) { 

    this.aBBS = BBS; 
    this.aALprojectile = new ArrayList<Projectile>(); 
    Log.d("TEST","test2"); 

} 

public void setStack(Stack<Projectile> stack){ 
    this.aProjectileAttente = stack; 
} 

private void updateProjectile() { 
    Log.d("UPDATE", "update en cours"); 
    while(!this.aProjectileAttente.isEmpty()) 
     aALprojectile.add(this.aProjectileAttente.pop()); 
} 

@Override 
public void run() { 

    Projectile vProjectile; 
    float nX, nY; 
    Canvas canvas = null; 
    Iterator<Projectile> vIt; 

    while(aBBS.getRunning()) { 

     updateProjectile(); 
     vIt = aALprojectile.iterator(); 
     if(!this.aBBS.getHolder().getSurface().isValid()) continue; // si ce n'est pas valide, on continue (continue fonctionne comme un statut break et nous)   
     canvas= this.aBBS.getHolder().lockCanvas(); 
     if(canvas == null) Log.e("CANVAS", "Pas de Canvas");    
     canvas.drawRGB(02, 02, 150); // coloriage du background  
     Log.d("BACKGROUND","test205"); 

     while(vIt.hasNext()) { 

      vProjectile = vIt.next(); 
      nX = vProjectile.getX() + vProjectile.getVX(); 
      nY = vProjectile.getY() + vProjectile.getVY(); 


      if(nX < 0 || nY < 0 || nX > aBBS.getWidth() || nY > aBBS.getHeight()) vIt.remove(); 
      else{ 
       canvas.drawBitmap(vProjectile.getBitmap(), nX-(vProjectile.getBitmap().getWidth()/2) , nY-(vProjectile.getBitmap().getHeight()/2), null); 
       vProjectile.setX(nX); 
       vProjectile.setY(nY); 
      }       
      Log.d("TEST","X:"+nX+" Y:"+nY);     
     } 
     Log.d("TEST","test207"); 
     this.aBBS.getHolder().unlockCanvasAndPost(canvas);     
    } 

} 

} 

末級使用:

package com.example.slider; 

import android.content.Context; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 

public class BringBackSurface extends SurfaceView { // Cette classe dans cette classe pour avoir accès aux valeurs de X et Y (XML?) dans la méthode onTouch() 

public SurfaceHolder aHolder; 

public boolean aIsRunning = false; // notre thread va aller dans le onresume() donc va passer en true 

public BringBackSurface(Context context) { 
    super(context); 
} 

public void pause(){ 
    aIsRunning = false; 
} 

public void resume(){ 
    aHolder = getHolder(); 
    aIsRunning = true; 
} 

public boolean getRunning() { 
    return aIsRunning; 
} 

} 

謝謝。

+0

'aTP.run();'這不是你如何開始一個線程。 – njzk2

+0

(你想'新線程(aTP).start()') – njzk2

回答

0

我會說你需要分開你的代碼;在OnTouch函數上,我實際上不會繪製,只需使用它來計算座標(如同你正在做的那樣)並調用另一個類來繪製。

我做了一個關於帆布問題就在不久前,我想你會發現它足智多謀(我希望如此):Drawing fast in canvas Bitmap android ics

正如你可以看到有我做了一個自定義類,只是爲了得出:

private class Painter extends View{ 
public Painter(Context context){ 
    super(context); 
} 

public void draw() { 
    //more code on the source 
} 

在onTouch事件上,我儘量做到最低限度,因爲我遇到同樣的問題。

希望它有幫助。