NanoPixel
NanoPixel

Reputation: 122

How to run code multiple times in Java Android Studio

I am new to making android apps, and I don't know how to run a piece of code multiple times. Here is my code:

package com.example.test;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import java.util.Random;
import android.widget.AbsoluteLayout;
import android.util.*;
import java.util.concurrent.TimeUnit;


public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    int score = 0;
    TextView scoreText;
    ImageButton mole;
    Random random = new Random();

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

        scoreText = findViewById(R.id.scoreCount);
        mole = findViewById(R.id.mole);
        //I want to run this multiple times
        TimeUnit.MILLISECONDS.sleep(random.nextInt(500));
        AbsoluteLayout.LayoutParams absParams =
                (AbsoluteLayout.LayoutParams) mole.getLayoutParams();

        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        int width = displaymetrics.widthPixels;
        int height = displaymetrics.heightPixels;


        Random r = new Random();

        absParams.x = r.nextInt(width);
        absParams.y = r.nextInt(height);
        mole.setLayoutParams(absParams);
    }

    @Override
    public void onClick(View v) {

    }
}

I am trying to make a mole game where the mole randomly goes across the screen and you have to tap it to earn points, the thing is though, I don't know how to run

TimeUnit.MILLISECONDS.sleep(random.nextInt(500));
        AbsoluteLayout.LayoutParams absParams =
                (AbsoluteLayout.LayoutParams) mole.getLayoutParams();

        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        int width = displaymetrics.widthPixels;
        int height = displaymetrics.heightPixels;


        Random r = new Random();

        absParams.x = r.nextInt(width);
        absParams.y = r.nextInt(height);
        mole.setLayoutParams(absParams);

again and again. I've tried doing

Thread test = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //I want to run this multiple times
                    TimeUnit.MILLISECONDS.sleep(500);
                    AbsoluteLayout.LayoutParams absParams =
                            (AbsoluteLayout.LayoutParams) mole.getLayoutParams();

                    DisplayMetrics displaymetrics = new DisplayMetrics();
                    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
                    int width = displaymetrics.widthPixels;
                    int height = displaymetrics.heightPixels;


                    Random r = new Random();

                    absParams.x = r.nextInt(width);
                    absParams.y = r.nextInt(height);
                    mole.setLayoutParams(absParams);
                }catch(InterruptedException e){
                    Log.i("Error", "Thread");
                }
            }
        });
        test.start();

But it keeps returning the following error:

com.example.test E/AndroidRuntime: FATAL EXCEPTION: Thread-1057
    Process: com.example.test, PID: 25335
    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
        at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7266)
        at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1065)
        at android.view.View.requestLayout(View.java:19098)
        at android.view.View.requestLayout(View.java:19098)
        at android.view.View.requestLayout(View.java:19098)
        at android.view.View.requestLayout(View.java:19098)
        at android.view.View.requestLayout(View.java:19098)
        at android.view.View.requestLayout(View.java:19098)
        at android.view.View.requestLayout(View.java:19098)
        at android.view.View.setLayoutParams(View.java:12590)
        at com.example.test.MainActivity$1.run(MainActivity.java:48)
        at java.lang.Thread.run(Thread.java:818)

Upvotes: 0

Views: 517

Answers (1)

Alireza Sharifi
Alireza Sharifi

Reputation: 1162

you can use RxJava as @Mohammad Reza Khahani mentioned which make life easier but if you don't want to get in to it you have two option to run your Thread and change the UI.

first one is to create Handler and inside of your Thread use it to run your code related to UI:

    Handler handler = new Handler(); // create new instance in ui thread eg: @onCreate or @onResume

    handler.post(new Runnable() {
        @Override
        public void run() {
            //UI changes
        }
    });

Or you can use YourActivity.this.runOnUiThread method of activity inside of your background-thread to run your UI related code.

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            //UI changes
        }
    });

Upvotes: 1

Related Questions