Kompilierfehler aufgrund Konstruktor-Argumenten

  • Hallo Androidentwickler,


    ich arbeite mich derzeit mit Android Studio in die Android- und Java-Programmierung ein und beschäftige mich aktuell mit den Sensoren.
    Dabei bin ich auf folgenden Java-Code gestoßen, den ich in Android Studio zu Testzwecken übernommen habe:
    https://software.intel.com/de-…tom-based-android-tablets
    (Code-Beispiel 2-2)


    Beim Kompilieren bekomme ich folgende Fehlermeldung:
    Error:(21, 9) error: constructor SensorDialog in class SensorDialog cannot be applied to given types;
    required: Context,Sensor
    found: Context
    reason: actual and formal argument lists differ in length


    Der Kompilierfehler bezieht sich auf den SensorDialog-Konstruktor in der SensorDialog-Klasse:

    Java: SensorDialog.java
    public class SensorDialog extends Dialog implements SensorEventListener {
       Sensor mSensor;
       TextView mDataTxt;
       private SensorManager mSensorManager;
       
       public SensorDialog(Context ctx, Sensor sensor) {
          this(ctx);
          mSensor = sensor;
       }


    Ich habe mich mit den Zeilen nun mehrere Stunden auseinandergesetzt und kann hoffentlich auch Tippfehler ausschließen.
    Daher möchte ich folgende Fragen gerne in diesem Forum stellen:


    Hauptfrage:
    Warum findet der Compiler den Sensor-Wert nicht? So wie ich den Code lese wird der Wert sensor mit dem vorher als Sensor deklarierten Wert mSensor bedient.


    Zusatzfrage:
    Was wird in diesem Fall konkret mit dem Befehl this(ctx) zurückgegeben? So wie ich es aus der Oracle-Java-Hilfe herauslese, wird der this-Befehl in einem Konstruktor verwendet um auf andere Konstruktoren in derselben Klasse zu verweisen. Aus den Erläuterungen zu Context auf der developers.android-Seite kann ich nicht erkennen welche konkreten Werte hier ausgelesen werden und warum diese hier überhaupt notwendig sind.


    Es würde mich freuen, wenn mir jemand bei der Lösung dieses Problems ein paar Tipps geben könnte.


    Viele Grüße
    AirDevil



    Hier noch der Vollständigkeit halber der komplette Quellcode aus Android Studio zum Abgleich mit der Website-Version von Intel:

  • Moin,


    das Problem ist this(ctx);, wie Du Dir sicher schon gedacht hast.
    (Nachdem der Compiler ja so explizit darauf hingewiesen hat...)


    Hauptantwort
    Du übergibst dem Konstruktor this nur einen Kontext und keinen Sensor. Deshalb findet der Kompiler keinen Sensorwert.
    Die Zuweisung der Membervariable findet unterhalb dieses Konstruktoraufrufes statt und ist da auch völlig unerheblich.
    Es hilft auch nicht, den Sensor da einfach mitzugeben - dann rufst Du den Konstruktor in einer Endlosschleife auf. ;)


    Zusatzantwort
    Wenn ich mich recht entsinne sucht this(arg,...) nach passenden anderen Konstruktoren der aktuellen (this) Klasse. Deine Klasse hat nur einen einzigen Konstruktor, der zwei Argumente erfordert. Da einen Konstruktor mit nur einem Argument aufzurufen kann nicht klappen. Ergo liefert die Methode gar nichts zurück, da sie nicht ausgeführt werden kann.
    Man könnte denken: 'Heeeeey, Dialog hat einen Konstruktor, der nur einen Kontext verlangt!'
    Faktisch richtig. Aber der Konstruktor heißt Dialog, nicht SensorDialog.
    Wie aus diesem StackOverflow Kommentar hervor geht, werden Konstruktoren nicht mitgeerbt.
    Du musst also irgendwie den Konstruktor Deiner Superklasse aufrufen, damit der Dialog weiß, wohin er angezeigt werden soll.


    Einfacher Lösungsweg:
    Tausche this(ctx); gegen super(ctx);.


    Schönerer Lösungsweg:
    Füge folgende Zeilen hinzu, am Besten in die Nähe Deines Hauptkonstruktors:

    Java
    public SensorDialog(Context ctx) {
      super(ctx);
    }

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Hallo Marco,


    besten Dank für die schnelle und weiterführende Antwort. Deine beiden Lösungsvarianten stimmen den Compiler glücklich. Warum das eine schöner ist als das andere erschließt sich mir dabei noch nicht.


    Hauptproblem:
    Leider startet die App gar nicht erst. Es wird in LogCat folgender Fehler gezeigt:
    java.lang.InstantiationException: can't instantiate class com.xxx.sensordialog.SensorDialog; no empty constructor


    Aus der Oracle-Hilfe zu dem Fehler werde ich nicht wirklich schlau und in StackOverflow-Posts wird sich immer wieder auf static bezogen.


    Die SensorDialog.java habe ich an der entsprechenden Stelle so angepasst (schnelle Variante - aber auch die schönere Variante führt zum gleichen Fehler):

    Java
    public SensorDialog(Context ctx, Sensor sensor) {
       super(ctx);
       mSensor = sensor;
    }


    So wie ich es verstehe liefert der Java-Code über das Argument "mDataTxt" die gewünschten Informationen in ein TextView-Element

    Java
    mDataTxt = (TextView) findViewById(R.id.sensorDataTxt);


    Dieses habe ich in der activity_sensor_dialog.xml entsprechend mit dem Befehl innerhalb des TextView verknüpft

    XML
    android:id="@+id/sensorDataTxt"


    Die Manifest-Datei ist über den SensorDialog informiert

    XML
    <activity android:name=".SensorDialog">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>


    Die androidspezifische Umgebung um die App zu builden sollte also passen, oder?

  • Die Lösung ist, dass du, wie der Fehler dir ja schon sagt, einen leeren Konstruktor brauchst. Du musst also einen Konstruktor ohne jeglichen Parameter definieren, da Android intern wohl diesen aufrufen möchte. Es kann aber auch sein, dass du deine Klasse mit new instanziierst anstatt mit der statischen Methode newInstance, in dem du einen überladenen Konstruktor auch instanziieren kannst.


    Ich hoffe das hilft dir ;)

    MfG,
    Christopher


    Eine gewisses Maß an Freundlichkeit kann man auch von Menschen im Internet erwarten.
    Das Forum basiert komplett auf der Freiwilligkeit ihrer Nutzer und diese sollen sich wohlfühlen! Daher seid bitte freundlich. Danke

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!