So, here in Java, I wrote a typical class to send json to a leisure server. (I will include the entire class below for clarity.) To the file "Fetcher.java"
Now for the callback you need an interface. The interface is trivial, only one function with a string.
public interface FetcherInterface { public void fetcherDone(String result); }
Annoyingly, for this you need the whole file, "FetcherInterface.java"
So this interface is nothing more than a “single callback with a string”. Often you only need a “single callback with no arguments”.
Actually ........ Are there any standard interfaces that I can use , or something like that?
It seems annoying that you need to put the whole interface for such a simple "standard" interface.
What is the deal about this? What is javaly's solution?
It seems you CANNOT put it in the same file :

Maybe I don’t understand something. If you could put it in one file, that would be convenient at least.
(Lambdas are not yet available. Anyway, sometimes you need an interface.)
Just for clarity, here, as you call the class
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();
or really
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); }
Here is the whole class ... File Fetcher.java
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); } }