why ImageView can't update before SystemClock.sleep() - android

I want to show other image in ImageView within 3 second, after that rollover old image. The code:
OnClickListener oc = new OnClickListener() {
#Override
public void onClick(View v) {
ImageView iv = (ImageView)v;
iv.setImageResource(img2_id);
SystemClock.sleep(3000);
iv.setImageResource(img1_id);
}
}
myImageView.setOnClickListener(oc);
But it doesn't work? So, am I doing something wrong?

You are blocking the UI thread. Thus during the sleep command, the screen won't refresh. What you need is to schedule a non-blocking delayed call to a function which changes image resource. Here is a modified code that would do such a thing:
Handler mHandler = new Handler(); /*handler declared in your Activity thread, I assume*/
OnClickListener oc = new OnClickListener() {
#Override
public void onClick(View v) {
ImageView iv = (ImageView)v;
iv.setImageResource(img2_id);
mHandler.postDelayed(new Runnable(){
public void Run(){
iv.setImageResource(img1_id);
}
},3000);
}
}
myImageView.setOnClickListener(oc);

Related

Access view from Runnable cause memory leak?

This is a piece of code from the docs of android:
https://developer.android.com/guide/components/processes-and-threads.html.
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
final Bitmap bitmap =
loadImageFromNetwork("http://example.com/image.png");
mImageView.post(new Runnable() {
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
}
}).start();
}
My question is why it is ok to use mImageView inside the Runnable, I mean when we run this piece of code the mImageView might not be existed so this is a memory leak, am i right? If so, why people do that kind of thinks like reference a View inside a Runnable.

How I make an ImageView show-up immediatlly

public class MainActivity extends Activity {
ImageView img;
MediaPlayer failure;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bButton= (Button)findViewById(R.id.blueBtn);
img = (ImageView)findViewById(R.id.image);
img.setVisibility(View.VISIBLE);
failure= MediaPlayer.create(this,R.raw.failure_sound);
bButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
img.setVisibility(View.VISIBLE);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
failure.start();
}
});
}
well thats my code.
I just want to make that when I press the button it'll show the image
then wait 1000 miliseconds, and then make a sound.
BUT(!) unfortunaltly when I press that button: the process waits 1000 ms, and then make the sound and shows the img.
help plz!!!
Replace your onClick handler:
public void onClick(View v){
img.setVisibility(View.VISIBLE);
v.postDelayed(new Runnable() {
public void run() { failure.start(); }
},1000);
}
With Thread.sleep(10000); you are causing the main thread to freeze and thus the UI cannot be updated for that amount of time.
If you want to wait for a certain amount of time to do something, you may use a Handler instead, so the UI can be updated in the meantime:
public void onClick(View v){
img.setVisibility(View.VISIBLE);
new Handler().postDelayed(new Runnable() {
public void run() {
failure.start();
}
}, 1000);
}
You're putting your UI thread to sleep, which causes your app to freeze and the image not showing up.
A better approach for this is to use a handler, which will execute code after a delay and will not freeze your UI.
A quick adaption of your clickListener would be:
bButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
img.setVisibility(View.VISIBLE);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
failure.start();
}
}, 1000);
});
}

Android Why does this line of code execute after the for loop?

btnSwitch2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
btnSwitch2.setImageResource(R.drawable.on);
myVib.vibrate(50);
strobeFlash();
}
});
}
private void strobeFlash(){
for(int i=0; i<10;++i){
turnOnFlash2();
turnOffFlash2();
}
}
The code above executes when a button is pressed, I would like to change the picture of the image button. However, when the button is pressed, the for loop executes first then the line above it
btnSwitch2.setImageResource(R.drawable.on);
executes. Is there something I'm doing that's causing the loop to execute completely first?
Actually for loop execution is faster the then changing the image resource. You can add a postDelay() between the UI update and the for loop execution.
It will solve the issue.
btnSwitch2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
btnSwitch2.setImageResource(R.drawable.on);
myVib.vibrate(50);
handler=new Handler();
Runnable r=new Runnable() {
public void run() {
strobeFlash();
}
};
handler.postDelayed(r, 3000);
}
});
}
private void strobeFlash(){
for(int i=0; i<10;++i){
turnOnFlash2();
turnOffFlash2();
}
}

Android UI very slow

I'm creating a simple app that will stream the internet radio station. So when the user clicks the play button I want to show a progress bar (loading circle) until the stream is being played.
I have two Runnables, one to show the progress bar, other to load audio stream and play. This is a progress bar Runnable:
private Runnable showProgressBar = new Runnable() {
#Override
public void run() {
progBar.setVisibility(View.VISIBLE);
}
};
Than on button click:
buttonPlay.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Handler show_progress_h = new Handler();
show_progress_h.post(showProgressBar);
Handler play_h = new Handler();
play_h.post(startPlayingThread);
}
});
But... the progress bar loads much to late. It loads when the radio is almost loaded, so you only see it for a blink. Is it possible to show it immediately after the button was clicked? I have no idea what is slowing it down. Should I use something else instead of Handler?
Oh and btw... I also tried both with no handlers, but the response is the same.
The problem is you are posting long running task on UI thread immidiatly after showing progressbar:
buttonPlay.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Handler show_progress_h = new Handler();
show_progress_h.post(showProgressBar);
Handler play_h = new Handler();
play_h.post(startPlayingThread);//<< issue is here
}
});
Instead do something similar to this:
buttonPlay.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Handler show_progress_h = new Handler();
show_progress_h.post(showProgressBar);
new AsyncTask<Void, Void, Void>(){
#Override
protected void doInBackground(Void v){
// perform long runningtask here that you are performing in
//startPlayingThread
}
}.execute();
}
});
For more detail check this tutorial: http://www.vogella.com/articles/AndroidBackgroundProcessing/article.html#concurrency_asynchtask
You can use new Thread(your_runnable).start() as an alternative, and try debugging it.

update text constantly through for() loop and Handler

I am working on a Testing Project for me , just so I could learn more , so now I need to update the text of a TextView constantly every 250 milliseconds through a for(;;) loop , it happens after a Button click ... My problem is that whenever I press that button my app freezes (Yes my button is totally working , verified through previous testings) , I am using a handler to the Main thread doesn't get affected while the Runnable is up ... Here is my code of the Button and Handler ...
final Handler handler = new Handler();
B3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handler.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
for(;;){
String a = Shells.sendSingleCommand("free");//Here I send a command "free" and it returns its output
text.setText(a);//text is my TextView which is used through my experimentations ...
synchronized(this){
try{
wait(250);
}catch(Exception e){
}
}
}
}
});
}
});
If you need anymore info ask please :)
use handler.postDelayed for updating textview constantly every 250 milliseconds instead of using for loop to avoid freeze current Activity as :
Handler handler=new Handler();
B3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handler.post(runnable);
}
});
Runnable runnable=new Runnable(){
#Override
public void run() {
String a = Shells.sendSingleCommand("free");
text.setText(a);
handler.postDelayed(runnable, 250);
}
};
Android doesnt allow you to do long tasks in the main thread. If you need to do something like this I recommend moving the for loop and depdendent code into a separate thread..

Categories

Resources