2016-07-09 5 views
1

私は今、約一ヶ月のために、この問題を持ってきたと私はここでそれについて別の質問をした後に実行を停止します。一見無作為な時間を過ごした後、UIスレッドは作業をやめているようです。 '.post()'または 'runOnUIThead()'で渡された 'Runnable'オブジェクトは実行されません。単純なログメッセージです。問題が発生してもonClickListenerオブジェクトは起動しません。私はスタートから2秒以内に起きるようなところで走ってきました。試合全体を通して問題なく走っていました。すべて同じコード上にあります。ここでUIスレッドは、ランダムな時間

あなたがそれを必要とする場合、私のコードです:
活動:

package edu.rit.jacob.timeturner; 

import android.app.ActivityManager; 
import android.app.Application; 
import android.app.Dialog; 
import android.content.Intent; 
import android.os.Looper; 
import android.provider.ContactsContract; 
import android.provider.Settings; 
import android.support.annotation.StringRes; 
import android.support.v7.app.AlertDialog; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.text.Layout; 
import android.util.Log; 
import android.view.Gravity; 
import android.view.View; 
import android.view.Window; 
import android.view.WindowManager; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.ImageView; 
import android.widget.PopupWindow; 
import android.widget.ProgressBar; 
import android.widget.SeekBar; 
import android.widget.TextView; 

public class UniverseActivity extends AppCompatActivity { 

public static final String TAG = UniverseActivity.class.getSimpleName(); 

private UniverseThread thread; 
public UniverseThread getThread(){ return thread; } 

public static int SECTORS_HEIGHT = 3; 
public static int SECTORS_WIDTH = 3; 

private Galaxy player; 
public Galaxy getPlayer() { 
    return player; 
} 

//components: 
private UniverseView surfaceView; 
private ImageView playerSprite; 
private ImageView otherSprite; 
private TextView testText; 
private SeekBar speedBar; 
private ProgressBar timebar; 

//Pop ups 
private Dialog infoPopUp; 
private Dialog startScreen; 

//other Galaxies 
Galaxy[] galaxies = new Galaxy[SECTORS_HEIGHT * SECTORS_WIDTH]; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    //Setup Activity 
    super.onCreate(savedInstanceState); 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
    setContentView(R.layout.activity_universe); 

    Runnable init = new Runnable() { 
     @Override 
     public void run() { 
      initInfoPopUp(); 
      initActivityComponents(); 
      initPlayerAndSprites(); 
      initOtherGalaxies(); 
      initStartScreen(); 
     } 
    }; 
    runOnUiThread(init); 

    thread = new UniverseThread(surfaceView.getHolder(), surfaceView); 
    thread.setRunning(true); 
    thread.start(); 

    startScreen.setTitle("The Beginning..."); 
    startScreen.show(); 

    Log.d(TAG, "App launched with " + ((ActivityManager)getSystemService(ACTIVITY_SERVICE)).getLargeMemoryClass() + "MB max"); 
} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    boolean retry = true; 
    while(retry){ 
     try{ 
      thread.join(); 
      retry = false; 
     } 
     catch (InterruptedException e){ 
      //try again 
     } 
    } 
} 

private void initStartScreen(){ 
    startScreen = new Dialog(this); 
    startScreen.setContentView(R.layout.new_game_start); 

    ((TextView)startScreen.findViewById(R.id.textView4)).setText(getString(R.string.start_game_info)); 

    startScreen.findViewById(R.id.buttonStart).setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      player.setName("" + ((EditText)startScreen.findViewById(R.id.editText)).getText()); 
      startScreen.dismiss(); 
     } 
    }); 
} 

private void initInfoPopUp(){ 
    infoPopUp = new Dialog(this); 
    infoPopUp.setContentView(R.layout.info_popup); 
    Button infoOption1 = (Button) infoPopUp.findViewById(R.id.option1); 
    Button infoOption2 = (Button) infoPopUp.findViewById(R.id.option2); 

    infoOption1.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Log.d(TAG, "Option 1 clicked"); 
      //player.incrementGas(galaxies[player.getSector() - 1].getGas()); 
      player.merge(galaxies[player.getSector() - 1], true); 
      galaxies[player.getSector() - 1] = null; 
      infoPopUp.dismiss(); 
     } 
    }); 

    infoOption2.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Log.d(TAG, "Option 2 clicked"); 
      //player.incrementGas(galaxies[player.getSector() - 1].getGas()/2); 
      //galaxies[player.getSector() - 1].incrementGas(-galaxies[player.getSector() - 1].getGas()/2); 
      player.merge(galaxies[player.getSector() - 1], false); 
      infoPopUp.dismiss(); 
     } 
    }); 
} 

private void initActivityComponents(){ 
    surfaceView = (UniverseView) findViewById(R.id.surfaceView); 
    testText = (TextView) findViewById(R.id.testText); 
    speedBar = ((SeekBar)findViewById(R.id.seekBar)); 
    timebar = ((ProgressBar)findViewById(R.id.progressBar)); 
} 

private void initPlayerAndSprites(){ 
    playerSprite = (ImageView) findViewById(R.id.playerGalaxy); 
    player = new Galaxy("Milky Way", true, new Velocity(), playerSprite, 25.0f, 1, this); 
    otherSprite = (ImageView) findViewById(R.id.otherGalaxy); 

    //Tapping on player galaxy 
    playerSprite.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Log.d(TAG, "Player sprite clicked, stopping time and bringing up window..."); 
      speedBar.setProgress(0); 
      infoPopUp.setTitle(player.getName()); 
      infoPopUp.findViewById(R.id.infoPicture).setBackgroundResource(R.drawable.random_temp_galaxy_01); 
      infoPopUp.findViewById(R.id.option1).setVisibility(View.INVISIBLE); 
      infoPopUp.findViewById(R.id.option2).setVisibility(View.INVISIBLE); 
      ((TextView)infoPopUp.findViewById(R.id.infoText)).setText(player.toString()); 
      infoPopUp.show(); 
     } 
    }); 

    //Tapping on other galaxy 
    otherSprite.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if(otherSprite.getVisibility() == View.VISIBLE){ 
       Log.d(TAG, "Other sprite clicked, stopping time and bringing up window..."); 
       speedBar.setProgress(0); 
       infoPopUp.setTitle(galaxies[player.getSector() - 1].getName()); 
       infoPopUp.findViewById(R.id.infoPicture).setBackgroundResource(R.drawable.random_temp_galaxy_01); 
       infoPopUp.findViewById(R.id.option1).setVisibility(View.INVISIBLE); 
       infoPopUp.findViewById(R.id.option2).setVisibility(View.INVISIBLE); 
       ((TextView)infoPopUp.findViewById(R.id.infoText)).setText(galaxies[player.getSector() - 1].toString()); 
       infoPopUp.show(); 
      } 
     } 
    }); 
} 

private void initOtherGalaxies(){ 
    for(Galaxy g: galaxies) g = null; 
    int i = 0, galaxiesNum = 0; 
    Log.d(TAG, "Populating the universe..."); 
    while(i < galaxies.length){ 
     double rand = Math.random(); 
     if(rand <= 0.25){ 
      galaxies[i] = new Galaxy("Random galaxy", new Velocity(0,0), otherSprite, 25.0f, i + 1, (Math.random()), this); 
      galaxiesNum += 1; 
     } 
     i += 1; 
    } 
    Log.d(TAG, "Universe populated with " + galaxiesNum + " galaxies."); 
} 

public int getSpeed(){ 
    return speedBar.getProgress(); 
} 

public void setTimeProgress(int progress){ 
    try { 
     if (timebar.getProgress() != progress) { 
      switch (progress) { 
       case 10: 
        //((ProgressBar) findViewById(R.id.progressBar)).getProgress() 
        progress += 1; 
        //bring up new popup 
        break; 
       case 50: 
        //do stuff 
        break; 
       case 100: 
        //do end game stuff 
        boolean retry = true; 
        while (retry) { 
         try { 
          thread.join(); 
          retry = false; 
         } catch (InterruptedException e) { 
          //try again 
         } 
        } 
      } 
      timebar.setProgress(progress); 
     } 
    } 
    catch (NullPointerException e){ 
     Log.d(TAG, "Failed to grab progressBar"); 
     e.printStackTrace(); 
    } 
} 

public void changeBackground(){ 
    Runnable changeBackground = new Runnable() { 
     @Override 
     public void run() { 
      //Set new background 
      Log.d(TAG, "Changing to background " + player.getSector()); 
      //surfaceView.setBackgroundResource(R.drawable.background01 + (player.getSector() - 1)); 
      testText.setText("Sector: " + player.getSector()); 

      //Check for other galaxy 
      if(galaxies[player.getSector() - 1] != null){ 
       otherSprite.setVisibility(View.VISIBLE); 
      } 
      else{ 
       otherSprite.setVisibility(View.INVISIBLE); 
      } 
      synchronized (this) { 
       this.notify(); 
      } 
     } 
    }; 
    Log.d(TAG, "Passing background runnable to the UI thread"); 
    synchronized (changeBackground){ 
     runOnUiThread(changeBackground); 
     try { 
      changeBackground.wait(); 
     } 
     catch (InterruptedException e){ 
      e.printStackTrace(); 
     } 
    } 
} 

public void checkForCollision(){ 
    if(playerSprite.getX() + (playerSprite.getWidth()/2) >= otherSprite.getX() && 
      playerSprite.getX() + (playerSprite.getWidth()/2) <= otherSprite.getX() + otherSprite.getWidth() && 
      playerSprite.getY() + (playerSprite.getHeight()/2) >= otherSprite.getY() && 
      playerSprite.getY() + (playerSprite.getHeight()/2) <= otherSprite.getY() + otherSprite.getHeight()){ 
     if(otherSprite.getVisibility() == View.VISIBLE){ 
      //switch (player.) 

      Runnable collide = new Runnable() { 
       @Override 
       public void run() { 
        speedBar.setProgress(0); 
        otherSprite.setVisibility(View.INVISIBLE); 
        ((TextView)infoPopUp.findViewById(R.id.infoText)).setText(""); 
        //infoPopUp.findViewById(R.id.infoPicture).setBackgroundResource(R.drawable.hubble_merger_01); 
        infoPopUp.findViewById(R.id.option1).setVisibility(View.VISIBLE); 
        infoPopUp.findViewById(R.id.option2).setVisibility(View.VISIBLE); 
        infoPopUp.setTitle("Incoming!"); 
        infoPopUp.show(); 
       } 
      }; 
      runOnUiThread(collide); 
     } 
    } 

    //Set gauge 
    Runnable setGauge = new Runnable() { 
     @Override 
     public void run() { 
      ((GaugeView)findViewById(R.id.gaugeView)).setTargetValue(player.getGas()); 
     } 
    }; 
    runOnUiThread(setGauge); 
} 

} 

スレッド:

package edu.rit.jacob.timeturner; 

import android.content.Context; 
import android.graphics.Canvas; 
import android.hardware.*; 
import android.hardware.SensorManager; 
import android.provider.Settings; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.widget.ImageView; 

public class UniverseThread extends Thread { 

public static final String TAG = UniverseThread.class.getSimpleName(); 

private double time; 
public double getTime(){ 
    return time; 
} 

private double speed; 
public double getSpeed(){ 
    return speed; 
} 

private boolean running; 
public void setRunning(boolean running){ 
    this.running = running; 
} 
public boolean isRunning(){ 
    return running; 
} 

//Reference to the UniverseActivity 
private SurfaceHolder surfaceHolder; 

//Reference to the UniverseView that is the background 
private UniverseView universeView; 

public UniverseThread(SurfaceHolder surfaceHolder, UniverseView universeView){ 
    super(); 
    this.surfaceHolder = surfaceHolder; 
    this.universeView = universeView; 
    running = false; 
    time = 0; 
} 

public static float x = 0, y = 0, z = 0; 

@Override 
public void run(){ 
    Log.d(TAG, "Starting Game Loop"); 
    time = 0.0; 
    speed = 0.0; 

    //SensorManager gets SENSOR_SERVICE from android 
    //Accesses gravity sensor 
    SensorManager sm = (SensorManager) this.universeView.getContext().getSystemService(Context.SENSOR_SERVICE); 
    sm.registerListener(new SensorEventListener() { 
     @Override 
     public void onSensorChanged(SensorEvent event) { 
      x = event.values[0]; 
      y = event.values[1]; 
      z = event.values[2]; 
     } 

     @Override 
     public void onAccuracyChanged(Sensor sensor, int accuracy) { 

     } 
    }, sm.getDefaultSensor(Sensor.TYPE_GRAVITY), SensorManager.SENSOR_DELAY_GAME); 

    //save player, velocity, and sprite 
    Galaxy player = ((UniverseActivity)universeView.getContext()).getPlayer(); 
    Velocity vel = player.getVel(); 
    ImageView sprite = player.getSprite(); 
    boolean changeBackground; 

    float timesRun = 0f; 

    while(running){ 
     //every 16 milliseconds (~60 Hz) 
     timesRun += 1; 
     final String testStr = "Thread has run for " + (timesRun) + " frames."; 
     Runnable test = new Runnable() { 
      @Override 
      public void run() { 
       Log.d(TAG, testStr); 
      } 
     }; 
     if(timesRun % 60 == 0) ((UniverseActivity) universeView.getContext()).runOnUiThread(test); 

     //increment the time 
     speed = ((UniverseActivity)universeView.getContext()).getSpeed(); 
     time += (speed/7200.0); 
     ((UniverseActivity)universeView.getContext()).setTimeProgress((int) time); 

     //update player's velocity 
     ((UniverseActivity)universeView.getContext()).getPlayer().getVel().incrementXV(-x/9.81f); 
     ((UniverseActivity)universeView.getContext()).getPlayer().getVel().incrementYV(y/9.81f); 

     //update player's position 
     //move sprite 
     sprite.setX((float)(sprite.getX() + (vel.getxV() * speed/400))); 
     sprite.setY((float)(sprite.getY() + (vel.getyV() * speed/400))); 

     changeBackground = false; 
     //bottom -> top 
     if (sprite.getY() + (sprite.getHeight()/2) > universeView.getHeight()) { 
      sprite.setY(0 - (sprite.getHeight()/2)); 
      sprite.setX(universeView.getWidth()/2); 
      player.updateSector("BOTTOM"); 
      changeBackground = true; 
     } 
     //right -> left 
     if (sprite.getX() + (sprite.getWidth()/2) > universeView.getWidth()) { 
      sprite.setY(universeView.getHeight()/2); 
      sprite.setX(0 - (sprite.getWidth()/2)); 
      player.updateSector("RIGHT"); 
      changeBackground = true; 
     } 
     //top -> bottom 
     if (sprite.getY() + (sprite.getHeight()/2) < 0) { 
      sprite.setY(universeView.getHeight() - (sprite.getHeight()/2)); 
      sprite.setX(universeView.getWidth()/2); 
      player.updateSector("TOP"); 
      changeBackground = true; 
     } 
     //left -> right 
     if (sprite.getX() + (sprite.getWidth()/2) < 0) { 
      sprite.setY(universeView.getHeight()/2); 
      sprite.setX(universeView.getWidth() - (sprite.getWidth()/2)); 
      player.updateSector("LEFT"); 
      changeBackground = true; 
     } 
     if(changeBackground) 
     {((UniverseActivity)universeView.getContext()).changeBackground();} 

     ((UniverseActivity)universeView.getContext()).checkForCollision(); 

     try{ 
      this.sleep(16L); 
     } 
     catch (InterruptedException e){ 
      e.printStackTrace(); 
     } 
    } 
    Log.d(TAG, "Game Loop terminated"); 
} 

}

明確にすることが、何の例外またはエラーがあることはありません実行時にスローされます。 logcatの唯一のメッセージは、自分自身と、クリックを登録するためのシステムメッセージです。アプリケーションはクラッシュせず、スプライトは完全に制御可能です。動作しない主なものは、背景の変更、衝突のチェック、onClickListenersです。

誰もこのようなことに遭遇しましたか?どんな助けもありがとう。

+0

一度に複数のスレッドを開始しますか?あなたがそうするならば、私はそれらのすべてが同時に動くわけではないと信じています...それで、おそらく、アンドロイドは1つのスレッドが終了するまで待っています。 – W0rmH0le

+0

いいえ、ワーカー/ゲームスレッドが作成され、UIスレッドの後に開始されます。私が知る限り、それらはここで唯一の2つのスレッドです。 –

+0

ランダムに停止したときのCPU使用率/メモリ使用率はどのくらいですか?意図的に起こるようにAndroidTestCasesを実行しましたか? –

答えて

1

私はUIスレッドに渡していたオブジェクトをRunnableに絞り込んだ後、最初にrunOnUIThread()という名前の時間を最小限に抑えるための手順を実行しましたが、最終的に私は停止しましたこの問題を抱えていて、それが私がそれに貢献できる唯一のものです。私は最終的にそれが問題とそれぞれの解決策であることをより具体的にするためにいくつかのテストを行うかもしれません。

関連する問題