2016-12-08 3 views
1

Also hier in Java habe ich eine typische Klasse geschrieben, um JSON zu einem Rest-Server zu senden. (Ich werde die ganze Klasse unten zur besseren Übersicht hinzufügen.) Das ist also eine Datei "Fetcher.java""Standard einfache" Schnittstellen in Java?

Jetzt für den Rückruf benötigen Sie eine Schnittstelle. Die Schnittstelle ist trivial, nur eine Funktion mit einer Zeichenkette.

public interface FetcherInterface { 
    public void fetcherDone(String result); 
} 

Ärgerlicher benötigen Sie eine ganze Datei für das, „FetcherInterface.java“

Also diese Schnittstelle ist nichts anderes als „ein Rückruf mit einem String“. Oft brauchen Sie nur "einen Rückruf ohne Argumente".

Tatsächlich ......... gibt es eine Art von Standard-Schnittstellen, die ich verwenden kann oder so ähnlich?

Es scheint irgendwie nervig zu sein, eine ganze Schnittstelle für solch eine einfache "Standard" -Schnittstelle einzubauen.

Was ist der Deal dazu? Was ist die Java-Lösung?

Es scheint, Sie NICHT es in der gleichen Datei setzen kann:

es

enter image description here

Vielleicht falsch verstehe ich etwas. Wenn Sie es in dieselbe Datei schreiben könnten, wäre das zumindest praktisch.

(Lambda noch nicht praktisch verfügbar. Wie auch immer, manchmal will man eine Schnittstelle.)


Gerade für Klarheit, hier ist, wie Sie die Klasse rufen

JSONObject j = new JSONObject(); 
    try { 
     j.put("height", 2.1); 
     j.put("width", 2.5); 
     j.put("command", "blah"); 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 
    new Fetcher("mobile/login", j, new FetcherInterface() { 
       @Override 
       public void fetcherDone(String result) { 
        Log.d("DEV","all done"); 
        doSomething(result); 
       } 
     } 
    ).execute(); 

oder in die Tat

public class HappyClass extends Activity implements FetcherInterface { 
... 

private void someCall() { 
    JSONObject j = new JSONObject(); 
    try { 
     j.put("height", 2.1); 
     j.put("width", 2.5); 
     j.put("command", "blah"); 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 
    new Fetcher("mobile/data", j, this).execute(); 
    devBlank(); 
} 

@Override 
public void fetcherDone(String result) { 
    Log.d("DEV","all done" +result); 
    doSomething(result); 
} 

Hier ist die ganze Klasse ... Fetcher.java Datei

public class Fetcher extends AsyncTask<Void, Void, String> { 

    private String urlTail; 
    private JSONObject jsonToSend; 
    private FetcherInterface callback; 

    // initializer... 
    Fetcher(String ut, JSONObject toSend, FetcherInterface cb) { 
     urlTail = ut; 
     jsonToSend = toSend; 
     callback = cb; 
    } 

    @Override 
    protected String doInBackground(Void... params) { 

     HttpURLConnection urlConnection = null; // declare outside try, to close in finally 
     BufferedReader reader = null;   // declare outside try, to close in finally 
     String rawJsonResultString = null; 
     String json = jsonToSend.toString(); 

     Log.d("DEV","the json string in Fetcher is " +json); 

     try { 
      URL url = new URL("https://falcon.totalfsm.com/" + urlTail); 

      Log.d("DEV","the full URL in Fetcher is " +url); 

      // open a json-in-the-body type of connection....... 
      urlConnection = (HttpURLConnection) url.openConnection(); 
      urlConnection.setRequestMethod("POST"); 
      urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); 
      urlConnection.setDoOutput(true); 
      urlConnection.setDoInput(true); 
      urlConnection.setConnectTimeout(5000); 
      // urlConnection.setDoOutput(false); // can be important? 

      urlConnection.connect(); 

      OutputStream os = urlConnection.getOutputStream(); 
      os.write(json.getBytes("UTF-8")); 
      os.close(); 

      // annoyingly, you have to choose normal versus error stream... 
      InputStream inputStream; 
      int status = urlConnection.getResponseCode(); 
      if (status != HttpURLConnection.HTTP_OK) 
       inputStream = urlConnection.getErrorStream(); 
      else 
       inputStream = urlConnection.getInputStream(); 
      if (inputStream == null) { // nothing to do. 
       return null; 
      } 

      StringBuffer buffer = new StringBuffer(); 
      reader = new BufferedReader(new InputStreamReader(inputStream)); 
      String line; 
      while ((line = reader.readLine()) != null) { // adding newlines makes debugging easier 
       buffer.append(line + "\n"); 
      } 

      if (buffer.length() == 0) { // stream was empty 
       return null; 
      } 

      rawJsonResultString = buffer.toString(); 
      return rawJsonResultString; 

     } catch (IOException e) { 
      Log.e("PlaceholderFragment", "Error ", e); 
      return null; 
     } finally{ 
      if (urlConnection != null) { 
       urlConnection.disconnect(); 
      } 
      if (reader != null) { 
       try { 
        reader.close(); 
       } catch (final IOException e) { 
        Log.e("PlaceholderFragment", "Error closing stream", e); 
       } 
      } 
     } 
    } 

    @Override 
    protected void onPostExecute(String s) { 
     super.onPostExecute(s); 
     Log.d("DEV", "Fetcher done"); 
     if (s==null) { 
      Log.d("DEV","applying anti-null measures in Fetcher!"); 
      s = "message from app communications layer: 'null' returned from servers for that call at " +urlTail; 
     } 
     callback.fetcherDone(s); 
    } 
} 
+1

Laut [der Dokumentation] (https://developer.android.com/guide/platform/j8-jack.html) unterstützt Android lambdas. Sie müssen etwas mehr arbeiten, wenn Sie API-Level 23 oder niedriger anvisieren. –

+0

Hallo Ted, danke, wie ich schon erwähne ich schätze lambdas sind eine kommende Möglichkeit. Weißt du, gibt es eine Antwort auf meine Frage zu Schnittstellen? Gibt es vielleicht "Standard-Interfaces" oder so? – Fattie

+0

'Ärgerlich brauchen Sie eine ganze Datei dafür," FetcherInterface.java "' Nicht unbedingt. Sie können die Klasse in eine andere Java-Datei einfügen, z. B. eine Aktivitätsklasse. –

Antwort

1

Ich fühle mich schlecht meine eigene Frage zu beantworten, aber da es keine anderen Antworten gab, kann diese Information hilfreich sein.

DaveNewton und Rowtang die genaue Antworten hier geliefert haben:

(Punkt 1) Wenn Sie einen wirklich öffentlichen Schnittstelle wollen, geht es in einer eigenen Datei. So funktioniert Java. Es gibt keine Alternative.

(Punkt 2) Normalerweise verwenden Sie protected interface und deklarieren Sie die Schnittstelle innerhalb der Klasse. Es kann dann in der gesamten App verwendet werden.

So ...

public class Fetcher extends AsyncTask<Void, Void, String> { 

    protected interface FetcherInterface { 
     public void fetcherDone(String result); 
    } 

    private String urlTail; 
    private JSONObject jsonToSend; 
    private FetcherInterface callback; 

    Fetcher(String ut, JSONObject toSend, FetcherInterface cb) { 
     urlTail = ut; 
     jsonToSend = toSend; 
     callback = cb; 
    } 

    @Override 
    protected String doInBackground(Void... params) { 
    .... 

(C# Programmierer nennen würde es vielleicht "IFetcher".)