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.
Related
I am writing an Android application that interfaces with the Motorola EMDK, and I am running into an issue with timing/threading. I have an activity that adds a fragment to perform a very specific function using the EMDK, displays a screen that tells the user what is happening and then is cleaned up by the activity after about 15 seconds.
I am noticing a 1-2 second delay between when the EMDK action occurs, in this case the device cradle is being unlocked, and when the GUI is displayed that says "The cradle is now unlocked."
I have done some research about how Android handles drawing to the screen for fragments, and everything I can find says that onResume is called "when the fragment becomes visible." This does not match my experience, however. According to how I understand the code below should work, the screen should be drawn and then the EMDKManager.getEMDKManager() method is called, which constructs a pointer to the EMDK service and creates a new thread to perform the unlock:
#Override
public void onResume() {
super.onResume();
EMDKManager.getEMDKManager(getActivity().getApplicationContext(), this);
}
It looks more like the screen is drawn to only once onResume() completes in entirety, ie EMDKManager.getEMDKManager() finishes its call as well.
As the fragment is the EMDKListener object that is required for the second parameter for the method, I am struggling finding a way to thread this correctly. I need the GUI to be drawn first or at the same time that the cradle unlock occurs.
Are there any other methods that can be overridden or interfaced with to get the equivalent to an onViewDrawn() event for the fragment?
Thank you very much.
All the lifecycle method onCreate(), onResume() onStop() etc. are called by the main thread, which is also responsible for drawing the UI.
By preforming a long operation in those method, you block the UI thread from handling touch input as well as drawing the app
you can start your long operation on another thread by doing so:
new Thread(new Runnable() {
#Override
public void run() {
// do long operations here
}
}.start();
note that if that operation wants to update the UI components it MUST be done on the UI thread, you can do so by passing a runnable to the activity
activity.runOnUiThread(new Runnable() {
public void run() {
// do UI updating but, do not block it here
}
});
(or you can create an handler if it's a Service or you want to delay those runnables)
Although I have huge concerns about memory use/leaks, I did this in order to get the timing right:
private EMDKManager.EMDKListener getThis() {
return this;
}
private Runnable initEMDK = new Runnable() {
#Override
public void run() {
EMDKManager.getEMDKManager(getActivity().getApplicationContext(), getThis());
}
};
#Override
public void onResume() {
super.onResume();
Log.v(LOGTAG, "Starting");
new Thread(initEMDK).start();
}
I feel like there is a standard way of doing the getThis() method. If you know it, I would love to know.
Thank you.
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
long time watcher, first time writer :P
I got this problem:
I can't seem to change anything that has to do with the layout of android from my playSoundThread.
In this example, I use EventListeners. I already tried the simple way. I passed the ScrollView through, so that the thread can change it. But when it's happening, the thread stops immediately. And even when I use EventListeners, the same Problem occurs.
Changing a variable and posting log information works fine, but not layout Objects.
The first thing is, that I want to scroll a HorizontalScrollView from out the Thread's run() method.
the second case is, that, if the thread comes to it's end, I wanna fire an "i'm finished"-Event and change the image and function of an ImageButton
Here's the run()-method of the thread
public void run() {
if(this.playbackPosition < rhythm.tracks.get(0).sounds.size()) {
for (Track t : rhythm.tracks) {
if (t.sounds.get(this.playbackPosition).equals("1")) {
this.sp.play(t.SoundID, 1, 1, 1, 0, 1);
}
}
this.playbackPosition++;
if ( this.playbackPosition >= (this.scrollIndex*(192/this.zoom)) ){
this.scrollIndex++;
//Here I wanna fire the "Scroll" event
for(ScrollListener sl : scrollListeners){
sl.update(scrollPositions[scrollIndex]);
}
}
}
//This is the point where the playback is finished and the event to change a button is fired
else {
tmpListener.update();
}
}
}
The declaration of the OnPlaybackFinishedListener can be found in the class Player, which is the parent of the PlaySoundThread:
public void addOnPlaybackFinishedListener(){
tmpListener = new OnPlaybackFinishedListener() {
#Override
public void update() {
scheduledExecutorService.shutdown();
//this is a seconds Listener, which was implemented to test, if the problem still occurs with a little listener chain
shutdownListener.update();
}
};
}
public void addShutdownListener(OnExecutorShutdown sl){
this.shutdownListener = sl;
}
And here's the part of the MainActivity which is the parent class of Player and adds the shutdown listener and the ScrollListener:
awesomePlayer.addScrollListener(new ScrollListener(){
public void update(int position){
Log.i("ScrollListener update()","Running ScrollTo( "+position+", "+VIEW_rhythmscroll.getScrollY()+")");
VIEW_rhythmscroll.scrollTo(position, VIEW_rhythmscroll.getScrollY());
}
});
awesomePlayer.addOnPlaybackFinishedListener();
awesomePlayer.addShutdownListener(new OnExecutorShutdown() {
#Override
public void update() {
// TODO Auto-generated method stub
//This method changes the Pause Button to a Play Button with a new OnClickListener and a new Picture
BUTTON_STOP.performClick();
}
});
Can anyone help? Is there another way to avoid this problem? I'm developing on Android 2.2
Is it even possible to access UI elements from a thread?
Thanks in advance :)
You can't modify UI elements from a seperate thread, UI elements have to be modified from the main, UI Thread. There are a lot of topics on this, but you can update the UI by using an AsyncTask's onPostExecute(), onPreExecute(), or onProgressUpdate() methods, the Activity class's runOnUiThread(Runnable action), or by sending a Message to a Handler.
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.
I have a Start button to start my function for downloading data(startdownload()).
When the start button click i have placed a text view that shows data is dowmload started and when download completed the same text view show download completed .
Download function is placed under a thread.
start_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Status.setText("Download Started");
Thread t = new Thread(){
public void run() {
startdownload();
runOnUiThread(new Runnable() {
public void run() {
Status.setText("Download Completed");
}
});
}};
t.start();
}
});
Also i have a stop button to stop downloading data,which stop the thread and shows download stopped using the same text view as above mentioned.the stop button code is as below
stop_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
onStop();
Status.setText("Download Stopped");
}
public void onStop() {
super.onStop();
isRunning = false;
}
The problem is that when i click start button the text view shows download started but when clicked stop button before completely dowloading the data it shows download stopped
in the text view first and after some time it shows download completed.....
Please any one verify that is there any problem with my thread implementation procedure...
I think thats why it shows download completed even when i stoped the thread using stop button....Please help me......
I think you can update UI from thread so please try to use the handler.
Thank you.
Do you actually stop thread? Or it continues to run after you press stop button?
You can use flag isStopped and in thread:
if (!isStopped) {
runOnUiThread(new Runnable() {
public void run() {
Status.setText("Download Completed");
}
});
}
and set isStopped to true in stop_button.
If onStop() is the Activity.onStop() callback method, then you should not call it. It has nothing to do with your downloading thread, and anyway it's just a system callback that is called by system. Actually, stopping a thread by yourself is not recommended, the Thread.stop() method is deprecated, as you may know. It's easy to "stop" a thread that is performing some operations in a loop: you just drop the flag controlling the loop, result is that the thread keeps on running, but it's doing nothing. Your application architecture doesn't let you stop your thread, cause you're just running a task. Post your downloading code and it will be more clear what you're doing and what you're trying to achieve.