Обновите интерфейс вне основного потока
Я полностью новичок в Android и просто хочу знать, если это какой-либо рабочий и возможный способ обновления пользовательского интерфейса за пределами основного потока. Просто из моего кода, который я перечислил ниже, я знаю, что из этого кода; Это невозможно вообще. Но дело в том, что я просто хочу обновить пользовательский интерфейс, используя другой поток. Пожалуйста, помогите мне спасибо заранее!
package com.example.app;
import java.util.Random;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button b;
public ImageView I1;
public ImageView I2;
public ImageView I3;
public ImageView I4;
public TextView T;
public TextView s;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
I1=new ImageView(this);
I1=(ImageView) findViewById(R.id.imag1);
I1.setVisibility(View.INVISIBLE);
I2=new ImageView(this);
I2=(ImageView) findViewById(R.id.imag2);
I2.setVisibility(View.INVISIBLE);
I3=new ImageView(this);
I3=(ImageView) findViewById(R.id.imag3);
I3.setVisibility(View.INVISIBLE);
I4=new ImageView(this);
I4=(ImageView) findViewById(R.id.imag4);
I4.setVisibility(View.INVISIBLE);
T=(TextView)findViewById(R.id.time);
s=(TextView)findViewById(R.id.score);
Thread t=new Thread(new MyThread());
t.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private class MyThread implements Runnable{
Random randomGenerator = new Random();
int n;
public void run(){
while(true){
n=randomGenerator.nextInt(8);
if(n==1){
I1.setVisibility(View.VISIBLE);
}
if(n==2){
I2.setVisibility(View.VISIBLE);
}
if(n==3){
I3.setVisibility(View.VISIBLE);
}
if(n==4){
I4.setVisibility(View.VISIBLE);
}
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.getStackTrace();
}
}
}
}
}
5 ответов
Использовать Activity.runOnUiThread
Acivity.runOnUiThread(new Runnable() {
public void run() {
//something here
}
});
Вы не можете обновлять пользовательский интерфейс напрямую из потока, не являющегося пользовательским интерфейсом, но вы можете взаимодействовать с потоком пользовательского интерфейса, используя объект Handler или объект AsyncTask. Наиболее удобный способ использования AsyncTask:
- .doInBackground() метод AsyncTask запускается в потоке не-пользовательского интерфейса
- .onProgressUpdate() запускается в потоке пользовательского интерфейса, поэтому может изменять представления
- Вы можете использовать метод publishProgress() внутри doInBackground() для передачи данных в.onProgressUpdate.
Извините, если есть ошибки в именах методов. Прочитайте http://developer.android.com/guide/components/processes-and-threads.html для получения подробной информации.
Рабочий поток никогда не может обновить основной поток, потому что только основной поток может отображать элементы пользовательского интерфейса (TextView, EditText и т. Д.), И если мы пытаемся обновить наверняка, мы собираемся сделать исключение.
myAcitity.runOnUiThread(new Runnable() {
public void run() {
//here you can update your UI elements because this code is going to executed by main thread
}
});
В противном случае вы можете использовать метод post класса View.
myView.post(new Runnable() {
public void run() {
//here you can update your UI elements because this code is going to executed by main thread
}
});
Вы должны использовать экземпляр Handler и использовать метод post, добавив Runnable в очередь потока пользовательского интерфейса. Если вы находитесь внутри Activity, вы можете использовать runOnUiThread, который является "ярлыком", чтобы сделать то же самое.
Только основной поток может обновлять пользовательский интерфейс. Если ваш поток хочет обновить пользовательский интерфейс, используйте activity.runOnUiThread()
Однако ваше действие просто ставится в очередь для запуска в потоке пользовательского интерфейса (если вы запускаете его не из потока пользовательского интерфейса), что означает, что он может обновить пользовательский интерфейс немного позже.
http://developer.android.com/reference/android/app/Activity.html