ImageView image = (ImageView) findViewById(R.id.imageview);
image.setImageResource(drawable.image1);
SystemClock.sleep(1000);
image.setImageResource(drawable.image2);
I am trying to change the image for a second, my code above doesn't work but not sure why?
Should I be using a thread? or does anyone have any better ideas?
EDIT
To clarify on the problem:
The image being displayed as "drawable.image2"
I want "drawable.image1" to be shown for one second then change to "drawable.image2".
EDIT2:
This code is used in the onClick. When a user clicks the image it needs to change for one second
I'd recommend using a TimerTask with a Timer. You can set it up like this:
protected void showDelayedImages() {
mImageView.setImageResource(resId1);
Timer timer = new Timer();
timer.schedule( new MyTimerTask(), 1000 );
}
private class MyTimerTask extends TimerTask {
#Override
public void run() {
runOnUiThread( new Runnable() {
#Override
public void run() {
mImageView.setImageResource(resId2);
}
} );
}
}
Thread.sleep(1000);
should do it. Although there are better ways too.
Use debug mode and set breakpoints on each call to setImageResource. Step through and see if each is getting called to see if your image is changing properly.
In real world cases, you probably want to change the image based on some user action, or for example change an icon while a thread is processing, then change it bad when complete. For this example check out AsyncTask.
use R.drawable.image1 instead of drawable.image1
It looks like you're performing the "switch" in an onCreate() method, the sleep will probably just make your Activity load slower since at this stage there isn't actually anything written to the page.
To have your image change you need to perform the switch on the UI thread and you need to perform it after the image has been inflated and added to the page.
Try adding this code in an "onClick" event.
Related
I have a TextView on my splash screen and I'm trying to emulate Discord's randomized loading text.
I have the following code, pulled from here:
private void LoadText() {
Runnable runnable = new Runnable() {
#Override
public void run() {
final TextView loadingTextView = findViewById(R.id.loading);
loadingTextView.setText(FetchRandomLoadingText());
}
};
ScheduledExecutorService ex = Executors.newScheduledThreadPool(1);
ex.scheduleAtFixedRate(runnable, 0, 5, TimeUnit.SECONDS);
}
FetchRandomLoadingText() returns a string from an ArrayList by index, works fine (tested with Toast to make sure it wasn't the problem).
This is working fine for one or two updates, but if the splash takes longer (slow internet connection for example) to do its thing, the text stops updating after 2 iterations.
I've looked at the equivalent of setInterval in JavaScript for Java but the solutions seems to iterate once and then stop all together.
Am I missing something obvious in getting this to endlessly run until I flag for a new Activity to be loaded?
I'd use a handler instead of a scheduler.
long delay = 5000; //5 seconds
final TextView loadingTextView = findViewById(R.id.loading);
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
loadingTextView.setText(FetchRandomLoadingText());
handler.postDelayed(this, delay);
}
};
handler.post(runnable);
I would also test to make sure FetchRandomLoadingText() runs like you expect it to. Maybe run it 20 times and print the results in a dummy activity
Andrew's code is what I've been using in production but with a slight change. I did some profiling on the code during execution and noticed a slight memory leak if my splash screen didn't change to the main activity (by design when I found the bug). I left the above code running for around 20 minutes by mistake, and found that the app began running 10s of mb over what should be realistic for a simple Activity with a TextView.
The altered, memory leak free code should have handler and runnable declared at a class level and instantiated in the onCreate function, rather than inside the local execution block. Doing so not only prevents the memory leak, but also executes faster.
I have been working from an example I found, here's the link to the Git repo:
https://github.com/basakpie/vaadin8-spring-security-sample
It works great, it's just what I need, except for one thing: I need Server Push.
Here's what I've done so far:
added the Vaadin Push dependency
added the following lines to the start of the MainUI.init() method:
getPushConfiguration().setTransport(Transport.WEBSOCKET);
getPushConfiguration().setPushMode(PushMode.AUTOMATIC);
Added the following fields to the MainUI class:
Label time = new Label();
Timer timer;
Added the following method to the MainUI class:
private void updateTime() {
access(() -> time.setValue(String.format("The server-side time is %s", LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")))));
}
Finally, added the following to the end of the MainUI.init() method:
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
updateTime();
}
}, 1000L, 1000L);
It mostly works. I am able to see the current system time updating every second. But when I hit refresh in the browser, the application just hangs with the vaadin loading spinner. There are no error messages.
I have tried the following alternatives:
Adding the method
public void attach() {
getPushConfiguration().setTransport(Transport.WEBSOCKET);
getPushConfiguration().setPushMode(PushMode.AUTOMATIC);
}
and removing the getPushConfiguration lines from init()
This solves the hanging problem, but the push does not work - no errors, just the time is not displayed at all.
I also tried adding a #Push annotation to MainUI. This results in the same behaviour as before - freezing on refresh.
How can I fix this? Any suggestions would be welcome.
Try out the below procedure:
Add #Push to the MainUI.java file
#Push(transport = Transport.WEBSOCKET,value = PushMode.AUTOMATIC)
Instead of :
getPushConfiguration().setTransport(Transport.WEBSOCKET);
getPushConfiguration().setPushMode(PushMode.AUTOMATIC);
Add #PreDestroy to exit the timer when you navigate from the mainUI
#PreDestroy
void destroy() {
timer.cancel();
}
Find the complete revised code HERE
https://gist.github.com/cansoftinc/351452ee0e616d353519f147c4a961ba
I Had exactly the same problem and my solution to this was to implement the vaadin servlet. Check this for more information.
I am making a library where an application can use it to capture a selection of a screen and convert it to an image, like Gyazo.
This library is not the application itself, but only the tool that returns the File or BufferedImage object to the application.
I want the application to be simple as this:
Bootstrap b = new Boostrap(new GifCapturer());
b.beginCapture(); // user selects an area
File file = b.getFile();
But how can I make the application wait till the library returns the object? as you see the beginCapture method should activate the JFrame where the user will select an area to capture.
Do I need to sleep the thread? or use listeners design?
The beginCapture method starts a jframe window, where the user is able to select an area of the screen. Once selected, the library will convert the selected area to an object and set it as a local variable. So when you will use getFile it ill return the captured image. But the thing is, i need to make sure that the image was selected before getFile call gets executed, and wait instead but im not sure how.
Sorry if the question is not detailed, im on phone.
Please let me know if you need more information.
Implement a listener, that is invoked as soon the selection is ready. Put your File file = b.getFile(); code into the listener.
The code of your JFrame would be necessary to give a more detailed answer.
I have decided to use a Listener with a own built listener class, and interface.
Create an interface which you will use to get the data, or that will get know when the listener gets called, like this in my case:
public static void main(String[] args) throws AWTException {
Bootstrap b = new Bootstrap(new GifCapturer());
b.beginCapture(new ScreenCaptureCallback() {
#Override
public void captureEnded(File file) {
System.out.println("done!");
}
});
}
In one of my adapters for a custom ListView, I have a piece of code to insert a Bitmap into an ImageView that looks something like this :
Handler handler = new Handler(context.getMainLooper());
handler.post(new Runnable()
{
#Override
public void run()
{
imageView.setImageBitmap(bitmap);
}
});
Except that I'm passing on the Handler along with a callback (that is later wrapped in the Runnable), to a different thread which computes the Bitmap to be displayed and then posts the results on to the provided handler.
And every time the ListView is updated, the contents flicker a couple of times.
I'm aware that AsyncTasks are primarily for this purpose. But I'd still like to know what is causing the screen to flicker.
I am trying to write some Activity tests for an app, and one particular scenario that I want to test is that when I click a certain button, the Activity view updates accordingly. However, clicking the button causes a somewhat long running asynchronous task to start and only after that task is completed does the view change.
How can I test this? I'm currently trying to use the ActivityInstrumentationTestCase2 class to accomplish this, but am having trouble figuring out how to have the test 'wait' until the asynchronous part of the button click task is complete and the view updates.
The most common and simplest solution is to use Thread.sleep():
public void testFoo() {
TextView textView = (TextView) myActivity.findViewById(com.company.app.R.id.text);
assertEquals("text should be empty", "", textView.getText());
// simulate a button click, which start an AsyncTask and update TextView when done.
final Button button = (Button) myActivity.findViewById(com.company.app.R.id.refresh);
myActivity.runOnUiThread(new Runnable() {
public void run() {
button.performClick();
}
});
// assume AsyncTask will be finished in 6 seconds.
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
assertEquals("text should be refreshed", "refreshed", textView.getText());
}
Hope this helps.
If you're using Eclipse, you could use the debugger by setting a breakpoint in the code that updates the view. You could also set some breakpoints in the long running task to watch and ensure that all your code is executing.
An alternative, write some log or console outputs in your long-running task and the view updater code, so you can see the progress without interrupting the thread by a debugger.
As a piece of advise, if its a long-running process, you should be showing a progress bar of some description to the user, so they aren't stuck there thinking "Is something happening?". If you use a progress bar with a maximum value, you can update it in your long-running task as it is running, so the user can see the activity going from 10% to 20%... etc.
Sorry if you were expecting some kind of jUnit-specific answer.
I ended up solving this by using the Robotium library's Solo.waitForText method that takes a string and timeout period and blocks until either the expected text appears or the timeout occurs. Great UI testing library.