Intentionally force android to wait AND load something in background - android

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.

Related

When I use runOnUIThread thread.join doesn't work

I'm creating an android application and i want when user press back button show an quick animation and then finish current activity.
I'm using following code for do this:
public void onBackPressed() {
Thread t = new Thread(){
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
animate();
}
});
}
};
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
this.finish();
}
But it doesn't work.
Don't use join. Using join pauses the main thread until it is finished. But you can't redraw until the main thread returns to the Looper and processes invalidate events. So the entire thing won't work- your code is basically doing the same thing as if you hadn't run a thread at all.
Never wait on the UI thread- that means not only sleep but also join. Instead, when the animation is finished you call finish then, and just return after you call thread.start. But all of this is extremely overly complicated, for what you're doing just post a message to a Handler.
I'm creating an android application and i want when user press back button show an quick animation and then finish current activity.
Personally, I do not recommend this. Think of it this way: when you press the BACK button in a desktop Web browser, how angry would you be if the Web site decided to display an ad before taking you back to the preceding page?
But it doesn't work.
onBackPressed() is called on the main application thread. You then create and start() a background thread. You then immediately call join(), to block the main application thread until the background thread ends.
This has two problems:
The background thread is pointless, as you are blocking the main application thread until that background thread is done.
runOnUiThread() takes your Runnable and arranges to run it on the main application thread. That cannot happen immediately, because you are blocking the main application thread.
Your code has the same effect as this:
public void onBackPressed() {
runOnUiThread(new Runnable() {
#Override
public void run() {
animate();
}
});
this.finish();
}
As a result, animate() will not be called until after the activity has finished.
A typical solution is to attach a listener to the animation, to be invoked when the animation is complete. Then, the listener can call finish(). Another solution is to schedule a Runnable, using postDelayed() on some View, to be invoked after a certain amount of time, using a value that matches your expected animation run time. Then, the Runnable you pass to postDelayed() could call finish().
But, again, I do not recommend interfering with BACK button processing. I do not know what the user experience will be like on an Android 7.0+ multi-window environment (e.g., Chrome OS devices, Samsung DeX).

Android another Thread

Everyone knows that when you are manipulating with Database you should do that in another Thread. But I don't understand is that really necessary when you are just inserting one item for example, or when it is happening when user opens Activity or Fragment for example and data is just loading from Database you user would wait for loading ending whatever.
Maybe it even stops app a bit while creating new Thread ect.
So what do you think is that "must be" to create new Threads?
A thread should be used in a long running process that would block the UI from updating. If it's more than a second or two you might want to put it into a background thread and notify the user with a dialog or spinner or something. If you lock the UI thread for more than 5 seconds the user will be prompted with a kill or wait option by the OS.
To have a good user experience heavy works should run in another thread, in this way there aren't any lags or blocks and the user experience is better.
The time taken to create a new thread is a lot less than the time taken to performe a query or an http request or other heavy works. Maybe on your phone this time is short but on low level phone it can take more time. After 5s Android shows to the user an allert to ask if user wants kill the app or wait, this isn't good.
Another point, it's true that the user must wait data to use it BUT if you performe a request in main thread the view will blocked, if you do it in another thread thed view is smooth, you can show easy a progress bar and if user want return back the app still responsive.
I can understand that send messages beetwen threads isn't easy like do it in main thread, but if you use a bus, like OTTO Bus (http://square.github.io/otto/) and extend the bus class in this way
public class AndroidBus extends Bus{
private final Handler mainThread = new Handler(Looper.getMainLooper());
#Override
public void post(final Object event) {
if (Looper.myLooper() == Looper.getMainLooper()) {
super.post(event);
} else {
mainThread.post(new Runnable() {
#Override
public void run() {
post(event);
}
});
}
}
}
In this way u can easly send messages beetwen threads

Android onCreate loading delay

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.

Indeterminate Progress Bar only shows very briefly at the end of the operation

I want it to show up as soon as I click the login button, but it only shows after the loggin process has finished
What am i doing wrong
runOnUiThread(new Runnable() {
public void run() {
mProgress.setVisibility(View.VISIBLE);
}
});
doLogin();
mProgress.setVisibility(View.INVISIBLE);
Since you are using another thread to show the Visibility, the runnable might get scheduled any time in the future. That is the reason it is being shown late.
Maybe adding a sleep routine in current thread immediately after runonuithread call might schedule the runnable, but you can never be really sure.
Edit: Or you could create a Handler which shows Progress bar and wait for it to be shown and then continue
The reason You don't see the loading dialog is that you call a blocking function in your GUI thread/MAIN thread.When you set your dialog to visible you should let the GUI thread to keep running so it can draw the dialog on the screen.Moreover after 5 seconds that the GUI thread is blocked, the user will be presented with FORCE CLOSE/Wait pop up.
It is a bad practice to preform long operation of the gui thread, you MUST only can non blocking function in it.
Here is how you should do it:
//make sure mProgress is final
mProgress.setVisibility(View.VISIBLE);
new Thread(){
public void run(){
doLogin();
mProgress.setVisibility(View.INVISIBLE);
}
}.start();

Android - Starting a thread crashes app

I've got a few activities. In the main activity I have a login screen, when the user presses the login button, a thread is started to show a progress dialog until the user has been authenticated. At this point i load the next activity which has several fields for the user to input data.
Here the user inputs some data and presses a button to process it. The data is passed to a new activity where the data is actually processed and displayed. This is where i create the new thread and where it's crashing when i call thread.start(); and I have no idea why this is happening.
Both activities are implementing Runnable.
I'm using the same code below to create and call thread.start() in the button press of the first activity and the onCreate method of the last one:
pd = ProgressDialog.show(search_results.this, "", "Searching...", true, false);
Thread thread = new Thread(this);
thread.start();
I'm using the same code below as well to handle the threads for both as well.
public void run() {
handler.sendEmptyMessage(0);
}
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
pd.dismiss();
}
};
Am I missing something? I don't really understand why it's crashing.
While I encourage people to use AsyncTask, it's not really needed, especially for simple things like progress/loading dialogs. That's not the problem here.
Your question and your code is confusing. I'm not sure which code goes where, on which activity, and I hope you're not leaving dialogs open between activities, trying to access them across them (it won't work, of course). Also, providing a Context to a Thread does not even compile (it's marked with errors at design time). To sum it all up, you didn't provide the Log entry. Sorry, I can't make sense of what you're doing or where the error is. We can only guess.
Below are one of the possible ways to do it with a Handler, a Runnable and a Thread. This was taken from the Developer Resource when I first learn how to use it:
1- You declare a Handler. Most people do this on the onCreate section to reuse it often:
Handler mHandler = new Handler();
2- When you need, you start a Thread:
new Thread() { public void run() {
mHandler.post(mLoadingData);
// ... do work
mHandler.post(mLoadingDataStop);
}}.start()
3- These are the Runnables that are posted to the Handler:
private final Runnable mLoadingData = new Runnable() {public void run() {
showDialog(LOADING_DIALOG); // In your case, show your custom dialog
}};
private final Runnable mLoadingDataStop = new Runnable() {public void run() {
dismissDialog(LOADING_DIALOG); // In your case, dismiss the dialog
}};
For a progress dialog, things need a bit more work (update the progress etc.), but for a loading dialog, you don't need to really mess with messages.
I had this same issue when developing for the tablet. After a certain API, I'm thinking 3.0 (sdk 11), Android enforces applications to run long running processes on a separate thread, otherwise it kills it. Logcat will confirm this.
I know you are using another thread, but that didn't work for me either. Try using AsyncTask. You can create a quick inner class that, in my opinion, is way easier than handling your own threads. AsyncTask has several functions that run on the UI thread and a couple that run on their own thread. This allows you to start a "Loading" user interface object on the user interface thread, process on the back end thread, and then when its done, it'll notify a user interface thread function.
You'll want to specifically look at override
onPreExecute()
doInBackground()
onPostExecute()

Categories

Resources