0

Je faisais face à un problème dans l'utilisation de thread dans l'application android.Comment mettre à jour l'interface utilisateur à partir du thread?

J'ai Activity1.java qui ont une certaine fonction qui obtiennent des données de la base de données sql lite et l'affichent sur l'activité. J'ai une méthode Load() qui remplit un spinner statique et d'autres de la base de données. Les valeurs du second spinner dépendent de la première liste déroulante, etc. Il a également visible/invisible certains contrôles interface utilisateur

Scénario 1: -

Si l'on appelle la fonction Load() sur oncreate() Méthode, puis l'activité va ralentir.

Scénario 2: - (Discussion)

Si nous appelons Load() fonction à l'intérieur fil de la méthode OnCreate() et i utiliser runOnUiThread ou Handler.post pour mettre à jour les commandes ui, il sautera ce code, aller plus loin dans le code et mes autres valeurs sont erronées ou ne viennent pas correctement.

Scénario 3: - (Async)

Si l'on appelle la fonction Load() à l'intérieur Aysnc sur oncreate() Méthode, alors je dois mettre à jour en continu de ui tâche async. La mise à jour dans l'interface utilisateur n'est autorisée que sur onPostExecute (Result) et onProgressUpdate (Progress ...), mais comment mettre à jour ui en continu depuis async.

@Override 
protected void onCreate(Bundle savedInstanceState) { 
      BindStaticValues(); 
    GetCalculationOptions(); 
} 
public void BindStaticValues() 
{ 

    //standard 
    BindStandard(); //static spinner (not db)   

    //Spinner 1 
    array1 = new ArrayList<ObjectMaterial>(); 
    Adapter1 = new DescriptionAdapter(this, 
      android.R.layout.simple_spinner_item, 
      array1); 
    Adapter1 
    .setDropDownViewResource(android.R.layout.simple_spinner_item); 
    sp1.setAdapter(Adapter1); 

    //Spinner 2 
    array2 = new ArrayList<ObjectMaterial>(); 
    Adapter2 = new DescriptionAdapter(this, 
      android.R.layout.simple_spinner_item, 
      array2); 
    Adapter2 
    .setDropDownViewResource(android.R.layout.simple_spinner_item); 
    sp2.setAdapter(Adapter2); 

} 


public void GetCalculationOptions() 
{ 

    progressCalcualtionOptions = ProgressDialog.show(context, getString(R.string.progressCalcualtionOptionsTitle), 
      getString(R.string.progressCalcualtionOptionsMessage), true); 

    new Thread(new Runnable() { 
     public void run() { 
      try 
      { 
       LoadValuesforFirstTime(false, false, false); //main load method (Need Updating UI) 
       isFirstOpen=false; 
      } 
      catch (Exception e) { 
       //Log.d(Constants.TAG, e.getMessage()); 
       e.printStackTrace(); 
      } 

      if (progressCalcualtionOptions != null) 
      { 
       progressCalcualtionOptions.dismiss(); 
       progressCalcualtionOptions=null; 
      }  


     } 
    }).start(); 

} 


private void LoadValuesforFirstTime(Boolean FromMaterial, 
     Boolean FromLangugae, Boolean FromCountry) { 


    ChangeVisibility(); // it will change visibility of some controls 

    FillSpinner1(TypeofMaterial); //fill first spinner 1 

    FillSpinner2(ObjectMaterial); //fill first spinner 2 (take values from spinner 1 or manipulate values in spinner 1) 

} 

private void ChangeVisibility() { 

// it will change visibility of some controls 

    runOnUiThread(new Runnable() { 

     public void run() { 


      relat_heightPipe.setVisibility(View.GONE); 
      relat_PipeDiameter.setVisibility(View.GONE); 
      relat_WidthPipe.setVisibility(View.GONE); 
      relat_length.setVisibility(View.GONE); 

      relat_lblMediumHeatCapacity.setVisibility(View.GONE); 
      relat_lblMediumDensity.setVisibility(View.GONE); 

     } 
    }); 
} 

private void FillSpinner1(String TypeofMaterial) { 

      array1 = DB_Manager.All(); //get from db 

    h.post(new Runnable() { 

      public void run() { 
       Adapter1.clear(); 
       for (ObjectMaterial object : array1) 
        Adapter1.add(object); 

       Adapter1.notifyDataSetChanged(); 
      } 
     }); 
} 

     private void FillSpinner2(String TypeofMaterial) { 


      array2 = DB_Manager.All1(spinner1.getSelectedItemPosition()); //get from db 

    h.post(new Runnable() { 

      public void run() { 
       Adapter2.clear(); 
       for (ObjectMaterial object : array2) 
        Adapter2.add(object); 

       Adapter2.notifyDataSetChanged(); 
      } 
     }); 
} 

Maintenant, Le problème est: -

Lorsque l'activité ouverte, GetCalculationOptions appellent un fil pour remplir toutes les valeurs de spinner. En cela, il appelle la fonction LoadValuesforFirstTime(). Ici, je fais tout avec db et ui. Ici changevisibility change la visibilité de certains contrôles, FillSpinner1 fill obtient les valeurs de db, refresh l'adaptateur dans le thread principal, Spinenr2 reçoit les valeurs de db selon les valeurs sélectionnées dans spinner 1, mais aucune valeur ne sera trouvée dans spinner1 car elle n'est pas remplie jusqu'à maintenant et c'est un autre thread, maintenant point que nous devons mettre à jour l'interface utilisateur en continu à partir des fonctions LoadValuesforFirstTime().

Quelqu'un, plz m'aider ou me suggérer une autre option pour y parvenir.

Répondre

0

appeler votre méthode

runOnUiThread(new Runnable(){ 
     public void run() { 

        write your method here 

     } 
    }); 

de méthode doInbackground.

+0

Si je cours toutes les fonctions sur le fil principal de l'ui, alors l'activité va lentement. –

+0

appelez simplement cette méthode dans la méthode d'exécution qui est chargée de mettre à jour l'interface utilisateur. –

Questions connexes