2017-02-02 25 views
-2

この質問は実際に何度も聞かれました。私は9つの質問(123456789)とそのすべての答えに目を通しています。彼らの誰も私の問題に取り組みません。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()のコードブロック内のすべてを実行しないのはなぜですか?

+2

あなたのコードでは、そのメソッドのcatch caluseによってキャッチされた実行時例外がスローされます。その後、returnステートメントはデータなしで実行されます。例外の原因を調べてみてください。それ以外はうまくいきます。 – KunalK

+0

@KunalK catch節を変更して、stringPack []配列をいくつかの偽のデータで返すようにしました。同じ実行時エラーがnullを返していなくても表示されています... – Gil

+0

'onPostExecute(String [] result)'。 'result'は' null'でもかまいません。しかし、あなたはヌルをチェックしておらず、盲目的には '3 'まで使い果たしていません。それはあなたに 'NullPointerException'を与えます。あなたはシーケンスがうまくいかないと思います。 – greenapps

答えて

1

コードが正常にエラーなく完了していた場合は、前に定義した空の配列(サイズ3)を返します。

Catchブロックはnullを返します。したがって、nullを返すことでトラップして処理するエラーが発生している可能性が高くなります。

キャッチ・ブロックにブレークポイントを置き、例外の原因を調査してください。

関連する問題