not - ¿Cómo utilizamos runOnUiThread en Android?
runonuithread(() (9)
A continuación se muestra el runThread
corregido de la función runThread
.
private void runThread() {
new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
btn.setText("#" + i);
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
Soy nuevo en Android y estoy tratando de usar el UI-Thread, así que escribí una actividad de prueba simple. Pero creo que he entendido mal algo, porque al hacer clic en el botón, la aplicación ya no responde
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();
}
}
}
}));
}
}
Así es como lo uso:
runOnUiThread(new Runnable() {
@Override
public void run() {
//Do something on UiThread
}
});
Hay varias técnicas que usan runOnUiThread (), permite ver todo
Este es mi hilo principal (hilo de interfaz de usuario) llamado AndroidBasicThreadActivity y voy a actualizarlo desde un hilo de trabajo de varias maneras:
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.) Pasando la instancia de Activity como argumento en el hilo de trabajo
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.) Mediante el uso del método de publicación de View (Runnable Runnable) en el hilo de trabajo
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.) Usando la clase Handler del paquete android.os Si no tenemos el contexto (this / getApplicationContext ()) o la instancia de Activity (AndroidBasicThreadActivity.this) entonces tenemos que usar la clase Handler como se muestra a continuación -
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.");
}
});
}
}
Lo tienes de frente a frente. Su clic de botón da como resultado una llamada a runOnUiThread()
, pero esto no es necesario, ya que el manejador de clics ya se está ejecutando en el subproceso de la interfaz de usuario. Entonces, su código en runOnUiThread()
está iniciando un nuevo hilo de fondo, donde intenta hacer operaciones de UI, que luego fallan.
En su lugar, simplemente inicie el hilo de fondo directamente desde su manejador de clics. A continuación, btn.setText()
las llamadas a btn.setText()
dentro de una llamada a runOnUiThread()
.
Puede usar de esta muestra:
En el siguiente ejemplo, vamos a utilizar esta función para publicar el resultado de una búsqueda de sinónimos procesada por una cadena de fondo.
Para lograr el objetivo durante la devolución de llamada de la actividad OnCreate, configuraremos onClickListener para ejecutar searchTask en un hilo creado.
Cuando el usuario hace clic en el botón Buscar, crearemos una clase anónima ejecutable que busca la palabra escrita en R.id.wordEt EditText y comienza el hilo para ejecutar Runnable.
Cuando finalice la búsqueda, crearemos una instancia de Runnable SetSynonymResult para publicar el resultado en el sinónimo TextView sobre el hilo de la interfaz de usuario.
Esta técnica a veces no es la más conveniente, especialmente cuando no tenemos acceso a una instancia de la Actividad; por lo tanto, en los siguientes capítulos, vamos a discutir técnicas más simples y más claras para actualizar la interfaz de usuario de una tarea de computación en segundo plano.
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";
}
}
Fuente :
Simplemente envuélvalo como una función, luego llame a esta función desde su hilo de fondo.
public void debugMsg(String msg) {
final String str = msg;
runOnUiThread(new Runnable() {
@Override
public void run() {
mInfo.setText(str);
}
});
}
tu esto:
@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();
}
runOnUiThread(new Runnable() {
public void run() {
//Do something on UiThread
}
});