setVisibility reagiert nicht

  • Antworten:8
  • Bentwortet
Jan Roessler
  • Forum-Beiträge: 22

18.04.2012, 14:44:12 via Website

hi,
eventuell hab ich ja mal wieder ein verstaendnisproblem.
waehrend der programmcode in meiner activity ausgefuehrt wird, er kann durchaus laenger dauern, soll ein progress sichtbar sein.
dazu habe ich einen progress als invisible in das layout aufgenommen, den ich nun sichtbar machen moechte.
aber er wird nicht sichtbar.

package cos.client.config;

import cos.service.COSConfig;
import cos.service.COSService;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;

public class cos_config extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

public void errorMessage(String Message) {
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle(getResources().getText(R.string.errorMessage_Title));
alertDialog.setMessage(Message);
alertDialog.setButton(getResources().getText(R.string.MessageButton),new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
return;
}
});
alertDialog.show();
}
public void infoMessage(String Message) {
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle(getResources().getText(R.string.infoMessage_Titel));
alertDialog.setMessage(Message);
alertDialog.setButton(getResources().getText(R.string.MessageButton),new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
return;
}
});
alertDialog.show();
}
// nun die Knoepfe noch aktivieren
// - Konfigurationsaufruf
public void onClick_button_config( final View view){
final Intent intent = new Intent(this,cos_config_preferences.class);
startActivity(intent);
}
// - Konfigurationstest
public void onClick_button_test( final View view){
ProgressBar PR = (ProgressBar) findViewById(R.id.progress);
PR.setVisibility(View.VISIBLE);
final COSConfig Config = new COSConfig();
if (Config.loadConfig(this)) {
Log.i("cos_config", "Verbindung zum Service wird vorbereitet");
COSService service = new COSService();
service.useConfig(Config.getConfig());
if (service.callService("cldmain")) {
service.rewindParameterlist();
String ERG = "";
String P = service.getParameter();
while (P != null) {
ERG = ERG + P + "=" + service.getDataString(P)+"\n";
P = service.getParameter();
}
Log.i("cos_config", "Return:"+ERG);
PR.setVisibility(View.INVISIBLE);
infoMessage(ERG);
} else {
Log.i("cos_config", "kann keine Verbindung zum Service herstellen");
PR.setVisibility(View.INVISIBLE);
errorMessage((String)getResources().getText(R.string.progress_TEST_badCall)+":"+service.getMessage());

}
} else {
PR.setVisibility(View.INVISIBLE);
Log.i("cos_config", "kann keine Verbindung zum Service herstellen");
errorMessage((String)getResources().getText(R.string.progress_TEST_badConfig));
}

}
}

muss ich sowas wie progress.show() aufrufen und wenn ja, ich finds nicht, wie heisst das da?
setVisible hat gut funktioniert bei onCreate, nur nicht im onClick_button_test.

Antworten
Jördis M.
  • Forum-Beiträge: 2

18.04.2012, 15:39:14 via Website

edit: Ok, dann wohl eher nicht.

— geändert am 18.04.2012, 15:53:36

Antworten
Markus Gu
  • Forum-Beiträge: 2.644

18.04.2012, 15:41:44 via Website

ähm

ein .show benötigst du dafür nicht. eine progressbar ist immer sichtbar sobald sie sichtbar ist.

du schreibst etwas von "kann länger dauern". Jetzt mal meine Vermutung ohne deinen Code genau zu verstehen:

1) User drückt den Knopf
2) Progressbar wird eingeblendet
3) Service wird ausgeführt ( dauert länger )
4) Progressbar wird ausgeblendet

kann es sein, dass 3) nicht in einem background thread läuft und somit einfach die UI blockiert ? das würde nämlich genau zu deiner beschreibung passen und wäre natürlich nicht gut.

swordiApps Blog - Website

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

18.04.2012, 15:44:18 via Website

Jördis M.
Probier es mal mit einer 1 statt dem View.Visible


PR.setVisibility(1);
Würde ich auf keinen Fall machen.
Dafür gibt es die Konstanten ja. Verwendet man die absoluten Werte, hat man ein Problem, falls die sich in neueren Android Versionen ändern.

Dein Problem ist, dass du die Arbeit NICHT in einem Thread ausführst,
sondern im GUI Thread.
Der Aufruf der onClick Methode erfolgt ZWISCHEN zwei Aktualisierungen des Bildschirms und du machst im Rumpf der Methode das Element sichtbar und wieder unsichtbar. Den Rest kannst dir ja denken :)

Benutze für sowas einen AsyncTask !

EDIT: too late, damn :D

— geändert am 18.04.2012, 15:45:18

Antworten
Jan Roessler
  • Forum-Beiträge: 22

18.04.2012, 16:49:18 via Website

@markus gu

ja, genau. 3 laeuft NICHT in einem eigenen thread. nachdem ich mich mit einem eigenen thread fuer 3 schon zwei tage rumgeaergert habe, hatte das auch schon in einen service ausgelagert, wollt ichs eben im activitythread machen.
mittlerweile hab ichs begriffen.
es waere echt daemlich es nicht in einen thread auszulagern. weil es entweder einen socket-timout geben kann, wenn der angesprochene backendservice nicht an ist oder halt die reaktion vom backend laenger als 5 sekunden dauern kann. wer liest wird schlauer, ich hab in der zwischenzeit gelesen.

nun hab ichs in ner AsyncTask classe eingebunden. nunja, das sollte wohl der richtige weg sein. nur, wie bekomm ich aus der meine ergebnisse wieder raus. das war ja schon das problem mit dem thread der letzten tage. ich hole ja daten vom backend ab, das geht. aber wie bekomm ich die wieder aus dem thread bzw. dem AsyncTask raus. oder bin da schonwieder aufm holzweg?
nachdem ich rausgefunden hab, das ich ja mehrere objekt dem execute mitgeben kann, hatte ich die hoffnung diese auch von innerhalb des AsyncTask fuellen zu koennen. is aber nix drin.

....
public void onClick_button_test( final View view){
findViewById(R.id.progress).setVisibility(View.VISIBLE);
final COSConfig Config = new COSConfig();
if (Config.loadConfig(this)) {
Log.i("cos_config", "Verbindung zum Service wird vorbereitet");
COSMemory config = Config.getConfig();
COSMemory values = new COSMemory();
COSExecute X = new COSExecute();
X.execute(config,values);
findViewById(R.id.progress).setVisibility(View.INVISIBLE);
infoMessage(values.getDataString("STATUSMSG"));
} else {
//PR.setVisibility(View.INVISIBLE);
findViewById(R.id.progress).setVisibility(View.INVISIBLE);
Log.i("cos_config", "kann keine Verbindung zum Service herstellen");
errorMessage((String)getResources().getText(R.string.progress_TEST_badConfig));
}

}

private class COSExecute extends AsyncTask<COSMemory,Void,String> {
@Override
protected String doInBackground(COSMemory... cosmems) {
String ERG = "";
COSService service = new COSService();
service.useConfig(cosmems[0]);
if (service.callService("cldmain")) {
service.rewindParameterlist();
String P = service.getParameter();
while (P != null) {
ERG = ERG + P + "=" + service.getDataString(P)+"\n";
cosmems[1].set(P, service.getDataString(P));
P = service.getParameter();
}
Log.i("COSExecute", "Return:"+ERG);
cosmems[1].set("STATUS","OK");
cosmems[1].set("STATUSMSG","OK");
} else {
Log.i("COSExecute", "kann keine Verbindung zum Service herstellen");
cosmems[1].set("STATUS","ERROR");
cosmems[1].set("STATUSMSG",(String)getResources().getText(R.string.progress_TEST_badCall)+":"+service.getMessage());
}
return ERG;
}

}

Antworten
Markus Gu
  • Forum-Beiträge: 2.644

20.04.2012, 09:32:03 via Website

hmm naja

du hast mehrere möglichkeiten

1) du schreibst den Asynctask als private klasse in die gleiche datei wie deine Activity. Dann kannst einfach eine Member variable einführen für dein ergebnis. die ist dann überall sichtbar

2) du definierst ein interface, eine callback methode im asynctask. am ende des tasks, rufst du dann die callback methode auf. musst sie halt beim starten setzen. hier mal kurz skizziert
1asynctask x = new myasynctask();
2x.setCallback(implementedCallback)
3x.execute();
4
5class myasynctask extends asynctask {
6private interface callbackInterface {
7resultishere(result);
8}
9private setCallback(callbackInterface) {
10 // callback setzen
11}
12
13onpost() {
14callback.resultishere(result);
15}
16}

swordiApps Blog - Website

Antworten
Jan Roessler
  • Forum-Beiträge: 22

20.04.2012, 11:33:33 via Website

danke. das sind neue moeglichkeiten.

in dieser app hab ich die ausgabe des ergebnisses aus dem asynctask im onpost mit einem alertdialog angezeigt.
bei der naechsten, sitz ich grad dran, werd ich deinen vorschlag ausprobieren. kann ich auf diese art auch daten zwischen activitys austauschen?

in der mainactivity hab ich ne eintragsID und die will ich in einer andern activity zum loeschen nehmen. muss sie also an die activity uebergeben.
dann muss diese aber nach dem loeschen mitteilen das die mainactivity den eintrag neu laden soll bzw. einen andern eintrag neu laden soll.

Antworten
Rafael K.
  • Forum-Beiträge: 2.359

20.04.2012, 12:02:40 via Website

Jan Roessler
in der mainactivity hab ich ne eintragsID und die will ich in einer andern activity zum loeschen nehmen. muss sie also an die activity uebergeben.
dann muss diese aber nach dem loeschen mitteilen das die mainactivity den eintrag neu laden soll bzw. einen andern eintrag neu laden soll.
Ich würde nicht einer Activity an eine andere übergeben und sie schon garnicht darin als Observer zwischenspeichern.
Solche Verknüpfungen zwischen Lifecycle Objekten sind in Android mit Vorsicht zu genießen.

Du kannst Werte zwischen Activities als "Extras" im Intent übergeben.

Antworten
Jan Roessler
  • Forum-Beiträge: 22

20.04.2012, 12:47:50 via Website

absolut cool!

das geht ja simpel und gut!
und auch wieder zurueck. ich hatte da garnicht mehr dran geglaubt,das es so einfach ist.
das loest mir gleich nen sack an problemen.

habs in http://www.vogella.com/articles/AndroidIntent/article.html nachgelesen.
geht. prima. vielen dank.

Antworten