Constant and Resource Type Mismatches

  • Antworten:12
  • Bentwortet
Urs R.
  • Forum-Beiträge: 38

12.04.2017, 22:25:20 via Website

hallo zusammen
ich stehe ein bisschen wie ein esel am berg und weiss irgendwie nicht weiter. mein kleines grosse problem ist folgendes:
ich möchte auf meinem S7 eine app haben, über die ich auf eine MySQL-Datenbank zugreifen kann. für den zugriff habe ich einen JSONParser, dem ich die notwendigen daten mit einer HashMap übergeben will. die eingabe der daten mit EditText steht. um die daten dem parser zu übergeben habe ich einen AsyncTask, in dem ich die text-eingaben in strings umwandeln sollte. aussehen tut das so:

    /**
     * Datensatz speichern
     * */
    protected String doInBackground(String... args) {
        String name = inputName.getText().toString();
        String adress = inputAdress.getText().toString();
        String login = inputLogin.getText().toString();
        String password = inputPassword.getText().toString();

        // Parameter erstellen
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("name", name);
        params.put("adresse", adress);
        params.put("login", login);
        params.put("passwort", password);

        // JSONParser
        // Datensatz senden url POST method
        String url_create_password = "hier_steht_mein_link_zu/create_password.php";
        JSONObject json = jsonParser.makeHttpRequest(url_create_password,
                "POST", params);

aussehen tut das so, wie ich mir vorstellen würde. leider will android studio, dass ich da noch etwas korrigieren soll. den fehler umschreibt android studio so:
Method getText must be called from the UI thread, currently inferred thread is worker.

mir ist nicht klar was ich tun könnte, um diesen fehler an diesem ort zu beseitigen. als vorgabe für die textzeilen habe ich etwas weiter oben in meinem listing folgendes:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.add_password);

    // Edit Text
    inputName = (EditText) findViewById(R.id.inputName);
    inputAdress = (EditText) findViewById(R.id.inputAdress);
    inputLogin = (EditText) findViewById(R.id.inputLogin);
    inputPassword = (EditText) findViewById(R.id.inputPassword);

    // Datensatz erstellen
    Button btnCreatePassword = (Button) findViewById(R.id.btnCreatePassword);

ich weiss nicht ob diese infos reichen, um mir einen vorschlag für einen lösungsweg zu meinem problem zu zeigen. weitere angaben mach ich gerne auf anfrage.

— geändert am 12.04.2017, 22:38:50

Antworten
swa00
  • Forum-Beiträge: 3.704

12.04.2017, 23:59:00 via Website

Hallo Urs,

getText must be called from the UI thread

die Fehlermeldung gibt schon recht genau den Grund an .
Das UI läuft bereits in einem Thread und diesem musst du gesondert innerhalb deines Asyns ansprechen .

Bsp

mActivity.runOnUiThread(new Runnable()
{
@Override
public void run() {
// my UI staff
}
});

ABER : getText würde ich auch an dieser Stelle vermeiden.
Dein Konzept , einen Inhalt eines Edit/TextViews innerhalb deines Tasks geht i.d.R. schief.

Du solltest den Inhalt besser VOR dem Starten des Threads ermitteln und diesen dann mittels Contructor
übergeben .

Das ist dann auch sauber, denn Dein Weg ist eher sehr unstabil

— geändert am 13.04.2017, 00:02:55

Liebe Grüße - Stefan
[ App - Entwicklung ]

Pascal P.

Antworten
Urs R.
  • Forum-Beiträge: 38

13.04.2017, 07:53:42 via Website

guten tag stefan
danke für deine schnelle antwort und deinen tip.
ich habe vor jahren ein paar anwendungen in VB geschrieben und in den 80er auch schon mal ein bisschen assembler auf dem altehrwürdigen C64. mit java und android beschäftige ich mich erst seit etwa 4 monaten und bin daher also noch ein waschechtes greenhorn.

dein rat getText zu vermeiden gibt mir ein neues rätsel auf. welche möglichkeit gibt es denn als alternative, um texte in form von strings in einer hashmap an meinen parser zu übergeben? einen hinweis an welcher stelle in der android API ich mich schlau lesen kann wäre schon sehr hilfreich. ;)

gruss urs

Antworten
swa00
  • Forum-Beiträge: 3.704

13.04.2017, 08:14:49 via Website

Guten Morgen Urs,

a) hashmap ist ein wenig obsulet. Wenn du etwas in der Richtung hast , solltest du eher List/ArrayList verwenden.
b) Du darfst grundsätzlich z.b. VB / C++ / C# NICHT mit Java, insbesondere unter Android verwechseln.
Android läuft i.d.R Thread lastig und darauf ist besonders ein Augenmerk zu legen.

Wie ich oben bereits erwähnt habe, solltest du dir für deine AsyncKlasse einen Constructor basteln , und
bevor du ihn startest, deine Textinhalte auslesen und dann dem Constructor übergeben.
Dadurch kannst du innerhalb des Threads mit den Variablen sicher spielen, ohne auf den UI Thread zugreiffen zu müssen.

Bevor du für dich eine andere Variante suchst und ggf deine Variablen global oder gar statisch deklarierst, so muss
ich im Vorfeld davon abraten , das geht auch unter Android schief. (Stichwort GC / Lifecycle)

.

P.S. Für dein Vorhaben gibt es bereits sehr gute und sichere Github Projekte (ION, OkHttp, Volley)

Dort rufst du nur eine Funktion auf und in einem Callback wird dir das fertige JSON zurückgegeben .
Diese Projekte fangen bereits alle erdenklichen "Unwegsamkeiten" für dich ab , die du bei deiner Methode oben erst mal alle implementieren müsstest.

Hier mal ein Beipiel für ION :

Ion.with(this).load(url).asJsonObject().setCallback(new FutureCallback<JsonObject>()
        {
            @Override
            public void onCompleted(Exception e, JsonObject myJson)
            {
                if (myJson != null)
                {
                  //  Hier  ist dein JSON - Objekt
                }
            }
        });

— geändert am 13.04.2017, 09:30:28

Liebe Grüße - Stefan
[ App - Entwicklung ]

Pascal P.

Antworten
Urs R.
  • Forum-Beiträge: 38

13.04.2017, 21:15:42 via Website

hallo stefan

ich werde deinen rat befolgen und mich im github umsehen. eigentlich wollte ich mein wissen mit selbstversuchen erweitern, aber wenn ich deine posts hinterfrage komme ich zum schluss, dass ich auf dich hören sollte. ich denke, dass ich besser lernen und verstehen kann, wenn ich mich bei bereits bestehenden lösungen bediene statt mich endlos mit fehlschlägen zu beschäftigen.
besten dank für deine tipps. sollte ich wieder irgendwo hängenbleiben, werde ich erneut um hilfe schreien. :)

gruss urs

Antworten
swa00
  • Forum-Beiträge: 3.704

13.04.2017, 22:35:16 via Website

Hallo Urs,

grundsätzlich MUSS ich deinen Gedankengang unterstützen, alles selbst zu machen .
Das tue ich auch , denn sonst lernt man nicht .

Ganz ganz selten bediene ich mich solchen Libraries - ich baue mir sie zu 90 % selbst.

Ausnahme : UrlRequests und die Threads sind aber eigentlich einer der trickreichsten Dinge und deshalb
bediene ich mich der Libraries , weil sie eher für mich ein "Helfer" sind und nicht Hauptfunktion der App darstellen.

Du kannst dir ja mal deren Source anschauen , da steckt schon jede Menge Gehirnschmalz dahinter

So, wir freuen uns auf deinen nächsten HilfeSchrei :-)

Liebe Grüße - Stefan
[ App - Entwicklung ]

Pascal P.

Antworten
Klaus T.
  • Forum-Beiträge: 8.183

13.04.2017, 23:16:03 via Website

swa00

a) hashmap ist ein wenig obsulet. Wenn du etwas in der Richtung hast , solltest du eher List/ArrayList verwenden.

Map | List sind zwei unterschiedliche Schuhe und davon ist keins von beiden obsolet. Wie kommst du darauf? (thinking)

if all else fails, read the instructions.

Antworten
swa00
  • Forum-Beiträge: 3.704

13.04.2017, 23:41:20 via Website

Nabend Klaus :-)

Also er bastelt ja oben nur seinen String zusammen um einen Link zu bekommen.
Da braucht er m.E weder List noch HashMap.

Zu deiner Frage :
Wenn ich mich nicht ansatzweise täusche, steht das sogar in der offiziellen DevDoku - müsste ich aber nochmal suchen.

Im Sinne wurde dort geschrieben :

Hashmap wurde aus Kompatibilitätsgründen zu Java ab API 1 übernommen , später dann durch List / ArrayList
erweitert und die Speicher/Indexverwaltung für Android optimiert.
(Zumal ab dem Zeitpunkt die mehrdimensionale Objektübergabe recht einfach geworden ist ).

Ich lasse mich allerdings sehr gerne vom Gegenteil überzeugen ... :-)
.

Grundsätzlich stelle ich mir aber selbst die Frage , welchen Vorteil würde HashMap bieten , wenn man mit List/ArrayList hervorragend Objekte (d.h. nicht nur eindimensionale Strings/Integer) verwenden kann.
(und ich auch durchweg tue)

So ganz schlau bin ich heute noch nicht draus geworden :-)

Hättest du dazu eine einleuchtende Erklärung ?

— geändert am 13.04.2017, 23:57:19

Liebe Grüße - Stefan
[ App - Entwicklung ]

Antworten
Klaus T.
  • Forum-Beiträge: 8.183

14.04.2017, 00:00:53 via Website

swa00

Also er bastelt ja oben nur seinen String zusammen um einen Link zu bekommen.
Da braucht er m.E weder List noch HashMap.

Achso Ok....das mag sein.

Hashmap wurde aus Kompatibilitätsgründen zu Java ab API 1 übernommen , später dann durch List / ArrayList
erweitert ...

Das glaube ich jetzt erst mal nicht so...das Interface Map(K,V) ist was anderes als Interface List(E) - für ganz unterschiedliche Anwendungsfälle.

Ob da bei Android was spezielles gilt oder bestimmt wurde, kann ich natürlich nicht wirklich beurteilen :?

Edit: klar... eine (Hash)Map braucht man natürlich nicht, wenn eine (Array)List angebracht ist ... und umgekehrt! :D

— geändert am 14.04.2017, 00:04:27

if all else fails, read the instructions.

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

14.04.2017, 13:00:07 via App

Das ist in dem Fall völlig egal, denn seine HttpRequest Methode benötigt die HaspMap:
Aus JSONParser.java:

public JSONObject makeHttpRequest(String url, String method, HashMap params)

         

— geändert am 14.04.2017, 13:00:19

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Urs R.
  • Forum-Beiträge: 38

15.04.2017, 11:56:23 via Website

Ich habe versucht die HashMap durch List bzw. ArrayList zu ersetzen und hab dafür die halbe $POST-/$GET-activity umgeschrieben. nach gut 2 stunden hab ich kein befriedigendes resultat erzielen können. vor allem hätte das noch weitere änderungen nach sich gezogen, die am schluss das ganze projekt betroffen hätten. ich hab mich dann wieder für die HashMap entschieden und das vorsichtshalber angelegte backup wieder eingesetzt.

noch ein kurzer überblick auf mein projekt:
ich habe anfang jahr beschlossen alle im internet benutzten logins mit einem eigenen passwort zu versehen. zuvor habe ich je nach relevanz der zugänge nur 4 unterschiedliche passwörter verwendet. wenn ich da versehentlich ein falsches benutzt habe, sind nur noch 3 weitere möglichkeiten gegeben gewesen. für die verwaltung meiner nun über 50 passwörter und unterdessen auch mehreren unterschiedlichen benutzernamen, habe ich eine MySQL-Datenbank angelegt, auf die ich mit laptop und pc zugreifen kann. für das smartphone habe ich eine provisorische app gebastelt, dessen liste ich jedesmal separat ergänzen muss, wenn neue logindaten dazu kommen. darum versuche ich eine app zu bauen, die mich von laptop und pc unabhängig macht (z.B. auf arbeit oder bei freunden) und mit der ich auch neue zugänge erstellen kann. etwas bestehendes, das meine bedürfnisse befriedigen könnte, habe ich nicht gefunden. :)

PS: ich bastle mir mit der HashMap nicht nur die url zusammen. ich verwende auch für das übermitteln der datensätze in beiden richtungen eine map. für das anzeigen der liste auf dem smartphone ist hingegen die ArrayList erste wahl. die übergabe der HashMap an eine ArrayList ist aber keine grosse sache. das geht schnell und unkompliziert.

— geändert am 15.04.2017, 12:04:34

Antworten
swa00
  • Forum-Beiträge: 3.704

15.04.2017, 12:04:10 via Website

Hallo Urs,

Pascal hat oben schon geschrieben , dass du bei makeHttpRequest das HashMap als zwingende Vorgabe benötigst , das ist mir bei meinen Tip unterlaufen - ich hatte mich dabei eher auf die allgemeine Verwendung von Hashmap eingeschossen.

Sorry für die leichte Verwirrung !

Funktioniert es denn jetzt ? was hast du denn geändert ? onRunUIThread ? oder doch die ION verwendet ??

Und da du "sensible" Daten durch die Gegend schiebst : Auf Serverseite auch PDO ggf verschlüsselt??

— geändert am 15.04.2017, 12:06:52

Liebe Grüße - Stefan
[ App - Entwicklung ]

Antworten
Urs R.
  • Forum-Beiträge: 38

15.04.2017, 12:40:06 via Website

der fehler mit dem "Constant and Resource Type Mismatches" ist behoben. dafür habe ich dank der experimente und dem zusätzlichen studium anderer lösungen einen passenden weg gefunden. eine analyze -> inspect code der app durch android studio gibt mir nur noch eine einzige warnung aus: App is not indexable by Google Search....
diese warnung erweckt mein interesse zum jetzigen zeitpunkt aber überhaupt nicht.
die app selbst scheint zu laufen. was aber scheinbar noch probleme macht ist der php-zugang auf meinem host-server. der debugger gibt mir keinen fehler aus. nur beim versuch daten zu senden oder empfangen kommt ein fehlercode zurück. da bin ich jetzt am suchen der ursache. :)

Antworten