问题
Hi I want to make Toast
available to me no-matter-what and available from any thread whenever I like within my application. So to do this I extended the Activity
class:
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Toast;
public class MyActivity extends Activity{
private Handler mHandler;
@Override
public void onCreate(Bundle savedInstanceState) {
mHandler = new Handler();
super.onCreate(savedInstanceState);
}
private class ToastRunnable implements Runnable {
String mText;
public ToastRunnable(String text) {
mText = text;
}
public void run(){
Toast.makeText(getApplicationContext(), mText, Toast.LENGTH_SHORT).show();
}
}
public void doToast(String msg) {
mHandler.post(new ToastRunnable(msg));
}
}
so that all Activity
classes in my app are now simply
public class AppMain extends MyActivity {
//blah
}
what I expected to be able to do (in a worker thread) was this:
try{
MyActivity me = (MyActivity) Looper.getMainLooper().getThread();
me.doToast("Hello World");
}
catch (Exception ex){
Log.e("oh dear", ex.getMessage());
}
and so long as the Activity
was a "MyActivity
" it should work - but the problem is ---> the Looper.getMainLooper().getThread();
isn't returning the MyActivity
to me and it's making me cry - what am I doing wrong?
: EDIT :
some background to explain "why" I am stuck with this type of implmentation.
I need to be able to confirm to the user that a "HTTP POST" event has been a success. Now. If the User clicks "OK" on the UI Form it MAY or MAY NOT have internet at that time.. If it has Internet - all well and good - it posts the form via HTTP POST all well and good.. but if there is NO Internet most (99.999% of Android apps lame /pathetic / mewling at this, and basically offer the user no plan "b" assuming that at all times the internet is there - when it is NOT)
My App will not "go lame (as I call it)" - it does have a plan "b" instead it "Queues" the post event and retries every x minutes.. now this is a silent thread in the background.. I have plenty of user interaction all over the app I don't know where the user will "be" but eventually when the HTTP POST that queue/retries/queue/retries returns "! Success! " I want to Toast
that as a message to the user (EG: "your form was sent")
回答1:
What's wrong with runOnUiThread
?
http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello, world!", Toast.LENGTH_SHORT).show();
}
});
回答2:
use below code. create activity object which contains your activity instance..
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity.getApplicationContext(),"Toast text",Toast.LENGTH_SHORT).show();
}
);
回答3:
This will allow you to display the message without needing to rely on the context to launch the toast, only to reference when displaying the message itself.
runOnUiThread was not working from an OpenGL View thread and this was the solution. Hope it helps.
private Handler handler = new Handler();
handler.post(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello, world!", Toast.LENGTH_SHORT).show();
}
});
回答4:
You can't just cast the result of getThread()
to an instance of your MyActivity
base class. getThread()
returns a Thread
which has nothing to do with Activity
.
There's no great -- read: clean -- way of doing what you want to do. At some point, your "worker thread" abstraction will have to have a reference to something that can create a Toast
for you. Saving off some static variable containing a reference to your Activity
subclass simply to be able to shortcut Toast
creation is a recipe for memory leaks and pain.
回答5:
Why don't you send an intent that is captured by a BroadCastReceiver, then the broadcast receiver can create a notification in the notification tray. It's not a toast, but its a way to inform the user that his post has been successful.
回答6:
if you have the context with you, you can call the ui thread like this from non activity class.
((Activity)context).runOnUiThread(new Runnable() {
public void run() {
// things need to work on ui thread
}
});
回答7:
If it's within your own activity, why can't you just call doToast()
?
来源:https://stackoverflow.com/questions/13746940/android-calling-ui-thread-from-worker-thread