Как мы используем runOnUiThread в Android?
Я новичок в Android, и я пытаюсь использовать UI-поток, поэтому я написал простую тестовую активность. Но я думаю, что я что - то неправильно понял, потому что при нажатии на кнопку-приложение больше не отвечает
public class TestActivity extends Activity {
Button btn;
int i = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
runThread();
}
});
}
private void runThread(){
runOnUiThread (new Thread(new Runnable() {
public void run() {
while(i++ < 1000){
btn.setText("#"+i);
try {
Thread.sleep(300);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}));
}
}
9 ответов:
просто оберните его как функцию, а затем вызовите эту функцию из фонового потока.
public void debugMsg(String msg) { final String str = msg; runOnUiThread(new Runnable() { @Override public void run() { mInfo.setText(str); } }); }
у вас есть это задом наперед. Ваш щелчок кнопки приводит к вызову
runOnUiThread()
, но это не нужно, так как обработчик щелчка уже запущен в потоке пользовательского интерфейса. Тогда ваш код вrunOnUiThread()
запускает новый фоновый поток, где вы пытаетесь выполнить операции пользовательского интерфейса, которые затем терпят неудачу.вместо этого просто запустите фоновый поток непосредственно из обработчика щелчка. Затем оберните вызовы в
btn.setText()
внутри вызоваrunOnUiThread()
.
есть несколько методов, использующих runOnUiThread (), позволяет увидеть все
Это мой основной поток (UI поток) называется AndroidBasicThreadActivity и я хочу обновить его из рабочего потока различными способами -
public class AndroidBasicThreadActivity extends AppCompatActivity { public static TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_android_basic_thread); textView = (TextView) findViewById(R.id.textview); MyAndroidThread myTask = new MyAndroidThread(AndroidBasicThreadActivity.this); Thread t1 = new Thread(myTask, "Bajrang"); t1.start(); } }
1.) Передавая экземпляр Activity в качестве аргумента в рабочем потоке
class MyAndroidThread implements Runnable { Activity activity; public MyAndroidThread(Activity activity) { this.activity = activity; } @Override public void run() { //perform heavy task here and finally update the UI with result this way - activity.runOnUiThread(new Runnable() { @Override public void run() { AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread."); } }); } }
2.) С помощью метода представления post (Runnable runnable) в worker нить
class MyAndroidThread implements Runnable { Activity activity; public MyAndroidThread(Activity activity) { this.activity = activity; } @Override public void run() { //perform heavy task here and finally update the UI with result this way - AndroidBasicThreadActivity.textView.post(new Runnable() { @Override public void run() { AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread."); } }); } }
3.) С помощью класса обработчика из android.пакет ОС Если у нас нет контекста (this/ getApplicationContext()) или экземпляра Activity (AndroidBasicThreadActivity.это), то мы должны использовать класс обработчика, как показано ниже -
class MyAndroidThread implements Runnable { Activity activity; public MyAndroidThread(Activity activity) { this.activity = activity; } @Override public void run() { //perform heavy task here and finally update the UI with result this way - new Handler(Looper.getMainLooper()).post(new Runnable() { public void run() { AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread."); } }); } }
вы можете использовать этот пример :
в следующем примере мы будем использовать это средство для публикации результата из a поиск синонимов, который был обработан фоновым потоком.
для достижения цели во время обратного вызова действия OnCreate мы настроим onClickListener для запуска searchTask в созданном потоке.
когда пользователь нажимает на кнопку поиска, мы создадим запускаемый анонимный класс, который ищет введенное слово ИД р..полей EditText wordEt и начинается поток для выполнения Runnable.
когда поиск завершится, мы создадим экземпляр Runnable SetSynonymResult чтобы опубликовать результат обратно в синониме TextView над потоком пользовательского интерфейса.
этот метод не самый удобный, особенно когда мы не иметь доступ к экземпляру Activity; поэтому в следующих главах мы мы обсудим более простые и чистые методы обновления пользовательского интерфейса с помощью фон вычислительная задача.
public class MainActivity extends AppCompatActivity { class SetSynonymResult implements Runnable { String synonym; SetSynonymResult(String synonym) { this.synonym = synonym; } public void run() { Log.d("AsyncAndroid", String.format("Sending synonym result %s on %d", synonym, Thread.currentThread().getId()) + " !"); TextView tv = (TextView) findViewById(R.id.synonymTv); tv.setText(this.synonym); } } ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button search = (Button) findViewById(R.id.searchBut); final EditText word = (EditText) findViewById(R.id.wordEt); search.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Runnable searchTask = new Runnable() { @Override public void run() { String result = searchSynomim(word.getText().toString()); Log.d("AsyncAndroid", String.format("Searching for synonym for %s on %s", word.getText(), Thread.currentThread().getName())); runOnUiThread(new SetSynonymResult(result)); } }; Thread thread = new Thread(searchTask); thread.start(); } }); } static int i = 0; String searchSynomim(String word) { return ++i % 2 == 0 ? "fake" : "mock"; } }
источник:
вот как я его использую:
runOnUiThread(new Runnable() { @Override public void run() { //Do something on UiThread } });
твой этот:
@UiThread public void logMsg(final String msg) { new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { Log.d("UI thread", "I am the UI thread"); } }); }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gifImageView = (GifImageView) findViewById(R.id.GifImageView); gifImageView.setGifImageResource(R.drawable.success1); new Thread(new Runnable() { @Override public void run() { try { //dummy delay for 2 second Thread.sleep(8000); } catch (InterruptedException e) { e.printStackTrace(); } //update ui on UI thread runOnUiThread(new Runnable() { @Override public void run() { gifImageView.setGifImageResource(R.drawable.success); } }); } }).start(); }