i got a FixedSizeThreadPool with 1 Thread(because i only Need one and every following request should wait till the earlier request has been finished):
myService = Executors.newFixedThreadPool(1);
myService.execute(new WorkerRunnable());
In my WorkerRunnable i do some stuff and in the middle i call a method from my Activity:
myActivity.thisMethodRunsOnUiThread();
The Method Looks like this:
public void thisMethodRunsOnUiThread() {
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
I'm trying to Change a View here, that's why i Need to do this on Ui Thread
}
});
}
And after that on the WorkerRunnable there Comes my last Method which should again run on the seperateThread from the fixedSizePool
myActivity.thisMethodsRunsonUiThread();
thisMethodRunsAgainOnTheSeperateThread();
But what i mentioned here is that he only calls the method which should RunOnUiThread after the MethodWhichShouldRunOnSeperateThread.(Which is the last method so my Thread would be finished at this time). Could it be that the seperateThread got a higher priority as the MainThread so that he waits till the seperateThread is finished and then he starts the method which runs on the UiThread?
I Need to finish the method
myActivity.thisMethodsRunsonUiThread();
before this method
thisMethodRunsAgainOnTheSeperateThread();
Can somebody explain why he acts like that? Any help is appreciated.
refer to http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)
if the current thread is not the UI thread, the action is posted to the event queue of the UI thread
Hence, this runnable must wait some time to be executed
You can use wait() and notify()/notifyAll() java methods for thread manipulation
Related
t1.speak("Hi sir", TextToSpeech.QUEUE_ADD, null);
onStart();
Blockquote
speak is not running and it directly skips to the on Start method but it run if i remove on start method .I want to go to the on start method once it complete speaking hi sir.
The speak method is asynchronous, and spawns a new thread that runs simultaneously to the code already running, so that's why execution does not "pause" and it simply continues to the next line.
You will have to have t1.speak() be the last instruction in whatever method contains it, and before calling speak, set an UtteranceProgressListener on your t1... and override the onDone() method like this:
#Override
public void onDone(String s) { // this method is called from a background thread...
runOnUiThread(new Runnable() { // ... so this is important :)
#Override
public void run() {
onStart(); // <-------- move your onStart here.
}
});
}
Here is a similar answer that you can use for complete details on how to set an UtteranceProgressListener.
I think this is a beginner (me) question, then for you guys is easy to answer.
I have this method:
public void onQuantityTextChange(final int value)
{
new Thread(new Runnable() {
public void run() {
addProductToCart(value);
view.post(new Runnable() {
public void run() {
updateTotals();
}
});
}
}).start();
}
My question is: this peace of code:
view.post(new Runnable() {
public void run() {
updateTotals();
}
is executed only when this addProductToCart(value); method is executed(finished)? or is it more safe to use AsyncTasks with doInBackground() and onPostExecute()?
It is always executed after: addProductToCart(value);
But if that function starts a Thread or AsyncThread or similar then the function will return before that task finishes.
To summarize: nobody can answer without the contents of addProductToCart
That largely depends on whether or not your method addProductToCart(value) starts another thread of its own. If it does, then there's no guarantee as the thread will start and finish as the system sees fit. If not, then you will not call view.post(...) until that thread is complete.
Another thing to watch out for depending on what you're trying to accomplish is the method inside view.post(...) is not guaranteed to run immediately. What this method does is put Runnable objects inside a message queue. This means, this runnable won't execute until the other elements in the message queue execute first. Secondly, the message queue can run at any time meaning even if this is the first Runnable in the queue it will start eventually, but not necessarily immediately.
In my app i am using soap webservice call , based on the webservice call reply i have to display some messages .,
But after the reply i could not able to do this from the spawned child thread
So how to get back to the main thread and display this after the reply i got
Hope this is clear.. help me how to achieve my requirement
{
Thread t1 = new Thread() {
public void run() {
String threadName = Thread.currentThread().getName();
// There will be delay in this statement while fetching a data from webservice
String returnfromWebservice = webservice(xmlDetails, "generateid");
Log.v("returnfromWebservice",returnfromWebservice);
if( ! returnfromWebservice.equalsIgnoreCase("nil")){
gotid = returnfromWebservice;
gotReply=true;
// dothis();// I could able to do this because this method contains widgets
// I am gettin the error : Only the original thread that created a view hierarchy can touch its views.
//I understand this is because childthread has no controls on widget
/**Suggest me how to get back to main thread*/
}
}};
t1.start();
dothis();// so i am doin here after the completion of it
}
public void dothis{
if(gotReply){
idtext.setText(gotid);
genId.setEnabled(false);
Toast.makeText(WelcomeScorer.this, "Generated ", 500).show();
}
else{
Toast.makeText(WelcomeScorer.this, "Try Once More ", 500).show();
idtext.setText(gotid);
}
}
I am new to android, Is there any best approach in android api to handle this situation ??
You should use the following code to touch your ui elements from another thread
youractivityname.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
}
});
If your thread is in same activity you can use this. Otherwise you should use your activity class object to run the above method.From your code you should call dothis(); after thread has done its job. From your it will call the dothis method immediately after thread has started it wont care whether thread has done its job or not.
The various methods are documented in this article. Using runOnUiThread is probably the simplest.
My service needs to check for something every minute and
while(true)
{
Thread.sleep(60000)
//REST OF CODE HERE//
}
is not working. Making the application freeze and asking me to forcefully stop it.
I am sure the problem is with the while loop but I thought it was the only way to infinitely repeat the service whenever the onStart() method executes.
Any suggestions are appreciated.
EDIT
I fixed it and in case you were wondering how the code looks like well there you go:
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Toast.makeText(this, "Service running", Toast.LENGTH_SHORT).show();
handler = new Handler(){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
Toast.makeText(protectionService.this, "5 secs has passed", Toast.LENGTH_SHORT).show();
}
};
new Thread(new Runnable(){
public void run() {
// TODO Auto-generated method stub
while(true)
{
try {
Thread.sleep(5000);
handler.sendEmptyMessage(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
Basically the service is been called and the tasks of that service will be repeated every 5 secs in that case.
I would like to thank vineetska, Janusz and inazaruk for suggesting to use Handlers. I would like to thank everyone who answered as well, your help was very much appreciated.
create a thread in your service and put while loop there like this:
new Thread(new Runnable(){
public void run() {
// TODO Auto-generated method stub
while(true)
{
Thread.sleep(60000)
//REST OF CODE HERE//
}
}
}).start();
Each of lifecycle method of service is called from UI thread. If you need background task to be running all the time, you can crate new thread for this. This is actually very well described in documentation.
In your case however, you should consider using AlarmManager instead. It handles recurring events very well and was specifically designed for similar scenarios.
Another solution would be to use Handler and its postDelayed() function. This can be used when your operation (that should be executed every 60s) is not time-consuming (or otherwise you should still run it in background thread).
Overall, creating a thread that sleeps all the time is not a good solution for mobile devices. This consumes resources that could've been spent for something more useful. Especially considering a rich set of capabilities of Android for recurring events.
A service itself is not a subthread. This means that every code that is run in your service will be run on the main UI Thread. You need to start a Thread, or use an AsyncTask in your service to move the computation to the background.
Have a look at the documentation of service for more information.
If you want to repeat some code every minute you can use a handler.
A handler has a method called postDelayed this allows you to specify a time after which a runnable will be run. Just call the method again at the end of your runnable to rerun the code after a minute.
Services run on the main thread. If you want to offload processing, you have to start a separate thread. Have a look at IntentService, it does this by default. On another note, having an infinitely running service with sleep() might not a good idea. For scheduled processing, you might want to use AlarmManager.
As Janusz wrote, you can use handler to post delayed. Here is a sample:
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
// Do repeatable stuff
handler.postDelayed(this, DELAYED_TIME);
}
};
handler.post(runnable);
It will post runnable and then post it again and again after DELAYED_TIME.
I'm trying to create a simple multiplayer game. There's a WorkerService which is supposed to handle all network communication and all interaction between this service and my Activities is done with AIDL. I think this is a standard approach - to enable two way interaction I use also an IWorkerCallback interface (also AIDL).
The problem is that callbacks have to change things in UI which may be done only in UI thread. I've created a Handler (in UI thread) and believed that this is an obvious solution. But, surprisingly, it's not working.
My LoungeActivity calls startServer() method of IWorker interface. Corresponding method of my WorkerService does some job and makes a callback - this works fine. Then WorkerService spawns a new thread and callback from this thread results in a bad Exception being thrown:
Can't create handler inside thread that has not called Looper.prepare()
Here's some code to make it clear:
startServer() implementation:
private void startServerImpl(String name, float latStart, float latEnd,
float lonStart, float lonEnd)
{
// some instructions here
// this works fine:
callback.notifySocketCreated();
// my naughty thread:
new ServerThread().start();
// some instructions here
}
ServerThread code:
private class ServerThread extends Thread {
#Override
public void run()
{
//some instructions here
// this call will cause an error
callback.notifyGameRegistered();
}
}
Every method from callback looks like that:
public void notifyGameRegistered() throws RemoteException
{
handler.dispatchMessage(handler.obtainMessage(CALLBACK_GAME_REGISTERED));
}
In Handler's handleMessage() method I'm doing a simple switch(msg.what) and in every case there's a simple UI modification (showing a Toast, changing Text, etc.).
I have no idea why is this Exception thrown.. I've managed to fix it by packing code into a Runnable and calling runOnUiThread() but it still makes me curious - shouldn't a Handler always run in thread that created it? Or maybe I'm doing something wrong?
I know this is a bit late - but the problem is that you called dispatchMessage().
The correct method is sendMessage().
dispatchMessage() will call handleMessage() on the same thread.
I am guessing the problem is not your Handler being on the wrong thread - but that the UI is trying to create a Handler somewhere in yout onHandle() method. Because onHandle() is called on the wrong thread, you are getting an exception.
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg)
{
if (msg.callback != null) {
handleCallback(msg);
} else {
handleMessage(msg);
}
}
You have to somehow call the offending function from the main thread.
The function that changes the UI should be in the activity that owns the UI.
This link should help you out:
http://android-developers.blogspot.com/2009/05/painless-threading.html