2017-10-06 27 views
0

私は、Webサービスを呼び出すために私のアプリケーションにretrofit 2を実装しています。私のコードは以下の通りです:Android Retrofit:応答を待つ

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

私はと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) 

これは、改造応答の前にスピナーの初期化の実行が行われるためです。

私はどのように改造応答を待つことができますか教えてください。上記のコードで何をする必要がありますか?この問題のために私は先に進むことができません。 ありがとうございます。

+0

短いと簡単な使用後の設定アダプターAsyncTask **あなたが** arrayListCountryDetails **の国リストを持っている後にあなたのアダプターを設定する**セットアダプターの前にあなたのリストサイズ> 0をチェックする –

答えて

1

非常におおよそ次のようなことをします。私はコードの必要な部分をAsyncTaskのメソッドの中に置きました。必要に応じて変更します。また

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

} 

これは「バックグラウンド」で実行されますので、ごGetCountryListから任意のUIの呼び出しを削除

+0

それは正しい方法ですか? –

+1

'AsyncTask'は、データベース、URL、およびその他の"バックグラウンド "プロセスにアクセスしてUIをブロックしないようにするための正しい方法です。 https://developer.android.com/reference/android/os/AsyncTask.html – pleft

+1

@pleft retrofitネットワークコールはすでにバックグラウンドで、私はAsyncTaskを使用する良い方法とは思わない。 –

0

峠のSpinnerオブジェクト間のデータのロードと完全な負荷

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


} 
関連する問題