2017-10-06 4 views
0

Ich implementiere Retrofit 2 in meiner App, um Web-Services aufzurufen. Mein Code ist wie folgt:Android Retrofit: Warte auf Antwort

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

Wenn ich den Code bin Ausführung i als Null-Zeiger-Ausnahmefehler immer bin:

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) 

Ich weiß, dass dies ist, weil die Spinnerinitialisierung Ausführung vor Retrofit-Antwort stattfindet.

Bitte schlagen Sie mir vor, wie kann ich auf die Nachrüstung Antwort warten. Welche Änderungen muss ich im obigen Code vornehmen? Bitte ich bin nicht in der Lage, aufgrund dieses Problems voranzukommen. Vielen Dank im Voraus.

+0

kurze und einfache Bedienung AsyncTask und setze deinen Adapter, nachdem du eine Länderliste in ** arrayListCountryDetails hast ** überprüfe deine Listengröße> 0 bevor du den Adapter einstellst –

Antwort

1

Sehr grob tun Sie etwas wie folgt. Ich habe gerade den notwendigen Teil des Codes innerhalb der AsyncTask Methoden platziert. Ändern Sie bei Bedarf.

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(); 

} 

Auch alle UI Anrufe von Ihrem GetCountryList entfernen, da dies auf „Hintergrund“ ausgeführt wird

+0

Ist es ein richtiger Weg? –

+1

'AsyncTask' ist die richtige Vorgehensweise beim Zugriff auf Datenbanken, URLs und andere" Hintergrund "-Prozesse, um die Benutzeroberfläche nicht zu blockieren. Tun Sie etwas Forschung, um zu Ihren eigenen Schlussfolgerungen zu kommen https://developer.android.com/reference/android/os/AsyncTask.html – pleft

+1

@pleft Retrofit Netzwerkanruf bereits im Hintergrund, ich denke nicht, es ist eine gute Möglichkeit, AsyncTask zu verwenden. –

0

Pass Spinner Objekt beim Laden von Daten und stellten Adapter nach Ladung vollständig

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


}