Android – Comment passer des données à Runnable dans runOnUiThread?

J'ai besoin de mettre à jour une interface utilisateur et la faire dans le thread UI en utilisant runOnUiThread
Maintenant, les données pour l'interface utilisateur proviennent de l'autre Thread, représenté par les data ici.

Comment puis-je passer les données à Runnable, donc, elles peuvent être utilisées pour mettre à jour l'interface utilisateur? Android ne semble pas permettre l'utilisation directe des données. Existe-t-il une façon élégante de le faire?

  • Écoutez les changements du calendrier Android. (Synchroniser / Supprimer / Insérer etc.)
  • Comment parcourir localhost sur un périphérique Android?
  • Java.lang.NoSuchFieldError: org.apache.http.message.BasicLineFormatter.INSTANCE
  • Android Mediarecorder enregistre la durée de la vidéo différente de la durée attendue
  • Comment faire un android mm clean?
  • IllegalArgumentException: Impossible de trouver la racine de configuration qui contient xxx sur FileProvider.getUriForFile
  •  public void OnNewSensorData(Data data) { runOnUiThread(new Runnable() { public void run() { //use data } }); } 

    Ma solution était de créer private Data sensordata confidentielles private Data sensordata intérieur de l'exécution, et de lui attribuer des données. Cela ne fonctionne que si les Data data sont définitives.

     public void OnNewSensorData(final Data data) { runOnUiThread(new Runnable() { private Data sensordata = data; public void run() { //use sensordata which is equal to data } }); } 

  • Comment puis-je réduire l'espacement des lignes entre le texte dans ma mise en page Android?
  • GCM avec PHP (Google Cloud Messaging)
  • Modification de la couleur d'arrière-plan des éléments ListView sur Android
  • Obtenir un temps réel - Pas le temps de l'appareil programmé dans Android
  • Comment traiter le mode hors ligne de Firebase et les données pousser?
  • Modifier les onglets est lent / retardé - Utilisation de fragments
  • 6 Solutions collect form web for “Android – Comment passer des données à Runnable dans runOnUiThread?”

    Le problème que vous avez trouvé est que

    Classes internes en capture Java ("close over") de la portée lexicale dans laquelle elles sont définies. Mais ils ne capturent que des variables déclarées «finales».

    Si cela est clair comme de la boue, il y a une bonne discussion sur les détails ici: ne peut pas se référer à une variable non finale dans une classe intérieure définie dans une méthode différente

    Mais votre solution semble bien. De plus, à condition que les data soient définitives, vous pouvez simplifier le code à ce sujet:

     public void OnNewSensorData(final Data data) { runOnUiThread(new Runnable() { public void run() { // use data here data.doSomething(); } }); } 

    Si vous souhaitez éviter d'utiliser une variable finale intermédiaire (comme décrit par Dan S), vous pouvez implémenter Runnable avec une méthode supplémentaire pour définir Data:

     public class MyRunnable implements Runnable { private Data data; public void setData(Data _data) { this.data = _data; } public void run() { // do whatever you want with data } } 

    Vous pouvez ensuite appeler la méthode comme ceci:

     public void OnNewSensorData(Data data) { MyRunnable runnable = new MyRunnable(); runnable.setData(data); runOnUiThread(runnable); } 

    Vous pouvez également créer un constructeur MyRunnable dans l'instance Data en tant qu'argument:

     public class MyRunnable implements Runnable { private Data data; public MyRunnable(Data _data) { this.data = _data; } public void run() { ... } } 

    Et ensuite dites runOnUiThread (nouveau MyRunnable (données));

    J'ai eu un problème similaire où je voulais transmettre de l'information dans le fil. Pour le résoudre avec le système Android, je modifie la réponse de corsiKa dans: Runnable with a parameter?

    Vous pouvez déclarer une classe dans la méthode et passer le paramètre comme indiqué ci-dessous:

     void Foo(String str) { class OneShotTask implements Runnable { String str; OneShotTask(String s) { str = s; } public void run() { someFunc(str); } } runOnUiThread(new OneShotTask(str)); } 

    Vous devrez mettre à jour chaque fois que votre programme contient de nouvelles Data qu'il souhaite afficher. Votre deuxième liste de code ici est la manière standard d'y parvenir. Il peut y avoir des prises si vous continuez à mettre à jour les Data dans le fil. Si tel est le cas, envisagez de bloquer le thread jusqu'à ce que l'interface utilisateur finisse la mise à jour ou la copie des données vers un autre objet Data .

    Ce qui se passe en interne, c'est que la JVM copie la référence à l'objet Data pour quand la classe anonyme sera exécutée. Data stockées à l'intérieur peuvent encore être modifiées. Si votre méthode nécessite des modifications supplémentaires dans Data utilisez simplement une autre variable (référence d'objet), par exemple: final Data finalData = data; . Vous pouvez également supprimer la ligne private Data sensordata = data; Et utiliser les données directement dans votre méthode d'exécution.

    Il peut ne pas être élégant, mais c'est la façon dont Java passe les variables d'objet aux classes anonymes. Il existe une nouvelle syntaxe dans Java Language version 7, mais Android est compatible avec Java Language version 5 et 6.

    Voici un cas typique où le rappel de service est appelé pour mettre à jour une chaîne d'état de l'interface utilisateur (TextView textStatus). Le service peut être enfilé.

    L'échantillon combine la vérification si la redirection de fil est nécessaire et la redirection réelle:

      // service callbacks public void service_StatusTextChanged(final String s) { if( isOnUiThread() ) { textStatus.setText(s); } else { runOnUiThread(new Runnable() { @Override public void run() { textStatus.setText(s); } }); } } static public boolean isOnUiThread() { return Thread.currentThread() == Looper.getMainLooper().getThread(); } 

    Voir aussi Comment vérifier si vous exécutez sur UI thread dans Android?

     public static Activity globalContext = null; CommonSetting.globalContext = this;// put this in MainACtivity.onCreate() public void createToastShort(final String message) { runOnUiThread(new Runnable() { public void run() { Toast.makeText(CommonSetting.globalContext, message, Toast.LENGTH_SHORT).show(); } }); } 
    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.