2017-01-19 5 views
0

これはカスタムリストを返すメソッドです。しかし、私は非同期タスク(OnResponse)内のリストを更新しています。私は入れ子になったボレーのリクエストを使用しなければならなかった。私はリスト項目を宣言しましたが、OnResposeメソッドの中でそれを使用することはできません。誰もこれで私を助けることができますか?メソッドからリストアイテムを返すにはどうしたらいいですか?AsyncTaskからリストを返す

private ArrayList<sItem> fetchApiData(){ 

    ArrayList<sItem> list= new ArrayList<>(); 
    String url="http://www.gadgetsinnepal.com.np/wp-json/wp/v2/posts/"; 

    JsonArrayRequest jsArrayRequest = new JsonArrayRequest 
      (Request.Method.GET, url, null, new Response.Listener<JSONArray>() { 

       @Override 
       public void onResponse(JSONArray response) { 


        try { 

         // Parsing json array response 
         // loop through each json object 

         for (int i = 0; i < response.length(); i++) { 
          sItem sitem=new sItem(); 

          JSONObject item = (JSONObject) response 
            .get(i); 
          String id = item.getString("id"); 
          sitem.id=id; 
          String date = item.getString("date"); 

          JSONObject titleobj = item 
            .getJSONObject("title"); 
          String title= titleobj.getString("rendered"); 
          sitem.title=title; 
          String featuredMedia= item.getString("featured_media"); 


          JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET, 
            "http://www.gadgetsinnepal.com/wp-json/wp/v2/media/"+featuredMedia, null, new Response.Listener<JSONObject>() { 

           @Override 
           public void onResponse(JSONObject nested_response) { 

            try { 
             JSONObject guilld = nested_response.getJSONObject("guid"); 
             String featured_img_url = guilld.getString("rendered"); 
             sitem.img=featured_img_url; 
             list.add(sitem); 
             //Toast.makeText(getApplicationContext(),"IMAGE :" + list.get(0),Toast.LENGTH_LONG).show(); 

            } catch (JSONException e) { 
             e.printStackTrace(); 
             Toast.makeText(getApplicationContext(), 
               "Error: " + e.getMessage(), 
               Toast.LENGTH_LONG).show(); 
            } 
           } 
          }, new Response.ErrorListener() { 

           @Override 
           public void onErrorResponse(VolleyError error) { 
            Toast.makeText(getApplicationContext(), 
              "ERROR "+error.getMessage(), Toast.LENGTH_LONG).show(); 
            if (error instanceof TimeoutError || error instanceof NoConnectionError) { 
             Toast.makeText(getApplicationContext(),"network timeout error", 
               Toast.LENGTH_LONG).show(); 
            } else if (error instanceof AuthFailureError) { 
             //TODO 
            } else if (error instanceof ServerError) { 
             //TODO 
            } else if (error instanceof NetworkError) { 
             //TODO 
            } else if (error instanceof ParseError) { 
             //TODO 
            } 
           } 
          }); 
          jsonObjReq.setRetryPolicy(new DefaultRetryPolicy(
            7000, 
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 

          MySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonObjReq); 


         } 
        } catch (JSONException e) { 
         e.printStackTrace(); 
         Toast.makeText(getApplicationContext(), 
           "Error: " + e.getMessage(), 
           Toast.LENGTH_LONG).show(); 
        } 
       } 
      }, new Response.ErrorListener() { 

       @Override 
       public void onErrorResponse(VolleyError error) { 
        // TODO Auto-generated method stub 

       } 
      }); 

    MySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsArrayRequest); 

    return list; 
} 

答えて

0

としてあなたのリストを宣言し、あなたはそれを宣言するときに変数決勝をマークする必要があります。最終的なリストは内部的に操作することができます(アイテムの追加/削除が可能)ので、これはリストでも問題ありません。

final ArrayList<sItem> list = new ArrayList<>();

しかし、あなたはおそらくまだあるため、非同期動作のあなたの結果を得ることはありません。メインの折り返し関数はリストを直ちに返します。 Volleyがネットワークリクエストを開始する前であっても。将来のある時にはいつも、Volleyの回答によって満たされます。

fetchApiData()(今書いているとおり)を呼び出すと、常に空のリストが返されます。 (しかし、それはあなたの使い方によっては後で記入されるかもしれませんが、これはデザインの悪いものであり、ほとんどの場合、その機能の消費者によって間違って使われるでしょう)。

おそらくfetchApiData()パラメータリストにインターフェイスまたはコールバック関数を提供し、ネットワーク応答からリストに記入したらその関数を呼び出す必要があります。

注:ネストされたコールが完了したときと、ネストされた各コールがいつ終了するかを追跡する必要があります。onResponseチェックが最後のコールであるときにコールバック。

次に、コールバックでfetchApiData()を呼び出すと、そのコールバックが呼び出されたときにリストが完全に埋められることがわかります。

+0

もしそれほど尋ねるべきではないなら、正しいデザインはどのように見えますか? –

+0

@NipeshKc実装するのが面倒です。私は実際に代わりにRxJava/RxAndroid経由でObservablesを調べることをお勧めします。この全体を書くと理解するのがずっと簡単になります。 (ObservableとRxの学習曲線を乗り越えれば) –

0

リスナーの内側に閉鎖変数を使用するには、最終的な、またはグローバルフィールドとして

関連する問題