how to sleep in for loop until finished loading page android - java

I am making an app to do something in webview automatically.
I want to make a pause between two lines inside (for-loop) until page finished loading without using Thread.sleep because it freezing my application.
this is my code:
webview.loadUrl("http://**********");
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
for(int i=1;i<10;i++){
evaluateJavascript( "document.getElementById('select').value=" + i)
evaluateJavascript("document.getElementById('Search').click();")
//wait until finished loading
while( isloading() ){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
evaluateJavascript( "document.getElementById('any_select').value=5")
.
.
.
.
}
public boolean isloading(){
boolean isloading;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webview.evaluateJavascript("(function() { return document.getElementById(\"Loading\").style.display; })();", new ValueCallback<String>() {
#Override
public void onReceiveValue(String s) {
if(s.equals("none")){
isloading=false;
}else{
isloading=true;
}
}
});
}
if(isloading=true)return true;
if(isloading=false)return false;
}

If you don't want to use Thread.sleep then the alternative is to use AsyncTask in your application.
You can do your loading task in doInBackground() method of AsyncTask and call it using new AsyncTaskClass.execute();
You can go through it from here : http://developer.android.com/reference/android/os/AsyncTask.html

You can do something similar (instead of AsyncTask):
Edit:
Timer timer = new Timer();
while( isloading() ){
try {
timer.schedule( new TimerTask(){
public void run() {
//
}
}, delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

If you want to achieve, what i understand, that once your second line is called you want to stop there and when after 1000 ms you want to continue. You can do one thing, copy all the code after your second line and put that in run method of below code:
new Handler().postDelayed(new Runnable()
{
#Override
public void run() {
}
}, 1000);
It will execute you code after 1000ms

If you want to execute sequentially actions happening on UIThread and in backgrounds threads you should be looking for the Bolt Library by Parse/Facebook.
It apply Javascript promises to Android application.
You can go through it from here : https://github.com/BoltsFramework/Bolts-Android

Related

Change Text after onWindowFocusChange() has been called

I'm trying to make a fighting screen where I have two sprites, and on top of them I have health bars with their health points written (ProgressBar with a TextView on top of it).
I also have a AnimationDrawable. And it is started inside of onWindowsFocusChanged(). I want to have the text in front of the progressBar change after the animation. So, for example, before the animation a bar has 150/150 written and after the animation I want it to change to, for example, 80/150. The thing is, whenever I try to call setText, the app crashes (I guess because onWindowFocusChanged is the last thing that's called). Is there a way to do this?
Here's a snippet of my code (number_one.start() is the starting of the animation):
private void health_bars(int points_one, int points_two){
healthBarOne.setMax(MAX_HEALTH);
healthBarOne.setProgress(points_one);
health_points_one.setText(points_one + "/" + MAX_HEALTH);
healthBarTwo.setMax(MAX_HEALTH);
healthBarTwo.setProgress(points_two);
health_points_two.setText(points_two + "/" + MAX_HEALTH);
}
public void onWindowFocusChanged(final boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus){
Thread th = new Thread(){
public void run(){
number_one.start();
try {
Thread.sleep(2000);
} catch(InterruptedException e){
}
health_bars(new_health_one, new_health_two);
try {
Thread.sleep(2000);
} catch(InterruptedException e){
}
finish();
}
};
th.start();
attackAnimation();
}
}
Thank you for your time!
EDIT:
Error Log
You cannot update UI elements from any other thread than UI. That is basically what the error is saying. To fix this, use runOnUiThread method in Android:
Thread th = new Thread(){
public void run(){
runOnUiThread(new Runnable() {
#Override
public void run() {
health_bars(new_health_one, new_health_two);
}
});
}
}

java update screen in thread

Im writing a script which consists of a thread with a wait. If the thread get executed, it doesn't update the screen. In the script i change a picture to another picture, but it doesn't show it until I press the button again. So the main question is: After setting an different Image Resource, i need to update the screen.
Here is the code:
public void Start(View view) {
Runnable r = new Runnable() {
#Override
public void run() {
int i =0;
while(i<12) {
synchronized (this) {
try {
Setfoto(i);
Thread.sleep(1000);
Log.i(TAG, "Begonnen met loop");
Log.i(TAG, "i = " + i);
i = i +1;
} catch (Exception e) {}
}
}
}
};
Thread buckysThread = new Thread(r);
buckysThread.start();
}
public void Setfoto(int nummer) {
if (nummer == 1) {
een.setImageResource(R.drawable.eerster);
Log.i(TAG, "Foto 1 wordt rood");
} if(nummer ==2) {
twee.setImageResource(R.drawable.eerster);
Log.i(TAG, "Foto 2 wordt rood");
} if(nummer ==3) {
drie.setImageResource(R.drawable.tweer);
Log.i(TAG, "Foto 3 wordt rood");
}
}
You'll need to have some sort of way to run code on the UI thread, which is responsible for updating the contents of the screen and manipulating views.
Activity.runOnUiThread(Runnable) can be called. Any code placed in there will be run on the UI thread.
You can use runOnUiThread, AsyncTask or Thread-Handler to implement your task
Activity.runOnUiThread
runOnUiThread(new Runnable() {
public void run() {
//Do something on UiThread
}
});
Thread-Handler
Communicating with the UI Thread
AsyncTask
AsyncTask Tutorial

Start an Activity from Splash Screen, should I use run() or runOnUiThread()?

I have a Splash Screen (Logo Activity) to show the company name for 3 seconds before app starts. I start Main Activity from a thread, here is the code:
public class Logo extends Activity {
Thread t;
public boolean dead = false;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.logo);
t = new Thread() {
public void run() {
try {
Intent i = new Intent(Logo.this, Main.class);
Thread.sleep(3000);
if (!dead) {
startActivity(i);
}
finish();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t.start();
}
The Main Activity is called from a worked thread, is this correct? What are the differents with this code (using runOnUiThread)?
...
if (!dead) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Intent i = new Intent(Logo.this, Main.class);
startActivity(i);
}
});
}
...
I see no difference with this code in debug mode (The same threads, the same operation, etc.). Which is correct?
Starting an intent I think is not an UI operation. runOnUI thread runs UI operation on UI thread. So you can use either of thread (runOnUI or normal). May be normal thread will be good in this situation. But I would like to suggest you use timer instead.
To be honest, I don't like the Thread.sleep. PLease take a look at my solution:
new Timer().schedule(new TimerTask() {
#Override
public void run() {
// Do your work here like... startActivity...
}
}, SPLASH_DURATION); // SPLASH_DURATION IS IN MILLISECONDS LIKE 3000
Also you can block the user to prevent the back key like this:
#Override
public void onBackPressed() {
// do nothing! disable user interaction!
}
You should use AsyncTask in "doInBackground" background thread and than sleep your thread(this thread not UIThread) "PostExecute" run on UI Thread than start your new activity
private class mSplashViewer extends AsyncTask<Void,Void,Void>{
protected void doInBackground(Void params){
Thread.currentThread().sleep(3000);
return null;
}
protected void onPostExecute(){
startActivity(...);
}
}

Avoid multi-click in image view android

I try to use this code to prevent multi-click in ImageView but it doesn't help.
Boolean isClicked = false;
#Override
public void onClick(View v)
{
if (v == imgClick && !isClicked)
{
//lock the image
isClicked = true;
Log.d(TAG, "button click");
try
{
//I try to do some thing and then release the image view
Thread.sleep(2000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
isClicked = false;
}
}
In the log cat, I can see 5 lines "button click" when I click on ImageView for 5 times as quickly as possible. I can see the log cat print the first line, wait for a while (2 seconds) and then print the next line. I think when I click the ImageView, the fired event is moved to queue in order, isn't it?. So how can I stop that?
I also try to use setEnable() or setClickable() instead of isClicked variable but it doesn't work too.
Just try this working code
Boolean canClick = true; //make global variable
Handler myHandler = new Handler();
#Override
public void onClick(View v)
{
if (canClick)
{
canClick= false; //lock the image
myHandler.postDelayed(mMyRunnable, 2000);
//perform your action here
}
}
/* give some delay..*/
private Runnable mMyRunnable = new Runnable()
{
#Override
public void run()
{
canClick = true;
myHandler.removeMessages(0);
}
};
Instead of sleeping in 2 seconds, I use some task like doSomeThing() method (has accessed UI thread), and I don't know when it completed. So how can I try your way?
//I referred this android link. You can handle thread more efficiently but i hope below code will work for you..
//you try this and
Boolean canClick = true; //make global variable
public void onClick(View v) {
if(canClick){
new DownloadImageTask().execute();
}
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
protected Bitmap doInBackground(String... urls) {
Log.d("MSG","Clicked");
canClick =false;
//perform your long operation here
return null;
}
protected void onPostExecute(Bitmap result) {
canClick =true;
}
}
You could keep track of the last consumed click upon your View, and based on it either perform the necessary actions, or simply return:
private long calcTime;
private boolean isClickedLately(final long millisToWait)
{
if (System.currentTimeMillis() - calcTime < millisToWait)
return true;
return false;
}
#Override
public void onClick(View v)
{
if (isClickedLately(2000))
return;
calcTime = System.currentTimeMillis();
Log.d(TAG, "consuming button click");
// perform the necessary actions
}
With the millisToWait parameter you can adjust the threshold of "waiting", but if you know that you want to wait exactly 2 seconds between two consecutive clicks, you can eliminate it.
This way you don't have to deal with Threads, which is good, since it's not a great idea to make the gui thread wait.

How can I use delay on textview for show text?

When i click button first time. Program will random text. then when i press button again it will delay slow to show text
my code
public void onClick(View v) {
final MediaPlayer mp = MediaPlayer.create(getBaseContext(), R.raw.yeehaw);
showRandom = !showRandom;
t = new Thread() {
public void run() {
try {
while(showRandom) {
sleep(5);
mp.start();
handler.sendMessage(handler.obtainMessage());
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
};
t.start();
}
Your context isnt clear from your question still i can see that you are trying to delay the thread execution by 5 ms that would not be noticible to you. Increase the sleep duration to see if you overcome you issue.
PFB the detail for the sleep method here
http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html
Thanks!

Categories