Wie kriege ich den Response der API in mein TextViewField in Android Studio?
Hallo,
momentan sitze ich daran, eine Android App mit Android Studio zu entwickeln. Die App soll GET und POST benutzen können, um mit einer API arbeiten zu können.
Soweit funktioniert das auch alles. Meine Frage bezieht sich hier auf Folgendes:
Ich habe in der MainActivity den TextView TW_Rueckgabe. Hier soll der Response der POST-Funktion gespeichert werden, da ich den gerne in der App anzeigen lassen will.
Nun habe ich aber bereits ein paar Sachen ausprobiert, allerdings vergebens.
Nun zu meiner eigentlichen Frage:
Wie kriege ich hin, das der Response der POST-Klasse in dem TextView TW_Rueckgabe gespeichert wird?
Danke im Voraus.
MfG
MainActivity.java
final TextView[] TW_Rueckgabe = {
findViewById(R.id.textViewRueckgabe)
};
Button sendBtn = findViewById(R.id.sendBtn);
sendBtn.setOnClickListener(v -> {
String POST_url = "http://dphost.ddns.net:1573/cool/post.php";
String requestData = "data=" + TW_Benutzername.getText().toString();
POSTRequestTask test = (POSTRequestTask) new POSTRequestTask().execute(POST_url, requestData);
TW_Rueckgabe[0].setText(test.fetching_data);
});
POSTRequestTask.Java
class POSTRequestTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
String url = params[0];
String requestData = params[1];
String response = "";
try {
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// add request header
con.setRequestMethod("POST");
con.setDoOutput(true);
// add request data
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(requestData);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer responseBuffer = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
responseBuffer.append(inputLine);
}
in.close();
response = responseBuffer.toString();
}
catch (IOException e) {
e.printStackTrace();
}
return response;
}
@Override
protected void onPostExecute(String result) {
// print result
System.out.println("\n\n\n" + result + "\n\n\n");
fetching_data = result;
}
public String returnString() {
return fetching_data;
}
}
1 Antwort
Das Prinzip hinter asynchronen Tasks liegt darin, dass nachfolgender Code nicht explizit auf ihre Vollendung wartet, da unbestimmt ist, wann ihre Aktion überhaupt beendet werden kann. Würde der Vorgang synchron ablaufen, würde so etwas wie der Verbindungsaufbau und Datentransport mit der API den Hauptprozess blockieren, der darauf wartet, das Textfeld mit Text füllen zu können.
Stattdessen dient die onPostExecute-Methode als Callback. Sobald die Ausführung (doInBackground) beendet ist, wird sie aufgerufen. In dieser Methode solltest du also auch den Text erst in das Textfeld setzen.
Eine Referenz auf die Komponente könntest du via Konstruktor übergeben.
class PostRequestTask extends AsyncTask<String, Void, String> {
private final TextView textView;
public PostRequestTask(TextView view) {
this.textView = view;
}
/* ... */
@Override
protected void onPostExecute(String result) {
textView.setText(result);
}
}
oder du nutzt ein Command Pattern, um einen eigenen Callback von außen zu integrieren und somit die Task-Klasse stärker von der Activity zu entkoppeln.
public interface PostExecutable {
void execute(String result);
}
public class PostRequestTask extends AsyncTask<String, Void, String> {
private final PostExecutable finalTask;
public PostRequestTask(PostExecutable finalTask) {
this.finalTask = finalTask;
}
/* ... */
@Override
protected void onPostExecute(String result) {
finalTask.execute(result);
}
}
// MainActivity:
var task = new PostRequestTask(new PostExecutable() {
@Override
public void execute(String result) {
yourTextView.setText(result);
}
});
task.execute();