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になるまで待たない彼が応答したら、新しく生成されたオブジェクトを返します。
まだヌルポインタ例外が発生します。コードをステップバイステップで実行すると、ここから[mCameraIO.getIsoSpeedRates(new CameraListener(){]が[return apertureSettings;]オブジェクトに直接ジャンプすることがわかりますが、これにはまだ必要なデータが設定されていません。 – Doru
私はそれが非常にバグのある方法で動作するようになったのですが、カメラから必要なリクエストのたびにthread.sleep(2000)が働いています。コードは戻り値availableSettings(iso、apertureなど)のすぐ上に挿入されるので、設定を正しく入力する時間を与えることができます。エラー解決の解決を待っています – Doru
AsyncTaskでこれを使用する理由はありますか?私はあなたがdoInBackground内でコールバックを使用していることを認識しました。つまり、非同期タスク内で別の非同期タスクを本質的に実行しています。 AsyncTaskを使用する必要がない場合は、潜在的な解決策で自分の答えを更新します。そうすれば、doInBackgroundの完了後にいつでも「内部」のものが返るようにすることができます。私はあなたがAsyncTaskなしで得ることができると思う。 –