Android lifecycle/multithreading - android

I am developing an App that uses NFC.
When a new intent is discovered (NFC), the Activity goes to onStop state, then it executes onNewIntent code which executes a new Thread, in the middle of the Thread execution, the main Activity goes to onResume state, and then the thread keeps on with its execution.
Is there a way to control this sequence, I mean: Is there a way to execute onResume before the Thread, or at least to be sure that onResume is going to be executed before the Thread have finished?
EDIT:
To solve the issue, I put the Thread in sleep mode during 2000 milliseconds, this way the main activity takes the control and executes onResume, but this sounds like dirty workaround.
This way another problems came out, during those 2000 milliseconds, a new intent could be discovered, executing another Thread.
Thanks

When your thread completes, it could enqueue something (a Runnable, perhaps) to a queue. In onResume() you could then look in the queue and if there is anything there you could run it.

Related

How come the code is executed after intent redirection code?

I have this Android code:
Intent launchIntent = packageManager.getLaunchIntentForPackage(context.getPackageName());
cpa.startMainActivity(launchIntent.getComponent(), user);
// try to move down
if (dialogDismisser != null) {
dialogDismisser.run();
}
How can it be that the dialogDismisser is called even after cpa.startMainActivity?
Intent redirection is promised to only happen sometime in the future?
Starting an activity does not kill your thread. Your thread will continue to run, finish the function, and any other functions until its back at its looper or ends the thread. If you want to not execute the remaining code, you need to return.
The new Activity will start the next time the main thread gets a chance to look at its messages. So if this is called on a thread, the next context switch. If this is run on the main thread, then when it returns to the looper, after processing any other pending messages. (Assuming your starting an Activity in your own app. If not, it happens the next time the OS context switches to that app's main thread and that thread reaches the looper).
Intent redirection is promised to only happen sometime in the future?
Sure. It is an asynchronous operation. Moreover, the call results in starting a new (or bringng up already running) process through IPC without terminating the caller.

Can someone please explain how startActivity(intent) and startActivityForResult(intent) are Asynchronous?

If an Asynchronous thread is a thread that operates separately to the main thread and doesn't interfere with the main thread...
Does a new Activity not occupy the main thread after it has been started through startActivity(intent)?
The majority of what I have read on this says these are both asynchronous, however there are a fair few conflicting answers and the people that say this don't really give convincing arguments.
So if anyone who has this clear in their head and could explain why they are synchronous/asynchronous, I would be a very grateful man!
Cheers
EDIT: So the answer I have derived from these two good folk and some stuff online...
Bringing Activities into the mix of synchronous/asynchronous can cause a load of horse to come about. But it is still referring to the principles of...
Synchronous methods/commands must be completed before the call stack can continue.
Asynchronous methods/commands (commonly done in a thread/AsyncTask) continue in parallel allowing the main thread of execution to continue. (It can return in its own time)
The startActivity(intent) and startActivityForResult(intent) methods are Asynchronous as they are non-blocking and allow the thread of execution to continue whilst performing their corresponding task as well.
startActivity(intent) and startActivityForResult(intent) are asynchronous in the sense that these methods return immediately without starting an Activity. Actually, they schedule an Activity to start only after the lifecycle events of the current Activity is finished.
The takeaway is, if you have something, that takes some time to finish, in the onPause() method of the first activity , the new Activity will be slow to start.
When you startActivityForResult you still perform an asynchronous call. Your caller activity gets suspended and the new is started in another process (if it runs under a different user).
But when the called activity terminates setting a result, your activity is resumed and you get onActivityResult called as a callback containing the result.

what is the difference of thread.sleep and systemclock.sleep. and which one should be used in AsyncTask?

I figured out if I exit an activity while is running the AsyncTask in the middle, and when I try to start that activity again, I will have to wait until the previous AsyncTask to finish before the new AsynTask starts. I tried both thread.sleep and systemclock.sleep and it gives me the same result. Which make sense because I guess the thread that I closed and opened are the same. Its there a way to just cancel the AsyncTask if the user exit an activity? Because then the second time the user enter the same activity he wouldn't have to wait until previous finishes.
I tried asyntask.cancel(true) in onPause(), it doesn't work, same thing happened.
As I understand it, the only difference between Thread.sleep() and SystemClock.sleep() is that Thread.sleep() can be interrupted. That is, something like:
SystemClock.sleep(10*1000);
sleeps the calling thread for 10 seconds and that's that, you just have to wait. Whereas:
Thread.sleep(10*1000);
will also sleep the calling thread for 10 seconds. But if you have a reference to the sleeping thread from another thread, you now have the option of something like:
sleepingThread.interrupt();
which effectively wakes sleepingThread from its 10 second sleep.
In the context of your question, which is better for AsyncTask, I think it's still entirely up to your requirements. I don't know your exact code of course, but given your task's doInBackground is apparently doing some sleeping and given you want to be able to cancel your task at arbitrary times, Thread.sleep() might make more sense.

Execution Time of Activity Callbacks

This may have been hidden somewhere in the docs, but I don't remember seeing it:
Assuming everything is running on the same thread, would an activity callback, or any kind of callback for that matter, interrupt a runnable , or even some other callback, executing on the thread, or are they posted sequentially by time of occurance as messages similar to runnables?
It certainly doesn't interrupt execution, at least in the UI thread. For instance, say that you have a Button, and you place a Thread.sleep(10000) in its onClick callback. Well, as soon as you press the button the entire UI will freeze. This wouldn't happen if the onClick callback interrupted the UI thread's execution.
If you wanted to know all the answer of the question you need to use
http://developer.android.com/guide/developing/debugging/debugging-tracing.html
Depends on the Runnable.
All activity callbacks happen in the UI Thread. For example thread for onCreate is same as the thread which calls onTabSelected.
If you are started an AsyncTask, it runs in its own thread.
Try using following Log statement to check your scenario
Log.i("","Thread Id : "+Thread.currentThread().getId());

How to make a new instance of a Thread? [duplicate]

I am having a real hard time finding a way to start, stop, and restart a thread in Java.
Specifically, I have a class Task (currently implements Runnable) in a file Task.java. My main application needs to be able to START this task on a thread, STOP (kill) the thread when it needs to, and sometimes KILL & RESTART the thread...
My first attempt was with ExecutorService but I can't seem to find a way for it restart a task. When I use .shutdownnow() any future call to .execute() fails because the ExecutorService is "shutdown"...
So, how could I accomplish this?
Once a thread stops you cannot restart it. However, there is nothing stopping you from creating and starting a new thread.
Option 1: Create a new thread rather than trying to restart.
Option 2: Instead of letting the thread stop, have it wait and then when it receives notification you can allow it to do work again. This way the thread never stops and will never need to be restarted.
Edit based on comment:
To "kill" the thread you can do something like the following.
yourThread.setIsTerminating(true); // tell the thread to stop
yourThread.join(); // wait for the thread to stop
Review java.lang.Thread.
To start or restart (once a thread is stopped, you can't restart that same thread, but it doesn't matter; just create a new Thread instance):
// Create your Runnable instance
Task task = new Task(...);
// Start a thread and run your Runnable
Thread t = new Thread(task);
To stop it, have a method on your Task instance that sets a flag to tell the run method to exit; returning from run exits the thread. If your calling code needs to know the thread really has stopped before it returns, you can use join:
// Tell Task to stop
task.setStopFlag(true);
// Wait for it to do so
t.join();
Regarding restarting: Even though a Thread can't be restarted, you can reuse your Runnable instance with a new thread if it has state and such you want to keep; that comes to the same thing. Just make sure your Runnable is designed to allow multiple calls to run.
It is impossible to terminate a thread unless the code running in that thread checks for and allows termination.
You said: "Sadly I must kill/restart it ... I don't have complete control over the contents of the thread and for my situation it requires a restart"
If the contents of the thread does not allow for termination of its exectuion then you can not terminate that thread.
In your post you said: "My first attempt was with ExecutorService but I can't seem to find a way for it restart a task. When I use .shutdownnow()..."
If you look at the source of "shutdownnow" it just runs through and interrupts the currently running threads. This will not stop their execution unless the code in those threads checks to see if it has been ineterrupted and, if so, stops execution itself. So shutdownnow is probably not doing what you think.
Let me illustrate what I mean when I say that the contents of the thread must allow for that thread to be terminated:
myExecutor.execute(new Runnable() {
public void run() {
while (true) {
System.out.println("running");
}
}
});
myExecutor.shutdownnow();
That thread will continue to run forever, even though shutdownnow was called, because it never checks to see if it has been terminated or not. This thread, however, will shut down:
myExecutor.execute(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
System.out.println("running");
}
}
});
myExecutor.shutdownnow();
Since this thread checks to see whether or not it has been interrupted / shut down / terminated.
So if you want a thread that you can shut down, you need to make sure it checks to see if it has been interrupted. If you want a thread that you can "shut down" and "restart" you can make a runnable that can take new tasks as was mentioned before.
Why can you not shut down a running thread? Well I actually lied, you can call "yourThread.stop()" but why is this a bad idea? The thread could be in a synchronized (or other critical section, but we will limit ourselves to setions guarded by the syncrhonized key word here) section of code when you stop it. synch blocks are supposed to be executed in their entirity and only by one thread before being accessed by some other thread. If you stop a thread in the middle of a synch block, the protection put into place by the synch block is invalidated and your program will get into an unknown state. Developers make put stuff in synch blocks to keep things in synch, if you use threadInstance.stop() you destroy the meaning of synchronize, what the developer of that code was trying to accomplish and how the developer of that code expected his synchronized blocks to behave.
You can't restart a thread so your best option is to save the current state of the object at the time the thread was stopped and when operations need to continue on that object you can recreate that object using the saved and then start the new thread.
These two articles Swing Worker and Concurrency may help you determine the best solution for your problem.
As stated by Taylor L, you can't just "stop" a thread (by calling a simple method) due to the fact that it could leave your system in an unstable state as the external calling thread may not know what is going on inside your thread.
With this said, the best way to "stop" a thread is to have the thread keep an eye on itself and to have it know and understand when it should stop.
If your task is performing some kind of action in a loop there is a way to pause/restart processing, but I think it would have to be outside what the Thread API currently offers. If its a single shot process I am not aware of any way to suspend/restart without running into API that has been deprecated or is no longer allowed.
As for looped processes, the easiest way I could think of is that the code that spawns the Task instantiates a ReentrantLock and passes it to the task, as well as keeping a reference itself. Every time the Task enters its loop it attempts a lock on the ReentrantLock instance and when the loop completes it should unlock. You may want to encapsulate all this try/finally, making sure you let go of the lock at the end of the loop, even if an exception is thrown.
If you want to pause the task simply attempt a lock from the main code (since you kept a reference handy). What this will do is wait for the loop to complete and not let it start another iteration (since the main thread is holding a lock). To restart the thread simply unlock from the main code, this will allow the task to resume its loops.
To permanently stop the thread I would use the normal API or leave a flag in the Task and a setter for the flag (something like stopImmediately). When the loop encountered a true value for this flag it stops processing and completes the run method.
Sometimes if a Thread was started and it loaded a downside dynamic class which is processing with lots of Thread/currentThread sleep while ignoring interrupted Exception catch(es), one interrupt might not be enough to completely exit execution.
In that case, we can supply these loop-based interrupts:
while(th.isAlive()){
log.trace("Still processing Internally; Sending Interrupt;");
th.interrupt();
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
There's a difference between pausing a thread and stopping/killing it. If stopping for you mean killing the thread, then a restart simply means creating a new thread and launching.
There are methods for killing threads from a different thread (e.g., your spawner), but they are unsafe in general. It might be safer if your thread constantly checks some flag to see if it should continue (I assume there is some loop in your thread), and have the external "controller" change the state of that flag.
You can see a little more in:
http://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
May I ask why you want to kill the thread and restart it? Why not just have it wait until its services are needed again? Java has synchronization mechanisms exactly for that purpose. The thread will be sleeping until the controller notifies it to continue executing.
You can start a thread like:
Thread thread=new Thread(new Runnable() {
#Override
public void run() {
try {
//Do you task
}catch (Exception ex){
ex.printStackTrace();}
}
});
thread.start();
To stop a Thread:
thread.join();//it will kill you thread
//if you want to know whether your thread is alive or dead you can use
System.out.println("Thread is "+thread.isAlive());
Its advisable to create a new thread rather than restarting it.

Categories

Resources