我想通過WHTTP與遠程設備進行通信。我發送請求並且設備響應。它並不總是立即響應,這就是爲什麼我使用AsyncTask。NPE在AsyncTask的OnPostExecute()
下面是一些下調的代碼更好地解釋:
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()
不等待,直到它得到噸他迴應,然後返回新填充的對象。
仍然遇到空指針異常。如果我一步一步地執行代碼,我發現它從這裏[mCameraIO.getIsoSpeedRates(new CameraListener(){])直接跳轉到[return apertureSettings;]對象,但仍然沒有填充所需的數據。因爲doInBackground並沒有等待我的請求得到正確的響應 – Doru
對於我需要從相機中獲取的每一個請求,thread.sleep(2000)都是以非常麻煩的方式工作的。代碼插入右上方返回availableSettings(iso,光圈等),所以我可以給它時間正確填充設置。我仍然在等待錯誤證明的決議。 – Doru
是否有一個原因,你在AsyncTask這一點?我剛剛意識到你在doInBackground中使用了回調,這意味着你基本上在異步任務中執行另一個異步任務。如果您不需要使用AsyncTask,我將使用潛在的解決方案更新我的答案,因此在doInBackground完成後,「內部」可以隨時返回。我想你可以沒有AsyncTask。 –