==
проверяет ссылки на объекты, .equals()
проверяет строковые значения.
Иногда кажется, что ==
сравнивает значения, потому что Java делает некоторые закулисные вещи, чтобы убедиться, что одинаковые строки в строке являются одним и тем же объектом.
Для Например:
String fooString1 = new String("foo");
String fooString2 = new String("foo");
// Evaluates to false
fooString1 == fooString2;
// Evaluates to true
fooString1.equals(fooString2);
// Evaluates to true, because Java uses the same object
"bar" == "bar";
Но будьте осторожны с нулями!
==
обрабатывает строки null
в порядке, но вызов .equals()
из пустой строки приведет к исключению:
String nullString1 = null;
String nullString2 = null;
// Evaluates to true
System.out.print(nullString1 == nullString2);
// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));
Итак, если вы знаете, что fooString1
может но не менее очевидно, что он проверяет значение null (из Java 7):
System.out.print(Objects.equals(fooString1, "bar"));
Вы можете сделать это, вызвав метод Activity
runOnUiThread
из вашего потока:
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
}
});
Я сделал этот подход на основе ответа mjaggard:
public static void toastAnywhere(final String text) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
Toast.makeText(SuperApplication.getInstance().getApplicationContext(), text,
Toast.LENGTH_LONG).show();
}
});
}
Хорошо работал для меня.
Это похоже на другие ответы, однако обновленные для новой доступной apis и намного более чистые. Кроме того, не предполагается, что вы находитесь в Контексте активности.
public class MyService extends AnyContextSubclass {
public void postToastMessage(final String message) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getContext(), message, Toast.LENGTH_LONG).show();
}
});
}
}
Один подход, который работает практически из любого места, в том числе из мест, где у вас нет Activity
или View
, заключается в том, чтобы захватить Handler
в основной поток и показать тост:
public void toast(final Context context, final String text) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
Toast.makeText(context, text, Toast.DURATION_LONG).show();
}
});
}
Преимуществом этого подхода является то, что он работает с любыми Context
, включая Service
и Application
.
Мне нравится иметь метод в моей деятельности под названием showToast
, который я могу вызвать из любого места ...
public void showToast(final String toast)
{
runOnUiThread(() -> Toast.makeText(MyActivity.this, toast, Toast.LENGTH_SHORT).show());
}
Затем я чаще всего вызываю его из MyActivity
на любой поток, например это ...
showToast(getString(R.string.MyMessage));
Я столкнулся с той же проблемой:
E/AndroidRuntime: FATAL EXCEPTION: Thread-4
Process: com.example.languoguang.welcomeapp, PID: 4724
java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare()
at android.widget.Toast$TN.<init>(Toast.java:393)
at android.widget.Toast.<init>(Toast.java:117)
at android.widget.Toast.makeText(Toast.java:280)
at android.widget.Toast.makeText(Toast.java:270)
at com.example.languoguang.welcomeapp.MainActivity$1.run(MainActivity.java:51)
at java.lang.Thread.run(Thread.java:764)
I/Process: Sending signal. PID: 4724 SIG: 9
Application terminated.
Before: onCreate function
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show();
}
});
thread.start();
После: onCreate function
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show();
}
});
сработало.
Вы можете использовать Looper
для отправки сообщения Toast
. Пройдите эту ссылку для получения более подробной информации.
public void showToastInThread(final Context context,final String str){
Looper.prepare();
MessageQueue queue = Looper.myQueue();
queue.addIdleHandler(new IdleHandler() {
int mReqCount = 0;
@Override
public boolean queueIdle() {
if (++mReqCount == 2) {
Looper.myLooper().quit();
return false;
} else
return true;
}
});
Toast.makeText(context, str,Toast.LENGTH_LONG).show();
Looper.loop();
}
, и он вызывается в вашем потоке. Контекст может быть Activity.getContext()
получить из Activity
, который вы должны показать тост.
Как этот или этот , с Runnable
, который показывает Toast
. А именно,
Activity activity = // reference to an Activity
// or
View view = // reference to a View
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
showToast(activity);
}
});
// or
view.post(new Runnable() {
@Override
public void run() {
showToast(view.getContext());
}
});
private void showToast(Context ctx) {
Toast.makeText(ctx, "Hi!", Toast.LENGTH_SHORT).show();
}
Activity
, вместо этого вы можете использовать простой вспомогательный класс, см. здесь: stackoverflow.com/a/18280318/1891118 – Oleksii K. 28 August 2013 в 10:27MyActivity.this.runOnUiThread()
отлично работает с внутреннимThread
/AsyncTask
. – Anthony Atkinson 30 April 2014 в 18:39