0
votes

The main thread in this program is doing too much work for whatever reason. I don't know how else to use views on the main thread though. I've tried using AsyncTask but I have no idea as to how I'm supposed to use it.

Thread thread2 = new Thread(){
            public void run(){
                while(running){
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            try{
                                if(red){
                                    buttons[ran].setImageResource(R.drawable.button_red);
                                    buttons[ran].setTag("Red");
                                    Thread.sleep(duration);
                                    if(buttons[ran].getTag().equals("Red")){
                                        buttons[ran].setTag("Black");
                                        buttons[ran].setImageResource(R.drawable.button_null);
                                        lifeLost();
                                        red = false;
                                    }
                                }else if(white){
                                    buttons[ran].setImageResource(R.drawable.button_white);
                                    buttons[ran].setTag("White");
                                    Thread.sleep(duration);
                                    if(buttons[ran].getTag().equals("White")){
                                        buttons[ran].setTag("Black");
                                        buttons[ran].setImageResource(R.drawable.button_null);
                                        lifeLost();
                                        white = false;
                                    }
                                }
                            }catch(Exception e){

                            }
                        }
                    });
                    try {
                        sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        };
        thread2.start();

This thread is doing whatever non UI related tasks I could give it. The code itself actually works on this thread. However, it only works on newer devices and older ones seem to pick up on the bug instead of ignoring it.

@Override
    public void run() {
        random = new Random();
        random2 = new Random();

    try{
        Thread.sleep(1000);
        while(running){
            ran = random.nextInt(9);
            type = random2.nextInt(3);

            if(lives > 0){
                if(type == 0 || type == 2){
                  red = true;
                }else{
                    white = true;
                }

                if(lives == 0){
                        Thread.sleep(1000);
                        Intent overIntent = new Intent(this, OverActivity.class);
                        overIntent.putExtra("point", score);
                        startActivity(overIntent);
                        overridePendingTransition(0, 0);

                }

                if(score == 10){
                    duration -= 50;
                }else if(score == 20){
                    duration -= 50;
                }else if(score == 30){
                    duration -= 50;
                }else if(score == 40){
                    duration -= 50;
                }
            }
        }
    }catch(Exception e){
        e.printStackTrace();
    }
}
2
You can simply put your code in background task and let it return result for you. - olajide
You're calling runOnUiThread. That measn its actually running on the UI thread, and the Thread isn't doing anything. Which means you're calling sleep on the UI thread, which is NEVER a good idea. Take out the runOnUIThread and actually run it on the thread, and put only the code which actually calls functions on views in runOnUiThread. - Gabe Sechan
@BashorunOlajide I'll try that thank you. - Neptune
@GabeSechan Already tried that before. Didn't work - Neptune
@Neptune I'm not promising that will be sufficient, but it is necessary. Anything put in runOnUIThread is run on the ui thread. You can't sleep on it. You can't loop forever on it. Your code in any form that puts large blocks inside a runOnUiThread will never work. - Gabe Sechan

2 Answers

1
votes

Everything inside your runOnUiThread command is being run on the UI thread (as the name implies), which includes your calls to Thread.sleep(duration) (thus causing the UI thread to hang/do too much work). As an easy first step, try separating this into a couple calls of runOnUiThread and putting the Thread.sleep(duration) statement in between them instead of in them.

0
votes

You can create a class

public class DoCalculationAsyncTask extends AsyncTask<Void, Void, DataType> {

@SuppressLint("StaticFieldLeak")
private Context mContext;

public DoCalculationAsyncTask(Context context) {

}


@Override
protected Bitmap doInBackground(Void... params) {

    try {

    } catch (Exception e) {

        e.printStackTrace();

    } finally {

    }
    return something;
}

@Override
protected void onPostExecute(Bitmap result) {
    super.onPostExecute(result);

} }

Then call the class like this

 try {
            DoCalculationAsyncTask doCalculationAsyncTask = new
                    DoCalculationAsyncTask(value 1, value 2, value 3, ...);
            doCalculationAsyncTask.execute();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }