2016-07-06 2 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 그 응답, 새로 채워진 개체를 반환합니다. getApertures() 및 getIsoSpeedRates에

답변

0

호출()는 그것 이미 AsyncTask를 사용할 필요가없이 응답 대기 수단 콜백 (CameraListener)에 걸릴. 무슨 일

는 본질적 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;] 객체로 직접 점프하는 것을 볼 수 있습니다.) doInBackground가 요청에 대한 적절한 응답을 기다리고 있지 않은지 확인하십시오. – Doru

+0

매우 가치있는 일이라면 카메라에서 필요한 각 요청마다 thread.sleep (2000)을 사용하는 것이 좋습니다. 코드는 반환 가능한 설정 (iso, 조리개 등) 바로 위에 삽입되므로 설정을 올바르게 채울 수있는 시간을 줄 수 있습니다. 오류 해결을 기다리는 중입니다. – Doru

+1

AsyncTask에서이 작업을 수행 할 이유가 있습니까?방금 doInBackground 내에서 콜백을 사용하고 있다는 것을 깨달았습니다. 이는 비동기 작업에서 본질적으로 또 다른 비동기 작업을 수행한다는 것을 의미합니다. AsyncTask를 사용할 필요가 없다면 잠재적 인 솔루션으로 내 대답을 업데이트하므로 doInBackground가 완료된 후 언제든지 "내부"가 반환 될 수 있습니다. AsyncTask없이 얻을 수 있다고 생각합니다. –