I am experimenting with an app I am developping.
When I launch the app, there is currently a 3 second delay before the app UI is usable. During the delay the screen is black, apart from the task bar and, below it, the app title bar.
I was thinking about displaying a splashscreen as a dialog in the main Activity. However, it is only displayed after those 3 seconds, which makes it useless. This means that nearly all of the 3-second delay takes place between the launch and the call to
super.onCreate(savedInstanceState).
Can anyone educate me on what is happening behing the scenes during this delay ? Is there anything I can do to shorten it ?
Try to locate the slow code and put it into a second thread.
new Thread(new Runnable() {
#Override
public void run() {
// slow code goes here.
}
}).start();
Related
I have a progress bar that I change from View.GONE to View.VISIBLE, just before I call a method writeFile().
Something like this:
onButtonPress(){
mProgressBar.setVisibility(View.VISIBLE);
writeFile();
}
The method writeFile() can take a few seconds (lots of data parsing), but requires additional actions taken by the user afterwards, and thus is not performed on a background thread. This is to avoid the user navigating elsewhere within the app, and then being presented with a pop-up, or redirected, for something they thought they were done with.
My problem is that the Progress Bar does not display until the writeFile() method is complete, and then briefly pops up for a split second before the user is redirected elsewhere.
If I comment-out the method call, then the ProgressBar appears immediately and spins indefinitely, so I know the bar is working properly.
How can I ensure the progress bar pops up FIRST, and then the writeFile() method is called after?
Thanks in advance.
Additionally:
I don't have a lot of experience (exactly none!) with asynctasks, and so am not sure if this is the route I need to take. The behaviour I am looking for is the progress bar to pop up when the user presses the button, and remain on the screen until the method is complete. I don't want the user to navigate around the app during this time.
You can try the below code to check if the progressBar will be visible
new Thread(new Runnable() {
public void run() {
writeFile();
}
}).start();
My app takes a while to initiate (MainActivity), so I want a separate thread to show a loading indicator for 10 seconds (ignore all other touch events within this 10 seconds) then disappear automatically. How do I do this?
If your main activity takes several seconds to initialize, then the initialization is what should be on a separate thread, not the splash screen. You should never block the UI thread with time-consuming operations.
You can organize your initialization something like this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set up the splash screen
setContentView(R.layout.splash_screen);
// set up and start the initialization thread
final Handler handler = new Handler();
new Thread() {
public void run() {
// Do time-consuming initialization.
// When done:
handler.post(new Runnable() {
public void run() {
// set up the real UI
}
});
}
}.start();
}
That will remove the splash screen and replace it with the real UI after the time-consuming initialization is finished.
If you always want to wait a minimum of 10 seconds, you can record the start time in a local variable before starting the thread and then after initialization is finished, if there is still time left you can use postDelayed or postAtTime.
The above code uses a Handler and a Thread because what you want to do is fairly straightforward. As an alternative, you could use an AsyncTask, which does essentially the same thing. It also has built-in tools that allow you to "publish" initialization progress to the UI thread. See the docs for details.
Cover the Main Activity with splash screen(Any edge to edge image will do).
Display a progress bar using Progress Bar
Disable touch Events for the Splash screen so that the touch event doesn't pass towards the main activity screen.
Remove the Splash Screen from view when the loading is done in background or after a specific time.
Benefits:
No handlers/threads required because you stay in the main activity the whole time.
Updating progress bar will be a breeze because you stay in the UI thread the whole time.
Application less likely to crash because touch events are disabled during loading so no burden on UI thread.
I have a custom table layout where each row is a slide-able view. Everything is working fine, except there is a continuous delay between when a user starts sliding a when the view starts moving. Is there a way to reduce that starting delay?
I am building my table layout inside an async task. So at first I was getting an error about needing to use a looper. Since I didn't know how to do that I use runOnUiThread to handle the problem code. So now I am wondering if that's the reason for the slow response to touch. Here is the code
activity.runOnUiThread(new Runnable() {
public void run() {
handler.post(mResizeViews);
}
});
The question may be "What happen when user sliding?"
if you do some heavily task such as inflate layout when user start slide.
So, check what happen when user start sliding
I want to force android to wait AND continue processing something at the same time. I have seen the Thread wait function, but that just makes things hang for a while not actually letting the app do anything. Subsequent processes are simply queued up waiting their turn.
I want to force the timing of a process. This is kind of a combination between having a thread with a wait AND an asynctask
insight appreciated
public class yourActivity extends Activity{
final WebView yourWebview; //this is the webview
Context mContext = this;
public void onCreate(Bundle B){
setContentView(R.id.somethingtoshow);//this will be shown while webview working
Runnable yourRun = new Runnable(){
public void run(){
yourWebview = new WebView(mContext);
//do whatever you want with it
//loadUrl and whatever you want
//when your done
runOnUiThread(new Runnable(){
public void run(){
setContentView(yourWebView);
}
});
}
};
Thread T= new Thread(yourRun);
T.start();
}
}
'Waiting' means to put the thread in a suspended state - do you mean having the app simply do nothing until the process is completed?
You never want to make the main event thread hang or wait, that will make the user think the app is frozen. To do what you are wanting, you will probably spawn an async thread that loads the page from the main activity. The activity will continue to display whatever you had it doing last, and will not hang up or freeze while the async is going in the background. However, the user will still be able to press buttons, and might mess you up.
So to get the app to appear unfrozen and allow a process to occur in the background, you will want to enter into some loading screen or limit the user's options on the main layout. This will allow activity to continue occurring but allow the user a smooth experience.
My question is suppose i have to views(Screen). when i open my application from the emulator first screen should stay for just 5 secs and automatically new screen should appear(2nd).
i Know i can do this through timer concept but dnt know hwto do that in android?
So pls help me in this problem.
I completely agree with EboMike about not showing a splash screen. It's a bad practice with any app (desktop or android) and often just covers up sloppy programming. Get the user to do useful work as soon as possible and do any other startup work asynchronously.
However, sometimes lawyers are in charge of software, sometimes it's a marketing person, and sometime you just can't defer long startup code. In this case, you need an answer. The simplest is to have your main activity be your splash scree. In the splash screen activity, create a handler to start your real main activity doing something like this:
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
startActivity(...);
finish();
}
};
handler.sendEmptyMessageDelayed(0, 5000);