At the beginning, I would like to apologize for my bad English.
There is my problem:
Below timer is showing message at every 3 second , but when i getting out from the program (using back button) the message still pop out.
public Runnable mUpdateTimeTask = new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
Thread.sleep(3000);}
catch (Exception e) {
// TODO: handle exception
}
mHandler.post(new Runnable(){
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Testing 3 Seconds", Toast.LENGTH_LONG).show();
}
});
}
}
};
i already use mHandler.removeCallbacks(mUpdateTimeTask); still can't stop it.
Thanks in advance.
The call has been made from a runnable thread class, which is still active when Back button is pressed. It will pop messages until the application destroys.
Instead, use this:
handler.removeCallbacksAndMessages(null);
In the docs for removeCallbacksAndMessages it says. here is the link:
developer website documentation link
"Remove any pending posts of callbacks and sent messages whose obj is token. If token is null, all callbacks and messages will be removed."
I recently had the same problem and after searching a lot, I found the solution here.
handler.removeCallbacksAndMessages(null);
would only stop pending messages (Runnables). It won't work for the currently running runnable. You will have to write your own class to stop the currently running runnable.
Related
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.
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.
I've to develop a widget (AppWidget) that contains a button.
When the button is pressed an http request is done and, if the request is successful, the widget notify the fact through a Toast.
Since the http request can lock the UI, I run it in a thread.
All it's working fine (I can see "All right" in my logat), except for the Toast notification.
What am I doing wrong?
In the AppWidgetProvider subclass:
#Override
public void onReceive(Context c, Intent intent){
super.onReceive(c, intent);
if(intent.getAction().equals(CLICK_ACTION)){
performRequest(c);
}
}
(I think onUpdate method is not necessary for the question)
private void performRequest(final Context c){
new Thread(new Runnable(){
public void run() {
try {
if(Http.get(URL).contains(SUCCESS)){
Toast.makeText(c, "All right", Toast.LENGTH_SHORT).show();
Log.i("Widget","All right");
}
} catch (Exception e) {
e.printStackTrace();
}}}).start();
}
I think that the problem is the Context argument of performRequest, but if I remove the final keyword, I have errors.
Thanks in advice.
[EDIT]
I "solved" the problem in this way:
-I declare Toast t as a global variable;
-Inside the onReceive method I initialize it with Toast.makeText(Context,String,int)
-When I need to show it, I simply call t.show()
I hope that there are better solutions.
Since the http request can lock the UI, I run it in a thread. All it's working fine (I can view "All right" in my logat), except for the Toast notification. What am I doing wrong?
The problem is you cannot alter the UI from another Thread. You must pass this message back to the main Thread in order to display your Toast.
How can I do it?
There are a lot of different ways to do this, try saving the Context in onReceive() as a field variable:
Context context;
#Override
public void onReceive(Context c, Intent intent){
super.onReceive(c, intent);
context = c;
...
Next create a simple method in your Activity:
public void httpGetSucceeded() {
Toast.makeText(context, "All right", Toast.LENGTH_SHORT).show();
Log.i("Widget","All right");
}
Now call this inside your Runnable:
try {
if(Http.get(URL).contains(SUCCESS)){
httpGetSucceeded();
}
} //etc
Better yet, why don't you have a handler that dispatches a message after the thread completes its task. When you receive that message in your broadcast receiver just consume the message and display the toast by using the post runnable method from the Handler object.
Because the handler will belong to your broadcast receiver, you should be running on the UI thread when you call the post for the runnable.
Ref
http://developer.android.com/reference/android/os/Handler.html
http://developer.android.com/reference/android/os/Handler.html#post(java.lang.Runnable)
Easiest way is to call
activity.runOnUiThread(new Runnable() {
public void run() {
// launch toast here
}
});
Or, given a specific widget:
view.post(new Runnable() {
public void run() {
// launch toast here
}
});
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.
Note : I know there are many questions related to this, but still I am not convince, so asking.
I am getting cant create handler inside thread that has not called looper.prepare when I try to show the dialog.
Here is my code...
//this method is called from a different method based on some condition which is inturn called on click a button
private void download() {
thread = new Thread() {
public void run() {
/**** Downloads each tour's Tour.plist file ****/
try {
// do many heavy operations here, like download,
//calling web webvice and starting another activity
This comes at the end
Intent toAudio = new Intent(TourDescription.this,Audio.class);
startActivity(toAudio);
} catch (Exception e) {
}
}
};
thread.start();
}
Now before this actity gets called I am trying to show a dialog. I am trying to place that just before calling Intent.
Can any body please tell me how to do this, as I am not understanding how to solve this
you cannot show a dialog from a child thread.
A dialog can only be showed from within the UI thread/main Thread.
try this from inside the child thread
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO show dialog....
}
});