2016-07-06 6 views
0

WHTTP経由でリモートデバイスと通信しようとしています。私はリクエストを送信し、デバイスは応答します。それはすぐには必ずしも応答しないので、AsyncTaskを使用しています。ここでAsyncTaskのOnPostExecute()のNPE

は良く説明するためにいくつかのダウントリミングコードです:

private class CameraSettings extends AsyncTask<AvailableCameraSettings, Void, AvailableCameraSettings> { 
    private final String INNER_TAG = CameraSettings.class.getSimpleName(); 
    AvailableCameraSettings availableCameraSettings = new AvailableCameraSettings(); 


    @Override 
    protected void onPostExecute(AvailableCameraSettings availableCameraSettings) { 
     if(availableCameraSettings==null){ 
      Log.e(INNER_TAG, "NULL"); 
      return; 
     } 
     if (availableCameraSettings.getSetting().equals(SettingType.APERTURE)) { 
      apertureSettings = availableCameraSettings; 
      ArrayAdapter<String> apertureAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item); 
      apertureAdapter.addAll(apertureSettings.getAvailableSettings()); 

      apertureSpinner.setAdapter(apertureAdapter); 
      apertureSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
       @Override 
       public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 
        String itemAtPosition = ((String) parent.getItemAtPosition(position)); 
        mCameraIO.setAperture(itemAtPosition); 
       } 

       @Override 
       public void onNothingSelected(AdapterView<?> parent) { 

       } 
      }); 
      apertureSpinner.setEnabled(true); 
     } else if (availableCameraSettings.getSetting().equals(SettingType.ISO)) { 
      isoSettings = availableCameraSettings; 
      ArrayAdapter<String> isoSpeedAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item); 
      isoSpeedAdapter.addAll(isoSettings.getAvailableSettings()); 
      isoSpinner.setAdapter(isoSpeedAdapter); 
      isoSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
       @Override 
       public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 
        String itemAtPosition = ((String) parent.getItemAtPosition(position)); 
        mCameraIO.setIsoSpeed(itemAtPosition); 
       } 

       @Override 
       public void onNothingSelected(AdapterView<?> parent) { 

       } 
      }); 
      isoSpinner.setEnabled(true); 

     } 
    } 

    @Override 
    protected AvailableCameraSettings doInBackground(AvailableCameraSettings... params) { 
     AvailableCameraSettings parameter = params[0]; 
     if (parameter != null) { 
      Log.d(INNER_TAG, "***** Entered doInBackground method for setting " + parameter.getSetting().getName()); 
     }else{ 
      return null; 
     } 

     if (parameter.getSetting().equals(SettingType.APERTURE)) { 
      mCameraIO.getApertures(new CameraListener() { 
       @Override 
       public void onResult(JSONArray response) { 
        if (response == null) { 
         Log.d(INNER_TAG, " Response is Null"); 
         return; 
        } 
        try { 
         Log.d(INNER_TAG, "Response is: " + response.toString(4)); 
         extractAvailableSettings(response, apertureSettings); 
        } catch (JSONException e) { 
         Log.e(TAG, e.getMessage()); 
        } 
       } 

       @Override 
       public void onError(CameraIO.ResponseCode responseCode, String responseMsg) { 

       } 
      }); 
      return apertureSettings; 
     } else if (parameter.getSetting().equals(SettingType.ISO)) { 
      mCameraIO.getIsoSpeedRates(new CameraListener() { 
       @Override 
       public void onResult(JSONArray response) { 
        if (response == null) { 
         Log.d(INNER_TAG, " Response is Null"); 
         return; 
        } 
        try { 
         Log.d(INNER_TAG, "Response is: " + response.toString(4)); 
         extractAvailableSettings(response, isoSettings); 
        } catch (JSONException e) { 
         Log.e(TAG, e.getMessage()); 
        } 
       } 

       @Override 
       public void onError(CameraIO.ResponseCode responseCode, String responseMsg) { 

       } 
      }); 
     } 

     return null; 
    } 

} 

生成エラーは次のとおりです。

java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object[] java.util.Collection.toArray()' on a null object reference 
                      at java.util.ArrayList.addAll(ArrayList.java:188) 
                      at android.widget.ArrayAdapter.addAll(ArrayAdapter.java:210) 
                      at com.thibaudperso.sonycamera.timelapse.fragments.CameraSettingsFragment$CameraSettings.onPostExecute(CameraSettingsFragment.java:311) 
                      at com.thibaudperso.sonycamera.timelapse.fragments.CameraSettingsFragment$CameraSettings.onPostExecute(CameraSettingsFragment.java:297) 
                      at android.os.AsyncTask.finish(AsyncTask.java:651) 
                      at android.os.AsyncTask.access$500(AsyncTask.java:180) 
                      at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:148) 
                      at android.app.ActivityThread.main(ActivityThread.java:5468) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

ライン311は、次のとおりです。

 apertureAdapter.addAll(apertureSettings.getAvailableSettings()); 

私はList<String>が取得するヌルを理解しますそこに、なぜ私は理解していないdoInBackground()は、それがtになるまで待たない彼が応答したら、新しく生成されたオブジェクトを返します。

答えて

0

getAperturesの呼び出し()およびgetIsoSpeedRates()コールバックで(CameraListener)を取ることを意味既にAsyncTaskを使用することなく、応答のためにを待ちます。何が起こっている

は、それは、本質的にあなたのCameraSettings AsyncTaskから呼び出されて別の非同期タスク、だから、この場合には、それは doInBackgroundの完了後onResponse になってきているです。

私は、AsyncTaskを完全に削除し、次のような同様のメソッドを作成することをお勧めします。 updateAdapterへの呼び出しは、onResultから呼び出されます。実際にその結果が得られたからです。 onResultonPostExecuteAsyncTaskのものと本質的に同じですので、そこで機能を処理する必要があります。

public void getCameraSettings(AvailableCameraSettings parameter) { 

     if (parameter != null) { 
      Log.d(INNER_TAG, "***** Entered doInBackground method for setting " + parameter.getSetting().getName()); 
     }else{ 
      return null; 
     } 

     if (parameter.getSetting().equals(SettingType.APERTURE)) { 
      mCameraIO.getApertures(new CameraListener() { 
       @Override 
       public void onResult(JSONArray response) { 
        if (response == null) { 
         Log.d(INNER_TAG, " Response is Null"); 
         return; 
        } 
        try { 
         Log.d(INNER_TAG, "Response is: " + response.toString(4)); 
         extractAvailableSettings(response, apertureSettings); 
         updateAdapter(SettingType.APERTURE); 
        } catch (JSONException e) { 
         Log.e(TAG, e.getMessage()); 
        } 
       } 

       @Override 
       public void onError(CameraIO.ResponseCode responseCode, String responseMsg) { 

       } 
      }); 
      return apertureSettings; 
     } else if (parameter.getSetting().equals(SettingType.ISO)) { 
      mCameraIO.getIsoSpeedRates(new CameraListener() { 
       @Override 
       public void onResult(JSONArray response) { 
        if (response == null) { 
         Log.d(INNER_TAG, " Response is Null"); 
         return; 
        } 
        try { 
         Log.d(INNER_TAG, "Response is: " + response.toString(4)); 
         extractAvailableSettings(response, isoSettings); 
         updateAdapter(SettingType.ISO); 
        } catch (JSONException e) { 
         Log.e(TAG, e.getMessage()); 
        } 
       } 

       @Override 
       public void onError(CameraIO.ResponseCode responseCode, String responseMsg) { 

       } 
      }); 
     } 

     return null; 
    } 

次に、次のようにメソッドを追加します。基本的にはonPostExecuteのものと同じです。 isoSettingsapertureSettingsはメンバ変数なので、私はここにアクセスできると信じていますが、そうでない場合は、このメソッドに渡すパラメータとして追加します。

protected void updateAdapter(String settingType) { 
    if(availableCameraSettings==null){ 
     Log.e(INNER_TAG, "NULL"); 
     return; 
    } 
    if (settingType.equals(SettingType.APERTURE)) { 
     apertureSettings = availableCameraSettings; 
     ArrayAdapter<String> apertureAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item); 
     apertureAdapter.addAll(apertureSettings.getAvailableSettings()); 

     apertureSpinner.setAdapter(apertureAdapter); 
     apertureSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
      @Override 
      public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 
       String itemAtPosition = ((String) parent.getItemAtPosition(position)); 
       mCameraIO.setAperture(itemAtPosition); 
      } 

      @Override 
      public void onNothingSelected(AdapterView<?> parent) { 

      } 
     }); 
     apertureSpinner.setEnabled(true); 
    } else if (settingType.equals(SettingType.ISO)) { 
     isoSettings = availableCameraSettings; 
     ArrayAdapter<String> isoSpeedAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item); 
     isoSpeedAdapter.addAll(isoSettings.getAvailableSettings()); 
     isoSpinner.setAdapter(isoSpeedAdapter); 
     isoSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
      @Override 
      public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 
       String itemAtPosition = ((String) parent.getItemAtPosition(position)); 
       mCameraIO.setIsoSpeed(itemAtPosition); 
      } 

      @Override 
      public void onNothingSelected(AdapterView<?> parent) { 

      } 
     }); 
     isoSpinner.setEnabled(true); 

    } 
} 

注:私はあなたがAsyncTaskを使用するを持っていること欠けている強力な理由がある場合 - あなたは、単に内onResultの中から、あなたの新しいupdateAdapterメソッドを呼び出すことによって、同じことを達成することができますdoInBackgroundが、私はそれが不要だと思います。


+0

まだヌルポインタ例外が発生します。コードをステップバイステップで実行すると、ここから[mCameraIO.getIsoSpeedRates(new CameraListener(){]が[return apertureSettings;]オブジェクトに直接ジャンプすることがわかりますが、これにはまだ必要なデータが設定されていません。 – Doru

+0

私はそれが非常にバグのある方法で動作するようになったのですが、カメラから必要なリクエストのたびにthread.sleep(2000)が働いています。コードは戻り値availableSettings(iso、apertureなど)のすぐ上に挿入されるので、設定を正しく入力する時間を与えることができます。エラー解決の解決を待っています – Doru

+1

AsyncTaskでこれを使用する理由はありますか?私はあなたがdoInBackground内でコールバックを使用していることを認識しました。つまり、非同期タスク内で別の非同期タスクを本質的に実行しています。 AsyncTaskを使用する必要がない場合は、潜在的な解決策で自分の答えを更新します。そうすれば、doInBackgroundの完了後にいつでも「内部」のものが返るようにすることができます。私はあなたがAsyncTaskなしで得ることができると思う。 –

関連する問題