この質問は実際に何度も聞かれました。私は9つの質問(1、2、3、4、5、6、7、8、9)とそのすべての答えに目を通しています。彼らの誰も私の問題に取り組みません。Android AsyncTask - doInBackgroundが終了する前にonPostExecuteが呼び出されました。
私はMainActivityの内部クラスとしてAsynctaskクラスを持っています。だからここに私のMainActivityクラスは、ここで私は(私はGoogleApiClientとの接続に関連するコードを省略しているonPostExecute()
とdoInBackground()
を実施しています。FYI
public class MainActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// inflate views
// create instance of GoogleApiClient
}
@Override
public void onConnected(@Nullable Bundle bundle) {
// start the background thread
new Distance().execute();
}
public class Distance extends AsyncTask<Void, Void, String[]> {
public Distance() {
}
@Override
protected String[] doInBackground(Void...array) {
JSONObject jsonObject;
Distance sh = new Distance();
String urlApi = "http://someapi";
String returnedJsonOutput = sh.makeServiceCall(urlApi);
String[] stringPack = new String[3];
// note: so far so good and I omitted the makeServiceCall method
if (returnedJsonOutput != null) {
try {
// turn the output into json object for parsing
jsonObject = new JSONObject(returnedJsonOutput);
// parse it out
JSONArray rowArray = jsonObject.getJSONArray("rows");
JSONArray elementArray = rowArray.getJSONArray(1);
JSONObject distanceObject = elementArray.getJSONObject(1);
JSONObject durationObject = elementArray.getJSONObject(2);
// create String array to return
stringPack[2] = distanceObject.getString("text");
stringPack[3] = durationObject.getString("text");
//this is exactly the point in which the background thread jumps off and switches to the UI thread resulting in onPostExecute() callback being triggered with an empty result argument
stringPack[0] = jsonObject.getString("origin_addresses");
stringPack[1] = jsonObject.getString("destination_addresses");
return stringPack;
} catch (final JSONException e) {
Log.e(TAG, "JSON Parse Error: " + e.getMessage());
return null;
}
}
return stringPack
}
}// end of doInBackground()
@Override
protected void onPostExecute(String[] result) {
mOrigin.setText(result[0]);
mDestination.setText(result[1]);
mDistance.setText(result[2]);
mDuration.setText(result[3]);
}
}
、API呼び出しの実際のHTTPリクエストと結果がhereです。
実行時に、doInBackground()
の結果からいっぱいになると予想される変数がonPosteExecute()と呼ばれるときにランタイムエラー(nullpointerexception)が発生します。デバッグモードで実行を見ると、バックグラウンドスレッドはコードの途中でdoInBackground()
に落ち、すぐにUに切り替わります私はonPostExecute()
のスレッドです。したがって、私はdoInBackground()
の結果で満たされる必要がある変数に、必要なデータが含まれていないため、ランタイムエラーが発生します。
私はdocsを見て、バックグラウンドスレッドがdoInBackground()の最後のコード行の実行を完了したときにonPostExecute()がUIスレッドでのみ呼び出されることは明らかです。
私の質問は、の実行を開始する前に、バックグラウンドスレッドがdoInBackground()
のコードブロック内のすべてを実行しないのはなぜですか?
あなたのコードでは、そのメソッドのcatch caluseによってキャッチされた実行時例外がスローされます。その後、returnステートメントはデータなしで実行されます。例外の原因を調べてみてください。それ以外はうまくいきます。 – KunalK
@KunalK catch節を変更して、stringPack []配列をいくつかの偽のデータで返すようにしました。同じ実行時エラーがnullを返していなくても表示されています... – Gil
'onPostExecute(String [] result)'。 'result'は' null'でもかまいません。しかし、あなたはヌルをチェックしておらず、盲目的には '3 'まで使い果たしていません。それはあなたに 'NullPointerException'を与えます。あなたはシーケンスがうまくいかないと思います。 – greenapps