2016-10-15 1 views
0

Раньше у меня была проблема, когда я направлялся к своей основной деятельности (ColorMatch.java) из моей активности заставки, заставляя программу получать бесконечно застряли на черном экране. Я обнаружил, что это связано с методом run(), вызванным в моем onCreate в моей основной деятельности. Я пробовал комментировать некоторые вещи, чтобы увидеть, работает ли это, но до тех пор, пока run() вызывается в моем onCreate, он автоматически переходит на черный экран, даже не давая мне ошибки для устранения неполадок. Что может быть причиной этой проблемы?Android - основной метод в действии заставляет программу сбой на черный экран, но не дает ошибки

Мой ClassMatch.java:

package com.example.ali.colormatch; 

import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.widget.TextView; 
import android.os.Bundle; 
import android.app.Activity; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 
import android.widget.ImageView; 
import android.widget.RelativeLayout; 
import android.widget.TextView; 
import java.util.Random; 

public class ColorMatch extends AppCompatActivity { 

int answer; //1 = red, 2 = blue, 3 = green, 4 = yellow 
TextView textView3, textView2; 
int count = 0; 
volatile boolean playing = true; 
private long timeThisFrame; 
private Button testButton; 
long fps; 
int score; 
int correctAnswer; 
boolean matchColor = true, matchText = false; 
long startFrameTime; 
boolean firstTime = true; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_color_match); 
    textView3 = (TextView) findViewById(R.id.textView3); 
    textView2 = (TextView) findViewById(R.id.textView2); 

    run(); 
} 

public void run() { 
    while (playing) { 

     startFrameTime = System.currentTimeMillis(); 

     if (firstTime){ 
      generateNewWord(); 
      firstTime = false; 
     } 

     if (answer == correctAnswer){ 
      score++; 
      count++; 
      generateNewWord();} 
     //else { 
     // quit(); 
     // } 


     if (count % 5 == 0){ 
       if (matchColor) { 
        textView3.setText(getString(R.string.gameSetting2)); // might need to add context with this - check http://stackoverflow.com/questions/10698945/reference-string-resource-from-code 
        matchColor = true; 
        matchText = false; 
       } 
       else if (matchText){ 
        textView3.setText(getString(R.string.gameSetting1)); 
        matchText = true; 
        matchColor = false; 
       } 
      } 
     } 

     //draw(); 
     timeThisFrame = System.currentTimeMillis() - startFrameTime; 
     if (timeThisFrame > 0) { 
      fps = 1000/timeThisFrame; 
     } 

    } 

public void generateNewWord(){ 

    //randomly select between red, green, blue, yellow 
    Random rand = new Random(); 
    int randomInt1 = rand.nextInt(4) + 1; // assigns randomInt a value between 1 - 4 
    int randomInt2 = rand.nextInt(4) + 1; 

    if (randomInt1 ==1){ 
     textView3.setText(R.string.Red); 
    } 
    else if (randomInt1 ==2){ 
     textView3.setText(R.string.Green); 
    } 
    else if (randomInt1 == 3){ 
     textView3.setText(R.string.Blue); 
    } 
    else if (randomInt1 == 4){ 
     textView3.setText(R.string.Yellow); 
    } 


    //randomly select hex codes between rgby 
    if (randomInt2 ==1){ 
     textView3.setTextColor(0xffcc0000); 
    } 
    else if (randomInt2 ==2){ 
     textView3.setTextColor(0xff669900); 
    } 
    else if (randomInt2 == 3){ 
     textView3.setTextColor(0xff000080); 
    } 
    else if (randomInt2 == 4){ 
     textView3.setTextColor(0xffffff00); 
    } 


    if (matchColor) { 
     correctAnswer = randomInt2; 
    } 
    else if(matchText){ 
     correctAnswer = randomInt1; 
    } 

} 
public void quit(){ 

} 


public void sendBlue(View view){ 
    answer = 2; 
} 
public void sendRed(View view){ 
    answer = 1; 
} 
public void sendYellow(View view){ 
    answer = 4; 
} 
public void sendGreen(View view){ 
    answer = 3; 
} 


} 

activity_color_match.xml файл, который он использует:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 

xmlns:tools="http://schemas.android.com/tools" 
android:id="@+id/activity_color_match" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:paddingBottom="@dimen/activity_vertical_margin" 
android:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin" 
tools:context="com.example.ali.colormatch.ColorMatch"> 

<TextView 

    android:text="@string/matchText" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/textView3" 
    android:textAppearance="@style/TextAppearance.AppCompat.Body2" 
    android:layout_alignParentTop="true" 
    android:layout_centerHorizontal="true" /> 

<TextView 
    android:text="@string/mainColor" 
    android:id="@+id/textView2" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:gravity="center_horizontal" 
    android:textColor="@android:color/background_dark" 
    android:textSize="100dp" 
    android:layout_marginBottom="104dp" 
    android:textAppearance="@style/TextAppearance.AppCompat.Display3" 
    android:layout_above="@+id/button3" 
    android:layout_centerHorizontal="true" /> 

<Button 
    android:layout_width="150dp" 
    android:layout_height="60dp" 
    android:id="@+id/button" 
    android:background="#000080" 
    android:onClick="sendBlue" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentStart="true" /> 

<Button 
    android:layout_height="60dp" 
    android:id="@+id/button2" 
    android:background="@color/yellow" 
    android:elevation="0dp" 
    android:layout_width="150dp" 
    android:onClick="sendYellow" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentRight="true" 
    android:layout_alignParentEnd="true" /> 

<Button 
    android:layout_width="150dp" 
    android:layout_height="60dp" 
    android:id="@+id/button3" 
    android:background="@android:color/holo_red_dark" 
    android:onClick="sendRed" 
    android:layout_above="@+id/button" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentStart="true" 
    android:layout_marginBottom="19dp" /> 

<Button 
    android:layout_width="150dp" 
    android:layout_height="60dp" 
    android:id="@+id/button4" 
    android:background="@android:color/holo_green_dark" 
    android:onClick="sendGreen" 
    android:layout_alignParentRight="true" 
    android:layout_alignParentEnd="true" 
    android:layout_alignBottom="@+id/button3" /> 


</RelativeLayout> 

Ради ЗАВЕРШЕНИЕ, хотя я думаю, что это, вероятно, не имеет значения, вот мой MainActivity.java. Кажется, что я работаю, как хотелось бы:

package com.example.ali.colormatch; 

import android.content.Intent; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 


public class MainActivity extends AppCompatActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.splash_page); 
} 

public void onSplashPageClick(View view){ 
    Intent intent = new Intent(MainActivity.this, ColorMatch.class); 
    startActivity(intent); 
} 

public void onQuitClick(View view){ 
    finish(); 
} 
} 

Я использую Nexus 5 для запуска приложения и отладки. Спасибо.

+0

'onCreate()' никогда не возвращает причину 'play' в методе' run() 'is' true', что приводит к бесконечному циклу. Поскольку 'onCreate()' не может вернуть остальные методы жизненного цикла 'Activity', нельзя вызвать. В результате 'onResume()' не вернется, пользовательский интерфейс не будет нарисован, черный экран вверх. Вы должны переместить логику цикла while в фоновом потоке и опубликовать результаты в главном. – Onik

+0

Вы были правы! Я отключил цикл while (play), и он сработал. Это моя первая кодировка в Android с только опытом Java, так что цикл для меня был основой, которую я не понимал, может быть проблемой. Я возился с этим в то время как (играя) цикл в настоящее время, прямо сейчас текст загружается, поэтому мне просто нужно найти способ его обновления. – Johnny

ответ

0

Я думаю, вы можете создать поток в onCreate() и поместить метод 'run()' в этот поток.

попробовать:

  new Thread(new Runnable() { 
       @Override 
       public void run() { 
        ColorMatch.this.run(); 
       } 
      }).start(); 

** Редактировать **

Причина заключается в том, что вы тоже многие вещи в поток пользовательского интерфейса (основной поток), когда OnCreate, и если вы тратите слишком много времени в onCreate, это будет ANR (Activity Not Responding), вам нужно поставить задачу, которая тратит время в фоновом потоке. И он будет избегать черного экрана, когда действие onCreate.

+0

'AsyncTask' - это стандартный способ сделать это в Android, по крайней мере, для относительно коротких операций. – nasch

+0

Он не блокирует поток пользовательского интерфейса, он все еще работает. Также способ, который вы предлагаете, будет терпеть неудачу, потому что в методе 'run()' виджеты метода «коснулись». – Onik

+0

Да AsyncTask - стандартный способ :). –

0

Эй Если вы все еще ищете способ обновить время от времени, вы можете использовать Таймер.

Посмотрите на этот ответ здесь https://stackoverflow.com/a/18353754/2311117. это объясняет, как использовать таймер.

Для получения дополнительной информации о Timer и TimerTask.

+0

Я планирую добавить таймер, чтобы ограничить, сколько времени пользователю нужно нажать на кнопку, так что, похоже, я смогу использовать Таймер для этого. Однако мне нужно, чтобы метод run() выполнялся каждый раз, когда пользователь нажимает кнопку; если ответ будет прав, он будет генерировать новое слово и обновлять таймер, если это неправильно, программа остановится. – Johnny

+0

вы можете использовать 'Timer.start' и' Timer.cancel' для запуска/остановки таймера. насколько я понимаю, вам нужно что-то обновить, пока пользователь не предпримет какие-либо действия. – Shivansh

Смежные вопросы