2014-02-17 47 views
2

我正在嘗試在應用程序上使用線程來延遲該線程而不凍結活動。問題在於即使我在線程上有Thread.sleep(),活動也會凍結。我想要做的就是像Simon這樣的遊戲,我想在沒有凍結活動的情況下點亮一個按鈕2秒,但它會被凍結。該線程被稱爲NuevoColor,並且我在onCreate方法的結尾處​​開始它。我會在這裏粘貼代碼,預先感謝。線程正在凍結Android應用程序上的活動

package com.example.simondice; 

import java.util.ArrayList; 

import android.app.Activity; 
import android.graphics.Color; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.Button; 

public class Jugar extends Activity { 

public Button boton1Rojo; 
public Button boton2Azul; 
public Button boton3Verde; 
public Button boton4Amarillo; 

public ArrayList<Integer> arrayJuego; //se guarda la secuencia del juego 
public ArrayList<Integer> arrayJugador; //se guarda la secuencia introducida por el jugador 

@Override public void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 

    setContentView(R.layout.jugar); 
    boton1Rojo = (Button) findViewById(R.id.button1); 
    boton2Azul = (Button) findViewById(R.id.button2); 
    boton3Verde = (Button) findViewById(R.id.button3); 
    boton4Amarillo = (Button) findViewById(R.id.button4); 

    //cambiamos el color de los botones 
    boton1Rojo.setBackgroundColor(Color.rgb(127, 0, 0)); 
    boton2Azul.setBackgroundColor(Color.rgb(0, 0, 127)); 
    boton3Verde.setBackgroundColor(Color.rgb(0, 127, 0)); 
    boton4Amarillo.setBackgroundColor(Color.rgb(127, 127, 0)); 

    //botones a disable al iniciar 
    boton1Rojo.setEnabled(false); 
    boton2Azul.setEnabled(false); 
    boton3Verde.setEnabled(false); 
    boton4Amarillo.setEnabled(false); 

    //iniciamos el juego 
    NuevoColor juego = new NuevoColor(); 
    juego.start(); 
} 


// Crea un nuevo color para el juego 
public class NuevoColor extends Thread { 

    @Override public void run() { 
     runOnUiThread(new Runnable() { 

      @Override 
      public void run() { 
       // TODO Auto-generated method stub 
       arrayJuego = new ArrayList<Integer>(); 

       try { 
        int rand = 0; 

        rand = (int) Math.floor(Math.random()*4+1); 

        if(rand==1) { //iluminamos los botones y los añadimos al array 
         boton1Rojo.setBackgroundColor(Color.rgb(255, 0, 0)); 
         arrayJuego.add(1); 
         Thread.sleep(2000); 
         boton1Rojo.setBackgroundColor(Color.rgb(127, 0, 0)); 
        } else if(rand==2) { 
         boton2Azul.setBackgroundColor(Color.rgb(0, 0, 255)); 
         arrayJuego.add(2); 
         Thread.sleep(2000); 
         boton2Azul.setBackgroundColor(Color.rgb(0, 0, 127)); 
        } else if(rand==3) { 
         boton3Verde.setBackgroundColor(Color.rgb(0, 255, 0)); 
         arrayJuego.add(3); 
         Thread.sleep(2000); 
         boton3Verde.setBackgroundColor(Color.rgb(0, 127, 0)); 
        } else { 
         boton4Amarillo.setBackgroundColor(Color.rgb(255, 255, 0)); 
         arrayJuego.add(4); 
         Thread.sleep(2000); 
         boton4Amarillo.setBackgroundColor(Color.rgb(127, 127, 0)); 
        } 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 

      } 

     }); 
    } 
} 

}

編輯:感謝大家的答案,現在我知道什麼更好的runOnUiThread()。這裏的一些變化後級的工作,以防萬一有人發現了它有用:

public class NuevoColor extends Thread { 

    @Override public void run() { 
     try { 
      Thread.sleep(1000); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     runOnUiThread(new Runnable() { 

      @Override 
      public void run() { 
       // TODO Auto-generated method stub 
       cambiarColor(); 
      } 

     }); 

     try { 
      Thread.sleep(2000); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     runOnUiThread(new Runnable() { 

      @Override 
      public void run() { 
       // TODO Auto-generated method stub 
       colorOriginal(); 
      } 

     }); 
    } 
} 
+2

在'runOnUiThread'內使用'Thread.sleep(2000)'睡眠主UI線程而不是工作線程。所以使用'Handler'或'AsyncTask'來避免UI線程凍結 –

回答

0

只要移動「Thread.sleep(2000);」到在UI線程上運行的Runnable之外。我發現你想在任何情況下睡覺。因此,像這樣:NuevoColor的,你運行中運行(

public class NuevoColor extends Thread { 

    @Override public void run() { 
     Thread.sleep(2000); 
     runOnUiThread(new Runnable() { 

       @Override 
       public void run() { 
        // ... 
       } 

      }); 
    } 
} 

任何東西)是THA後臺工作,睡覺應該有,因爲你想要的後臺線程被暫停,而不是整個使用界面。

任何將Runnable引發到runOnUiThread()的東西當然會在UI線程上運行,所以它會凍結整個用戶界面直到完成。所以在那裏沒有繁重的工作,也沒有睡覺。

一般來說,可以這樣想:任何你想做的事,都在後臺線程中做。任何更新UI的東西(比如setBackgroundColor()等),都可以在UI線程上運行它。在你的情況下,按照我的指示移動Thread.sleep(2000)。

0

既然你調用了Thread.sleep(2000)內runOnUiThread,因此UI凍結爲所指出的ρяσѕρєя。不上調用sleep ui線程。你不應該阻止ui線程。

參考這個Does Thread.sleep() makes the UI Thread to sleep?

解決方法問題的方法:異步任務的調用async task和異步任務的doinbackground內()調用​​了Thread.sleep(2000).doinbackground()不上運行UI線程。這裏是你如何使用異步任務AsyncTask Android example