Reputation: 122
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
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