how android oncreate works? - android

On executing the following code, i found that the entire app freezes for 10000ms before showing anything on the emulator's screen. I would have expected the first Toast message to appear , followed by the app to freeze for 10000ms and the second toast message to appear. makes me wonder if android piles up all the code in the 'oncreate' method before executing it. is it supposed to be that way?
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, new ServiceCode("Hi").s, Toast.LENGTH_SHORT).show();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Toast.makeText(this, new ServiceCode("Hello").s, Toast.LENGTH_SHORT).show();
}

It behaves as expected. There is a single thread responsible for UI updates. It's called main thread. This thread shows toast messages too. When you call Toast.show(), Android schedules a new task for the main thread. When main thread is done with onCreate(), it will execute this task and show the toast. But because you blocked main thread for 10 seconds, no toasts are show. There is no one free, who can show this message. But then, 10 seconds later, both toasts will appear one after another, because main thread is free to show them.
Best practice is to never block the main thread. Otherwise your application will freeze and users will see ANR (application nor responding) message. If you need to execute something later in time, you need to post this task to the main thread's task queue for been executed later.
The code below will behave as you expect.
public class MainActivity extends Activity {
private Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// show first toast immediately
Toast.makeText(this, new ServiceCode("Hi").s, Toast.LENGTH_SHORT).show();
// schedule second toast to appear 10 sec later
handler.postDelayed(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this,
new ServiceCode("Hello").s, Toast.LENGTH_SHORT).show();
}
}, 10000);
}
}

When an Activity is created, the system-process would send a message to the UI thread of the Activity. The UI thread of the the Activity received the message and then executes "onCreate" method.
Here you make a toast in the "onCreate" method. That will not show the toast immediately. It only sends a message to the message queue of the UI thread. After you UI thread have fininshed the "onCreate" "onStart" "onResume" method, it receives the message of "Toast". At that moment, the Toast is actually showed on the screen.

The reason is simple, the show method of the Toast class might not be a synchronous call "internally", what I mean is, the main-thread is very unlikely to wait until the Toast is actually shown and rendered to continue, hence, it might start a functionality to start rendering the Toast BUT since you immediately after that force the main-thread to stop, it doesn't handle that request since main thread have the highest priority.
Hope it helps!
Regards!

check these links to know about the Android Life-Cycle
http://developer.android.com/training/basics/activity-lifecycle/index.html
Android activity life cycle - what are all these methods for?
your creating a Splash Screen,
if not remove
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
you App won't freeze.

Try this :
Toast.makeText(this, new ServiceCode("Hi").s, Toast.LENGTH_SHORT).show();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
Toast.makeText(this, new ServiceCode("Hello").s, Toast.LENGTH_SHORT).show();
}
}

The display of Toast is an asynchronous call.Thus, once the toast request is executed, the operating system jumps to the next operation and meanwhile the toast is prepared and displayed.
In your case since the next operation blocks the UI Thread for 10 sec the toast is not displayed until the UI Thread is released.

Related

Handler sending message to a dead thread after home button is pressed

I have function that must periodically run on the main thread of the application, and for this I use a Handler. The code looks like this:
keepDetecting = true;
final Handler handler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
#Override
public void run() {
try{
Utils.log("Detection service is running!");
myFunctionThatMustRunOnMainThread();
}
catch (Exception e) {
Utils.log(e.getClass().getSimpleName() + ": " + e.getMessage());
}
finally{
if(keepDetecting) {
handler.postDelayed(this, DETECTION_INTERVAL);
}
}
}
};
handler.post(runnable);
It works all good as long as the application is visible. However, after pressing the home button, I get the exception message: Handler sending message to a dead thread.
However, I know that the home button does not stop the application, and does not kill the main thead, so what is happening here?
I'm open to other ways to periodically run my function on the main thread, it needs to work if the user presses the home button as well.
EDIT: After further inspection I found that despite the handler throwing this exception once after the home button press, my function keeps getting executed periodically as if nothing happened. So I ended up ignoring this message.

Matter of Handlers execution in a sequence

I took this snipet from a site explaining handler in Android (a threading thing).
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread myThread = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 4; i++) {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i == 2) {
mUiHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(MyActivity.this, "I am at the middle of background task",
Toast.LENGTH_LONG)
.show();
}
});
}
}//ends for()
// THE SECOND HANDLER, RIGHT HERE!
mUiHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(MyActivity.this,
"Background task is completed",
Toast.LENGTH_LONG)
.show();
}
});
} //ends run()
});
myThread.start();
Judging from the task outputted in the second executed Handler, which is
Toast.makeText(MyActivity.this,
"Background task is completed",
Toast.LENGTH_LONG)
.show();
Seems like the writer of the article is pretty much sure that the second Handler will be executed last.
My question is that whether it's true that the second Handler will be executed last just after the first Handler finishes its job. Though, when I ran it multiple times, yes, it's executed last. In my mind, since the Handler is done in the background Thread then we're not supposed to know (even predict) which one the those two tasks the Handler will execute first. I need an explanation, thank you in advance.
My question is that whether it's true that the second handler will be
executed last just after the first handler finishes its job.
A Handler instance is associated to a single Thread (also called a message queue).
Runnables are executed on this Thread sequentially.
Calling post() will put the Runnable at the end of that queue, so yes, the second Runnable will be executed after the first one.
The outermost anonymous Runnable, the one passed to the new Thread(...) constructor, is what runs in the background thread. Everything inside that runnable will execute sequentially - one instruction after the other.
Since that runnable has a for loop and only after that the final toast appears you're guaranteed it'll run after the loop body.
There are not two handlers in play, just a single handler on the UI thread (mUiHandler). Your secondary thread is creating Runnable objects and posting them to the Handler. They will be executed by the handler in the order they are posted. Since the loop of the thread executes and posts first then the thread finishes by posting the "second" Runnable, that second one will always execute last, relative to the other things posted within the loop.

How do i add a delay to program before running selection query to avoid bind value being null?

I keep getting an illegal argument exception when running my app. However, this happens prior to the Toast messages coming up and that's why I think I need a delay.
Prior to adding on the DatabaseHelper class, my app was running and the proper value was coming up on both Toast messages, the one in the MainActivity and the one showing the intent value passed in the DisplayResult activity.
I'm not sure what to do at this point.
Just do a thread sleep in a runnable.
int timeYouWantToSleep = 60000;
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(timeYouWantToSleep);
//do your work here
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
If this doesn't work, you know it's not a delay that you need.

Do works in background indefinitely

I need to have a background thread that works indefinitely. I've wrote this code to define an IntentService:
public class RecordInternetUsageService extends IntentService {
public RecordInternetUsageService() {
super("test");
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
synchronized (this) {
try {
wait(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Toast.makeText(this, "test", Toast.LENGTH_LONG).show();
}
}
I have two questions, Is it a suitable class to do works indefinitely in background?
Why when I want to sleep this thread using by wait() method, Throws me an exception that mentioned below?
"sending message to a Handler on a dead thread".
And how can I solve this problem?
To do long processing task even when your application is closed i.e. in background one has to use Service... but you can do long processing work on that Main thread of Service or else you get ANR(android not responding). So you have to make a background thread and submit all the task on that background thread(That is done by Handle class) and handle all submitting and responding stuff... to wrap up this design pattern IntenServcie class is offered.
IntentService class automatically invokes the thread when a job is submitted and when the job is completed it kills the sevrice and frees up the memory. IntentSerive Exits as soon as it is done with its job.
The problem here is that you are creating a Toast inside a thread that is managed by the IntentService. The system will use the Handler associated with this thread to show and hide the Toast.
First the Toast will be shown correctly, but when the system tries to hide it, after the onHandleIntent method has finished, the error "sending message to a Handler on a dead thread" will be thrown because the thread in wich the Toast was created is no longer valid,.

Thread is not actually working

I'm a noobie in Java and Android I have a Thread question:
I have the following code that is triggered from android:onClick on the xml layout
The resulting behavior is that the UI waits 5 seconds and only after those 5 seconds, the ProgressDialog starts.
Shouldn't the Thread start independently and the dialog pop immediately?
Why is the Thread stopping the course of the procedure?
Thanks!
// (Button)
public void buttonReadGps(View v){
Thread readingGps = new Thread(){
public void run() {
// Read GPS code will go here
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
readingGps.run();
// Create a wait dialog
prgDialg = new ProgressDialog(context);
prgDialg.setTitle("Reading GPS...");
prgDialg.setMessage("Please wait.");
prgDialg.setCancelable(true);
prgDialg.setIndeterminate(true);
prgDialg.show();
}
Replace
readingGps.run();
with
readingGps.start();
The problem is the first version will just run your method synchronously and block the main thread. The second version actually starts a thread and continues, so the method will run asynchronously on a new thread.
This is such a common pattern in Android that the SDK gives a few classes to help: be sure to check out AsyncTask and possibly AsyncTaskLoader.

Categories

Resources