Как мы используем 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()
, но это не требуется, так как обработчик click уже запущен в потоке пользовательского интерфейса. Тогда ваш код в runOnUiThread()
запускает новый фоновый поток, где вы пытаетесь выполнить операции пользовательского интерфейса, которые затем терпят неудачу.
вместо этого просто запустите фоновый поток непосредственно из обработчика кликов. Затем оберните вызовы btn.setText()
внутри вызова runOnUiThread()
.
существует несколько методов, использующих runOnUiThread (), позволяет увидеть все
Это мой основной поток (UI thread) называется 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.) С помощью класса Handler из 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.");
}
});
}
}
вы можете использовать этот пример :
в следующем примере мы собираемся использовать это средство для публикации результата из поиск синонимов, обработанный фоновым потоком.
для достижения цели во время обратного вызова активности OnCreate мы настроим onClickListener для запуска searchTask в созданном потоке.
когда пользователь нажимает на кнопку поиска, мы создадим Runnable anonymous класс, который ищет введенное слово ИД р..полей EditText wordEt и начинается поток для выполнения Runnable.
по завершении поиска мы создадим экземпляр Runnable SetSynonymResult чтобы опубликовать результат обратно в текстовом представлении синонима над потоком пользовательского интерфейса.
этот метод не самый удобный, особенно когда мы не иметь доступ к экземпляру 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();
}