2017-10-06 5 views
0

J'applique la mise à niveau 2 dans mon application pour appeler les services Web. Mon code est comme ci-dessous:Android Rénovation: attendre la réponse

SignUp.java

ConnectionDetector connectionDetector = new ConnectionDetector(SignUpActivity.this); 
if (connectionDetector.isConnectingToInternet()) { 
    ArrayList<HashMap<String, String>> arrayListCountryDetails = new ArrayList<>(); 
    GetCountryList getCountryList = new GetCountryList(); 
    arrayListCountryDetails = getCountryList.CallWebServiceForCountryDetails(this); 

    // The app should wait here till the above retrofit web service calling returns response 


    CountryDetailsAdapter countryDetailsAdapter = new CountryDetailsAdapter(SignUpActivity.this, arrayListCountryDetails); 
    spinnerCountryName.setAdapter(countryDetailsAdapter); 
} else { 
    String message = "No internet connection."; 
    AlertDialog alertDialog = new AlertDialog.Builder(this).create(); 
    alertDialog.setTitle(getResources().getString(R.string.app_name)); 
    alertDialog.setMessage(message); 
    alertDialog.setCancelable(false); 
    alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.dismiss(); 
       } 
      }); 
    alertDialog.show(); 
} 

GetCountryList.java

public class GetCountryList { 
    ProgressDialog dialog; 
    APIService mAPIService; 
    ArrayList<HashMap<String, String>> arrayListCountryDetails; 

    public ArrayList<HashMap<String, String>> CallWebServiceForCountryDetails(final Context context) { 
     dialog = new ProgressDialog(context); 
     dialog.setMessage("Please wait..."); 
     dialog.setCancelable(false); 
     dialog.show(); 

     arrayListCountryDetails = new ArrayList<>(); 

     mAPIService = ApiUtils.getAPIService(); 
     mAPIService.getCountryDetails().enqueue(new Callback<CountryDetailsResponseModel>() { 
      @Override 
      public void onResponse(Call<CountryDetailsResponseModel> call, Response<CountryDetailsResponseModel> response) { 

       if (response.isSuccessful()) { 
        HashMap<String, String> cntDetails = new HashMap<>(); 
        cntDetails.put("airLineID", "0"); 
        cntDetails.put("airLineName", "Select Airline"); 
        arrayListCountryDetails.add(cntDetails); 

        // Get response 
        try { 
         if (response.body().getStatus() == 200 && response.body().getMessage().equalsIgnoreCase("success")) { 
          for (int count = 0; count < response.body().getCountry().size(); count++) { 
           cntDetails = new HashMap<>(); 
           String countryID = response.body().getCountry().get(count).getCountryId(); 
           String countryName = response.body().getCountry().get(count).getCountryName(); 

           cntDetails.put("countryID", countryID); 
           cntDetails.put("countryName", countryName); 
           arrayListCountryDetails.add(cntDetails); 
          } 

          // do UI work here 
          if (dialog.isShowing()) { 
           dialog.dismiss(); 
          } 
         } else { 
          // do UI work here 
          if (dialog.isShowing()) { 
           dialog.dismiss(); 
          } 
         } 
        } catch (Exception e) { 
         // do UI work here 
         if (dialog.isShowing()) { 
          dialog.dismiss(); 
         } 
        } 
       } 
      } 

      @Override 
      public void onFailure(Call<AirLineDetailsResponseModel> call, Throwable t) { 
       // do UI work here 
       if (dialog.isShowing()) { 
        dialog.dismiss(); 
       } 
      } 
     }); 

     return arrayListCountryDetails; 
    } 
} 

Quand je suis l'exécution du code je reçois une erreur d'exception de pointeur NULL:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Spinner.setAdapter(android.widget.SpinnerAdapter)' on a null object reference 
    at com.abc.xyz.SignUpActivity.initializeScreen(SignUpActivity.java:176) 
    at com.abc.xyz.SignUpActivity.onCreate(SignUpActivity.java:147) 
    at android.app.Activity.performCreate(Activity.java:6575) 
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1134) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3121) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3278)  
    at android.app.ActivityThread.access$1000(ActivityThread.java:211)  
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1705)  
    at android.os.Handler.dispatchMessage(Handler.java:102)  
    at android.os.Looper.loop(Looper.java:145)  
    at android.app.ActivityThread.main(ActivityThread.java:6912)  
    at java.lang.reflect.Method.invoke(Native Method) 

Je sais que c'est parce que l'exécution de l'initialisation de spinner a lieu avant la réponse de retrofit.

S'il vous plaît me suggérer comment puis-je attendre la réponse de rénovation. Quels changements je dois faire dans le code ci-dessus. S'il vous plaît, je ne suis pas en mesure d'aller de l'avant à cause de ce problème. Merci d'avance.

+0

utilisation courte et simple AsyncTask et réglez votre adaptateur après avoir la liste des pays dans ** arrayListCountryDetails ** vérifiez votre taille de liste> 0 avant de définir l'adaptateur –

Répondre

1

Faites très grossièrement quelque chose comme ceci. Je viens de placer la partie nécessaire du code dans les méthodes AsyncTask. Modifier si nécessaire.

if (connectionDetector.isConnectingToInternet()) { 


     // The app should wait here till the above retrofit web service calling returns response 

    AsyncTask task = new AsyncTask<Void, Void, List<Map<String, String>>>() { 
     @Override 
     protected String doInBackground(Void... params) { 
      List<Map<String, String>> arrayListCountryDetails = new ArrayList<>(); 
      GetCountryList getCountryList = new GetCountryList(); 
      arrayListCountryDetails = getCountryList.CallWebServiceForCountryDetails(this); 
      return arrayListCountryDetails; 
     } 

     @Override 
     protected void onPostExecute(List<Map<String, String>> arrayListCountryDetails) { 
      CountryDetailsAdapter countryDetailsAdapter = new CountryDetailsAdapter(SignUpActivity.this, arrayListCountryDetails); 
      spinnerCountryName.setAdapter(countryDetailsAdapter); 
     } 

     @Override 
     protected void onPreExecute() {} 

     @Override 
     protected void onProgressUpdate(Void... values) {} 
    } 
    task.execute(); 

} 

supprimer également tous les appels de l'interface utilisateur de votre GetCountryList puisque ce sera exécuté sur « fond »

+0

Est-ce une bonne façon de le faire? –

+1

'AsyncTask' est la bonne façon de faire lors de l'accès aux bases de données, urls et autres processus de" fond "afin de ne pas bloquer l'interface utilisateur. Faire des recherches pour arriver à vos propres conclusions https://developer.android.com/reference/android/os/AsyncTask.html – pleft

+1

@pleft retrofit appel réseau déjà en arrière-plan, je ne pense pas que son bon moyen d'utiliser AsyncTask. –

0

passe l'objet Spinner tandis que les données de chargement et kit adaptateur après chargement complet

public class GetCountryList { 
ProgressDialog dialog; 
APIService mAPIService; 


public void CallWebServiceForCountryDetails(final Context context,final Spinner spinnerCountryName) { 
    dialog = new ProgressDialog(context); 
    dialog.setMessage("Please wait..."); 
    dialog.setCancelable(false); 
    dialog.show(); 

    final ArrayList<HashMap<String, String>> arrayListCountryDetails = new ArrayList<>(); 

    mAPIService = ApiUtils.getAPIService(); 
    mAPIService.getCountryDetails().enqueue(new Callback<CountryDetailsResponseModel>() { 
     @Override 
     public void onResponse(Call<CountryDetailsResponseModel> call, Response<CountryDetailsResponseModel> response) { 

      if (response.isSuccessful()) { 
       HashMap<String, String> cntDetails = new HashMap<>(); 
       cntDetails.put("airLineID", "0"); 
       cntDetails.put("airLineName", "Select Airline"); 
       arrayListCountryDetails.add(cntDetails); 

       // Get response 
       try { 
        if (response.body().getStatus() == 200 && response.body().getMessage().equalsIgnoreCase("success")) { 
         for (int count = 0; count < response.body().getCountry().size(); count++) { 
          cntDetails = new HashMap<>(); 
          String countryID = response.body().getCountry().get(count).getCountryId(); 
          String countryName = response.body().getCountry().get(count).getCountryName(); 

          cntDetails.put("countryID", countryID); 
          cntDetails.put("countryName", countryName); 
          arrayListCountryDetails.add(cntDetails); 
         } 

         // do UI work here 
         if (dialog.isShowing()) { 
          dialog.dismiss(); 
         } 
        //set Adapter 

        CountryDetailsAdapter countryDetailsAdapter = new CountryDetailsAdapter(context, arrayListCountryDetails); 
        spinnerCountryName.setAdapter(countryDetailsAdapter); 
        } else { 
         // do UI work here 
         if (dialog.isShowing()) { 
          dialog.dismiss(); 
         } 
        } 
       } catch (Exception e) { 
        // do UI work here 
        if (dialog.isShowing()) { 
         dialog.dismiss(); 
        } 
       } 
      } 
     } 

     @Override 
     public void onFailure(Call<AirLineDetailsResponseModel> call, Throwable t) { 
      // do UI work here 
      if (dialog.isShowing()) { 
       dialog.dismiss(); 
      } 
     } 
    }); 


}