2016-07-31 13 views
0

ich versuche, von einer URL ein einfaches JSON-Objekt zu erhalten (nicht Array, nur {} s), und ich bin immer zwei Fehler:Jackson + volley - TypeReference ist abstrakt

Error:(43, 81) error: TypeReference is abstract; cannot be instantiated 

Error:(36, 16) error: no suitable constructor found for JsonObjectRequest(String,<anonymous Listener<JSONObject>>,<anonymous ErrorListener>) 
constructor JsonObjectRequest.JsonObjectRequest(String,JSONObject,Listener<JSONObject>,ErrorListener) is not applicable (actual and formal argument lists differ in length) 
constructor JsonObjectRequest.JsonObjectRequest(int,String,JSONObject,Listener<JSONObject>,ErrorListener) is not applicable (actual and formal argument lists differ in length) 

dies mein OnCreate Code:

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_details); 

    String url = getResources().getString(R.string.json_url); 
    RequestQueue requestQueue = Volley.newRequestQueue(this); 
    requestQueue.add(GetJsonObject(url)); 
} 

und das ist meine JsonObject Methode:

@NonNull 
    private JsonObjectRequest GetJsonObject(String url) { 
     return new JsonObjectRequest(url, new Response.Listener<JSONObject>() { 
      @Override 
      public void onResponse(JSONObject response) { 
       try { 
        if (response.length() > 0) { 
         Details results = mapper.readValue(response.toString(), new TypeReference<Details>()); 
         String a = response.toString(); 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 
       Toast.makeText(getApplicationContext(), getResources().getString(R.string.no_internet), Toast.LENGTH_LONG).show(); 
      } 
     }); 
    } 

ich verstehe nicht, die Fehler, vor allem der TypeReference einer , da ich einen anderen Code (witn jsonarray) habe, der einfach so zu sein scheint.

Vielen Dank im Voraus!

+0

Sie mischen Jackson JSONObject und Android eingebauten in JSONObject, es ist wie –

+0

Secondary Problem sieht ... Das ist, wie Sie ein Jackson JSON-Objekt 'Mapper lesen .readValue (Antwort, Details.class) ' –

+0

Danke für die Antworten! ich habe den readvalue geändert, wie Sie sagen, und alle jsonobjects sind die von android eingebauten – emboole

Antwort

1

Problem: Sie Method.GET und die JSONObject jsonObject Parameter auf Ihrem JsonObjectRequest

Hier ist der Konstruktor fehlen, den ersten und dritten Parameter feststellen.

public JsonObjectRequest(int method, String url, JSONObject jsonRequest, 
     Listener<JSONObject> listener, ErrorListener errorListener) 

Alternativ auch dieser

public JsonObjectRequest(String url, JSONObject jsonRequest, 
     Listener<JSONObject> listener, ErrorListener errorListener) 

Wo würden Sie passieren null zum JSONObject es eine GET-Anfrage zu machen.


Sie verwenden Volley ein wenig zurück, obwohl; wie -in es zu einem synchronen Methodenmuster zurückdrängen. Sie müssen die Rückrufe beachten.

Nehmen Sie zum Beispiel diese abgespeckte Methode. Parametrierung der beiden Listener

@NonNull 
private JsonObjectRequest GetJsonObject(String url, Response.Listener<JSONObject> onSuccess, Response.ErrorListener onError) { 
    return new JsonObjectRequest(url, null, onSuccess, onError); 
} 

Es ist im Grunde das gleiche wie nur die Volley Request selbst zu machen.

Nun angenommen, Details ist eigentlich ein Objekt, nicht eine Liste, wie Sie behaupten. Sie verwenden TypeReference nicht für die Verwendung von Jackson.

Zurück zu Volley, ein alternatives Muster besteht darin, keine Anfrage zurückzugeben, sondern stattdessen eine anzufangen, dann muss der Rückruf dorthin gehen, wo Sie diese Daten benötigen. Außerdem haben Sie die JSONObject zurück in eine String für Jackson gedreht, so dass Sie stattdessen eine StringRequest verwenden können.

public void getJSONObject(String url, Response.Listener<String> responseListener) { 

    // Just some never-changing error message. 
    final Response.ErrorListener errorListener = new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 
       Log.e("Error", error.toString()); 
       Toast.makeText(getApplicationContext(), getResources().getString(R.string.no_internet), Toast.LENGTH_LONG).show(); 
      } 
     }); 
    }; 

    StringRequest req = new StringRequest(url, responseListener, errorListener); 
    addToRequestQueue(req); // TODO: Need to add to a RequestQueue 
} 

Und das nennen wie so

public void foo(String url) { 
     final ObjectMapper mapper = // etc...    

     // Can declare various listeners to do different things with the String response from the URL 
     Response.Listener<String> responseListener = new Response.Listener<String>() { 
      @Override 
      public void onResponse(String response) { 
       try { 
        if (response.length() > 0) { 
         Details result = mapper.readValue(response, Details.class); 
         // TODO: Do something with the object 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     }; 

     // Execution returned above, when finished with request 
     getJsonObject(url, responseListener); 
} 
+0

danke für Ihre ausführliche Antwort.Ich habe den ganzen Code geändert, wie Sie vorschlagen, ich bekam eine Fehlerantwort (meine Toast-Nachricht wird angezeigt) – emboole

+0

Ich habe einige Änderungen vorgenommen: Ich rufe die Foo-Methode onCreate auf, und die Anforderungswarteschlange lautet: StringRequest req = new StringRequest (url, responseListener, errorListener); RequestQueue requestQueue = Volley.newRequestQueue (this); requestQueue.add (req); – emboole

+0

Sicher. Ich gebe nur foo dort hin. Der wichtigste Punkt war der Inhalt. Und verschiedene Leute benutzen die RequestQueue anders, weshalb ich den Kommentar dort eingefügt habe. –