Не уверен, что понимаю, как это сделать. У меня есть мой существующий public void run (). Я пробовал поместить туда этот код. Я знаю, что это неправильно, потому что это не сработало, но я действительно застрял.
SwimBikeRun
14
"Активность" передается не-пользовательскому потоку в его конструкторе? Как правильно получить объект действия, который вы используете, из отдельного потока?
snapfractalpop
Установите на Threadссылку объекта к Activityв Activity«с onResume. Отозвать его в Activity«с onPause. Делайте то и другое под synchronizedзамком, который соблюдают Activityи Threadуважают.
JohnnyLambada
5
иногда нет доступа к Activityэкземпляру, вместо этого вы можете использовать простой вспомогательный класс, см. здесь: stackoverflow.com/a/18280318/1891118
Алексей К.
5
Я обычно обнаружил, что MyActivity.this.runOnUiThread()это прекрасно работает внутри внутреннего Thread/ AsyncTask.
Энтони Аткинсон
62
Мне нравится иметь в моей деятельности метод, showToastкоторый я могу вызывать откуда угодно ...
@YoushaAleayoub В предоставленных вами ссылках много дискуссий и предположений. Например, RomainGuy утверждает, что в вашем доказательстве нет утечки памяти. 4. Некоторые ссылки относятся к раннему периоду Android в 2009 году. Также люди говорят в других ссылках, что вы можете использовать оба контекста. Деятельность и применение. Может быть, у вас есть более современные доказательства, основанные на доказательствах? У вас есть ссылка на 1?
OneWorld,
28
Это похоже на другие ответы, но обновлено для новых доступных API и намного чище. Кроме того, не предполагается, что вы находитесь в контексте деятельности.
Когда контекст, который у вас есть, не является деятельностью, это идеальный ответ. Большое спасибо!
francas
17
Один из подходов, который работает практически из любого места, в том числе из мест, где у вас нет Activityили View, - это захватить Handlerосновной поток и показать тост:
Как то или это , с тем, Runnableчто показывает Toast. А именно,
Activity activity =// reference to an Activity// orView view =// reference to a View
activity.runOnUiThread(newRunnable(){@Overridepublicvoid run(){
showToast(activity);}});// or
view.post(newRunnable(){@Overridepublicvoid run(){
showToast(view.getContext());}});privatevoid showToast(Context ctx){Toast.makeText(ctx,"Hi!",Toast.LENGTH_SHORT).show();}
Иногда вам нужно отправить сообщение из другого Threadпотока пользовательского интерфейса. Этот тип сценария возникает, когда вы не можете выполнять операции сети / ввода-вывода в потоке пользовательского интерфейса.
Пример ниже обрабатывает этот сценарий.
У вас есть поток пользовательского интерфейса
Вы должны начать операцию ввода-вывода, и, следовательно, вы не можете работать Runnableв потоке пользовательского интерфейса. Так что опубликуйте свой Runnableобработчик наHandlerThread
Получите результат Runnableи отправьте его обратно в поток пользовательского интерфейса и покажите Toastсообщение.
Создайте обработчик с помощью Looper из HandlerThread:requestHandler
Создайте обработчик с помощью Looper из основного потока: responseHandlerи переопределите handleMessageметод
postRunnableзадача поrequestHandler
Внутри Runnableзадача, вызов sendMessageнаresponseHandler
Это sendMessageрезультат вызова handleMessagein responseHandler.
Получить атрибуты из Messageи обработать, обновить UI
Образец кода:
/* Handler thread */HandlerThread handlerThread =newHandlerThread("HandlerThread");
handlerThread.start();Handler requestHandler =newHandler(handlerThread.getLooper());finalHandler responseHandler =newHandler(Looper.getMainLooper()){@Overridepublicvoid handleMessage(Message msg){//txtView.setText((String) msg.obj);Toast.makeText(MainActivity.this,"Runnable on HandlerThread is completed and got result:"+(String)msg.obj,Toast.LENGTH_LONG).show();}};for(int i=0; i<5; i++){Runnable myRunnable =newRunnable(){@Overridepublicvoid run(){try{/* Add your business logic here and construct the
Messgae which should be handled in UI thread. For
example sake, just sending a simple Text here*/String text =""+(++rId);Message msg =newMessage();
msg.obj = text.toString();
responseHandler.sendMessage(msg);System.out.println(text.toString());}catch(Exception err){
err.printStackTrace();}}};
requestHandler.post(myRunnable);}
E/AndroidRuntime: FATAL EXCEPTION:Thread-4Process: 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.
Ответы:
Вы можете сделать это путем вызова
Activity
«SrunOnUiThread
метод из вашего потока:источник
Thread
ссылку объекта кActivity
вActivity
«сonResume
. Отозвать его вActivity
«сonPause
. Делайте то и другое подsynchronized
замком, который соблюдаютActivity
иThread
уважают.Activity
экземпляру, вместо этого вы можете использовать простой вспомогательный класс, см. здесь: stackoverflow.com/a/18280318/1891118MyActivity.this.runOnUiThread()
это прекрасно работает внутри внутреннегоThread
/AsyncTask
.Мне нравится иметь в моей деятельности метод,
showToast
который я могу вызывать откуда угодно ...Затем я чаще всего вызываю его изнутри
MyActivity
в любом потоке, подобном этому ...источник
Это похоже на другие ответы, но обновлено для новых доступных API и намного чище. Кроме того, не предполагается, что вы находитесь в контексте деятельности.
источник
Один из подходов, который работает практически из любого места, в том числе из мест, где у вас нет
Activity
илиView
, - это захватитьHandler
основной поток и показать тост:Преимущество такого подхода в том, что он работает с любыми
Context
, в том числеService
иApplication
.источник
Как то или это , с тем,
Runnable
что показываетToast
. А именно,источник
Иногда вам нужно отправить сообщение из другого
Thread
потока пользовательского интерфейса. Этот тип сценария возникает, когда вы не можете выполнять операции сети / ввода-вывода в потоке пользовательского интерфейса.Пример ниже обрабатывает этот сценарий.
Runnable
в потоке пользовательского интерфейса. Так что опубликуйте свойRunnable
обработчик наHandlerThread
Runnable
и отправьте его обратно в поток пользовательского интерфейса и покажитеToast
сообщение.Решение:
HandlerThread
:requestHandler
responseHandler
и переопределитеhandleMessage
методpost
Runnable
задача поrequestHandler
Runnable
задача, вызовsendMessage
наresponseHandler
sendMessage
результат вызоваhandleMessage
inresponseHandler
.Message
и обработать, обновить UIОбразец кода:
Полезные статьи:
обработчики потоков-и-почему-вам-следует-использовать-их-в-ваших-андроид-приложениях
андроид-обработчик-обработчик-обработчик-поток-я
источник
handler.sendMessage();
post()
Метод вызоваhandler.post();
runOnUiThread()
view.post()
источник
Вы можете использовать
Looper
для отправкиToast
сообщения. Для получения более подробной информации перейдите по этой ссылке .и это называется в вашей ветке. Контекст может быть
Activity.getContext()
получен из-заActivity
того, что вы должны показать тост.источник
Я сделал этот подход на основе ответа mjaggard:
Хорошо сработало для меня.
источник
Я столкнулся с той же проблемой :
Раньше: функция onCreate
После: функция onCreate
это сработало.
источник