web-dev-qa-db-fra.com

Comment utilisons-nous runOnUiThread sous Android?

Je suis nouveau sur Android et j'essaie d'utiliser UI-Thread. J'ai donc écrit une activité de test simple. Mais je pense avoir mal compris quelque chose, car en cliquant sur le bouton, l'application ne répond plus

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();
                    }
                }
             }
        }));
    }
}
131
user1049280

Ci-dessous est l'extrait corrigé de la fonction 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();
}
184
Vipul Shah

Enveloppez-la simplement en tant que fonction, puis appelez cette fonction à partir de votre fil d’arrière-plan.

public void debugMsg(String msg) {
    final String str = msg;
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mInfo.setText(str);
        }
    });
}
74
user4284784

Vous l'avez à l'envers. Votre clic sur le bouton entraîne l'appel de runOnUiThread(), mais cela n'est pas nécessaire, car le gestionnaire de clics est déjà en cours d'exécution sur le thread d'interface utilisateur. Ensuite, votre code dans runOnUiThread() lance un nouveau thread en arrière-plan, dans lequel vous essayez d'effectuer des opérations d'interface utilisateur, qui échouent ensuite.

Au lieu de cela, lancez le fil d’arrière-plan directement à partir de votre gestionnaire de clics. Ensuite, encapsulez les appels à btn.setText() dans un appel à runOnUiThread().

25
Graham Borland
runOnUiThread(new Runnable() {
                public void run() {
                //Do something on UiThread
            }
        });
10
Terranology

Il existe plusieurs techniques utilisant runOnUiThread (), permet de voir toutes les 

Ceci est mon fil principal (fil de l'interface utilisateur) appelé AndroidBasicThreadActivity et je vais le mettre à jour à partir d'un fil de travail de différentes manières -

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.) En passant l'instance d'Activity comme argument sur le thread de travail

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.) En utilisant la méthode post de View (Runnable runnable) dans le thread de travail

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.) En utilisant la classe Handler du package Android.os Si nous n'avons pas le contexte (this/getApplicationContext ()) ou l'instance d'Activity (AndroidBasicThreadActivity.this), nous devons utiliser la classe Handler en tant que au dessous de -

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.");
        }
    });
  }
}
6
Bajrang Hudda

Si vous utilisez fragment, écrivez simplement

getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
            //Do something on UiThread
        }
    });
2
Shivam Yadav
  @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();

    }
0
Keshav Gera

Voici comment je l'utilise:

runOnUiThread(new Runnable() {
                @Override
                public void run() {
                //Do something on UiThread
            }
        });
0
Josh Aquino

Vous pouvez utiliser à partir de cet exemple:

Dans l'exemple suivant, nous allons utiliser cette fonction pour publier le résultat d'une recherche Synonym traitée par un fil d'arrière-plan.

Pour atteindre l'objectif lors du rappel d'activité OnCreate, nous allons configurer OnClickListener pour exécuter searchTask sur un thread créé.

Lorsque l'utilisateur clique sur le bouton Rechercher, nous allons créer une classe anonyme Runnable anonyme qui recherche le mot saisi dans R.id.wordEt EditText et démarre le thread Pour exécuter Runnable.

Une fois la recherche terminée, nous allons créer une instance de Runnable SetSynonymResultpour publier le résultat sur le synonyme TextView via le fil de l'interface utilisateur.

Cette technique n’est parfois pas la plus pratique, surtout lorsque nous n’avons pas accès à une instance Activity; Par conséquent, dans les chapitres suivants, nous allons discuter des techniques plus simples et plus propres pour mettre à jour l'interface utilisateur à partir d'une tâche informatique en arrière-plan.

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";
    }
}

La source :

Programmation Android asynchrone Helder Vasconcelos

0
user4813855

ton ceci:

@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");


            }
        });
    }
0
MrG