# Klasse im selben Package aufrufen



## Gast2 (31. Aug 2012)

Hallo,

ich habe meine MainActivity.java und will darin eine zweite Java-Klasse "ZweiteKlasse.java" und die darin befindliche Methode "get.Info()" aufrufen, die ich zuvor erzeugt habe.

Im Manifest habe ich die neue Klasse eingebunden.
[XML]
        <activity 
            android:name=".ZweiteKlasse"
            android:label="@string/titel_info_geben">
        </activity>[/XML]

Den Aufruf habe ich über den Klassennamen.Methode(); versucht
auch über com.example.namespace.Klassennamen.class.Methode();
und sonst umsonst rumprobiert.

Die ZweiteKlasse steht im Ordner "src" und F5 habe ich reichlich bedient.

*WIE SPRECHE ICH DIE METHODE IN DER NACHBARKLASSE AN?*
(Ich glaub ich hab'n Brett vor'm Kopp.)


----------



## nillehammer (31. Aug 2012)

Ist denn die Methode, die Du aufrufen willst, statisch? Ansonsten bräuchtest Du eine Instanz von _ZweiteKlasse_, um auf dieser die Methode aufzurufen


----------



## Trolok (31. Aug 2012)

müsste funktionieren

```
ZweiteKlasse zk=new ZweiteKlasse();
zk.getInfo();
```


----------



## Gast2 (31. Aug 2012)

Trolok hat gesagt.:


> ```
> ZweiteKlasse zk=new ZweiteKlasse();
> zk.getInfo();
> ```



Es fiel mir wie Schuppen von den Augen... :applaus:

*Aber *aus irgendeinem Grund bekomme ich eine *NullPointer Exception* bei der Zuweisung:

```
zk=new ZweiteKlasse();
```
( in onCreate(..) )

Im Manifest habe ich wie oben gezeigt die Klasse eingepflegt.

*Hat jemand eine Idee?*


----------



## Trolok (31. Aug 2012)

versuch mal so udn sag ob ein Fehler auftaucht

```
public class MainActivity extends Activity {
         ZweiteKlasse zk=new ZweiteKlasse();
         public void onCreate(Bundle savedInstanceState) {
               [...]
         }
}
```
falls ja müsstest du die ZweiteKlasse posten


----------



## Gast2 (31. Aug 2012)

Trolok hat gesagt.:


> falls ja müsstest du die ZweiteKlasse posten



JA, der Fehler tritt weiterhin auf.


```
package com.example.test;

import android.app.Activity;
import android.widget.TextView;

public class ZweiteKlasse extends Activity  {

	public TextView meinText = (TextView) findViewById(R.id.meinText);
	
	public void worteAendern (String neu){       
		meinText.setText("geändert");
	}

}
```

An der selben Stelle. Die eigentliche Methode worteAendern() habe ich noch gar nicht aufgerufen.


----------



## SlaterB (31. Aug 2012)

>  public TextView meinText = (TextView) findViewById(R.id.meinText)

schreibe nicht solche Code-Zeilen,
deklarierte Variablen werden noch vor dem Konstruktor initialisiert,
warum sollte findViewById() da schon funktionieren?
das ist doch bestimmt von zahlreichen Hintergrund-Initialisierungen abhängig,

> ZweiteKlasse zk=new ZweiteKlasse();
genauso


lasse ein Objekt erstmal mit leeren oder einfachen Konstruktor zur Ruhe kommen

---

bzw. das gehört anscheinend in onCreate(), 
wenn diese Methode dran ist, kann man vielleicht von einen gewissen Initialisierungsstand ausgehen

hier habe ich gerade ein Beispiel gefunden, in welchem ein solchen Aufruf in onCreate() steht
https://github.com/Yelp/parcelgen/b.../src/com/yelp/parcelgen/BusinessActivity.java


gibt es eigentlich eine Fehlermeldung mit StackTrace? 
je nach Ausführlichkeit könnte man erkennen ob der Fehler in findViewById() bzw. weiteren Untermethoden auftritt


----------



## Gast2 (31. Aug 2012)

SlaterB hat gesagt.:


> deklarierte Variablen werden noch vor dem Konstruktor initialisiert,


klar, habe ich auch probiert.



SlaterB hat gesagt.:


> gibt es eigentlich eine Fehlermeldung mit StackTrace?
> je nach Ausführlichkeit könnte man erkennen ob der Fehler in findViewById() bzw. weiteren Untermethoden auftritt



Ne, leider finde ich (in LogCat) nur fatal error und nullpointer axception als Hinweis.


Es hängt an der Zeile 11 in ZweiteKlasse.java, hier gibt es den Fehler.

```
meinText = (TextView) findViewById(R.id.meinText);
```


noch mal die Quelltexte:
MainActivity:

```
package com.example.test;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;

public class MainActivity extends Activity {
	
	ZweiteKlasse zk;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        zk = new ZweiteKlasse();
        zk.worteAendern("Neuer Text");
    }
}
```

ZweiteKlasse:

```
package com.example.test;

import android.app.Activity;
import android.widget.TextView;

public class ZweiteKlasse extends Activity  {

	public TextView meinText;
	
	public void worteAendern (String neu){      
		meinText = (TextView) findViewById(R.id.meinText);
		meinText.setText(neu);
	}
}
```

Ich könnte noch die LogCat -Daten kopieren, aber wie oben schon erwähnt finde ich(!) da nix weiter hilfreiches.

*Warum läuft das Programm nicht durch?*


----------



## SlaterB (31. Aug 2012)

was ist "R.id.meinText"?
gibt es sogar im Internet zu finden
Problem mit setText und Platzhalter in strings.xml - Android Forum - AndroidPIT

weißt du welcher Text das sein müsste, falls korrekterweise irgendwo definiert aber für dich bekannt?
setze dann direkt einen String "blahblah", immer noch Fehler?

------

darf man überhaupt Activity-Objekte einfach so selber erzeugen?
überschreibe onCreate(), logge Aufruf, wird von niemanden aufgerufen, oder?

wer erzeugt MainActivity? dort geht vielleicht findViewById(), da korrekt eingebunden,
in der zweiten losen Activity nicht

brauchst du eine zweite Activity? erstelle lieber leere einfache Klassen, übergib die erste für Framework-Aufrufe


-----

kannst du ein try/catch um "zk = new ZweiteKlasse();" setzen, die Exception abfangen und auf irgendeine Weise die Information des hoffentlich vorhandenen StackTraces extrahieren/ loggen?

die Welt fing mit System.out.println() an, da ging noch alles,
aber je höher man irgendwie kommt, mit komplizierten Frameworks/ Loggern, oder je tiefer man geht mit eingeschränkten APIs auf mobilen Geräten, desto weniger essentielles scheint manchmal zu laufen/ unter Kontrolle zu sein 

eine Programmausgabe ist DIE zentrale Programmfunktion überhaupt, wenn man die nicht selber bestimmt, kann man einpacken


----------



## Trolok (31. Aug 2012)

folgendes funktioniert:

```
Activity

 public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        zk=new ZweiteKlasse();
        Button button=(Button) findViewById(R.id.button1);
        button.setOnClickListener(temp);       
        zk.worteAendern("TEST",this);
    }
```


```
ZweiteKlasse

import android.app.Activity;
import android.widget.TextView;
public class ZweiteKlasse   {
    public void worteAendern (String neu, Activity a){ 
    	TextView meinText = (TextView) a.findViewById(R.id.meinText);
    	meinText.setText(neu);
       
    }
}
```

Der gedanke ist MainActivity zu übergeben, dies kann man schon nach der erstellung von ZweiterKlasse machen:


```
in onCreate:
zk=new ZweiteKlasse();
zk.setActivity(this);
```

leider fand ich keine andere Lösung, generell (und ich hoffe ich werde berichtigt falls ich falsch liege) gehören Activity und deren .xml zusammen d.h es sollte nur eine Activity auf .xml Elemente zugreifen

ganzer code:

```
package com.example.test;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
	ZweiteKlasse zk;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        zk=new ZweiteKlasse();
        zk.setAct(this);
        Button button=(Button) findViewById(R.id.button1);
        button.setOnClickListener(temp);       

    }
    OnClickListener temp=new OnClickListener(){
    	public void onClick(View v){    		
    		zk.worteAendern("TEST");
    	}
    };

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    
}
```


```
package com.example.test;


import android.app.Activity;
import android.widget.TextView;
public class ZweiteKlasse   {
	Activity act;
	public void setAct(Activity temp){
		act=temp;
	}
    public void worteAendern (String neu){ 
    	TextView meinText = (TextView) act.findViewById(R.id.meinText);
    	meinText.setText(neu);
       
    }
}
```


----------



## schlingel (31. Aug 2012)

Für was soll das gut sein?


----------



## Gast2 (3. Sep 2012)

Trolok hat gesagt.:


> Der gedanke ist MainActivity zu übergeben



Leider ohne Erfolg.


----------



## Trolok (3. Sep 2012)

frankmehlhop hat gesagt.:


> Leider ohne Erfolg.



Der Code den ich postete funktioniert, post mal deins.


----------



## SlaterB (3. Sep 2012)

@frankmehlhop
eine Zeile, das ist deine gesamte Reaktion auf zumindest zwei lange Posts?

nichts zur Klärung von 'R.id.meinText', funktioniert das etwa in der ersten Activity,
nichts zur Frage wozu zwei Activities, 
nichts zum Logging von Fehlermeldung

kein neuer eigener Code oder irgendwas?


----------



## Gast2 (3. Sep 2012)

SlaterB hat gesagt.:


> Problem mit setText und Platzhalter in strings.xml - Android Forum - AndroidPIT



schon bei der ersten Zeile 
	
	
	
	





```
Resources res = getResources();
```
 bekomme ich den selben Fehler. 



SlaterB hat gesagt.:


> weißt du welcher Text das sein müsste, falls korrekterweise irgendwo definiert aber für dich bekannt?
> setze dann direkt einen String "blahblah", immer noch Fehler?



Nun ja, ich muss ja erst mal angeben, welchen TextView ich will. Und zwar den TextView meinText aus der XML. Bevor ich den Inhalt davon ändere, muss ich den Aufruf starten und der verursacht schon den Fehler.



SlaterB hat gesagt.:


> darf man überhaupt Activity-Objekte einfach so selber erzeugen?
> überschreibe onCreate(), logge Aufruf, wird von niemanden aufgerufen, oder?



Aber für Android kenne ich gar keine andere Möglichkeit als mit extends Activity zu arbeiten. Testweise habe ich es in der ZweitenKlasse rausgeschmissen und da kann nicht mehr auf die zugehörigen XML's zugegriffen werden.

onCreate() in ZweiteKlasse wird NICHT aufgerufen.



SlaterB hat gesagt.:


> wer erzeugt MainActivity? dort geht vielleicht findViewById(), da korrekt eingebunden, in der zweiten losen Activity nicht



Die Frage wundert mich. Ich weiß nicht WER die MainActivity aufruft. Es ist die Startklasse in Android, so wie Main.java in Java (classic).
die Zeilen:
	
	
	
	





```
meinText = (TextView) findViewById(R.id.meinText);
meinText.setText(neu);
```
funktionieren übrigens in der MainActivity einwandfrei. Die XML's werden also gefunden.



SlaterB hat gesagt.:


> brauchst du eine zweite Activity? erstelle lieber leere einfache Klassen, übergib die erste für Framework-Aufrufe


Wie meinst Du das? Ich habe doch im Prinzip eine zweite leere Klasse erstellt (ZweiteKlasse.java). Steht da irgend etwas überflüssiges drin?




SlaterB hat gesagt.:


> kannst du ein try/catch um "zk = new ZweiteKlasse();" setzen, die Exception abfangen und auf irgendeine Weise die Information des hoffentlich vorhandenen StackTraces extrahieren/ loggen?


Na nu (sächsisch für "na klar"): java.lang.NullPointerException

*Viel probiert und noch nicht weiter gekommen.* ???:L
Ich will doch einfach nur lernen, eine zweite Klasse nutzen zu können. 
In Java (classic) konnte ich das schon.


----------



## Gast2 (3. Sep 2012)

SlaterB hat gesagt.:


> @frankmehlhop
> eine Zeile, das ist deine gesamte Reaktion auf zumindest zwei lange Posts?



Immer langsam,
so eine ausführliche Hilfe von Dir läßt sich nicht in einer Minute beantworten.


----------



## schlingel (3. Sep 2012)

> Ich will doch einfach nur lernen, eine zweite Klasse nutzen zu können.



Habe ich das richtig verstanden? Du willst eine zweite Activity starten und dann ein Resultat von ihr zurückbekommen?

Wenn das zutrifft, machst du das falsch. Du müsstest hier startActivityForResult aufrufen und zwar mit einem Intent für eine ganz normale Activity. Diese muss nicht in den Code der MainActivity gepackt werden.

In der MainActivity baust du dann einfach die Methode onActivityResult ein und kannst das dann auch verarbeiten.

*Odeeer* willst du einfach nur eine normale Klasse verwenden? Die musst du nicht in's Manifest packen sondern einfach nur importieren.


----------



## SlaterB (3. Sep 2012)

frankmehlhop hat gesagt.:


> Die Frage wundert mich. Ich weiß nicht WER die MainActivity aufruft. Es ist die Startklasse in Android, so wie Main.java in Java (classic).


das ist schon die gewünschte Erkenntnis, MainActivity ist kompliziert in ein Framework eingebunden,
welches von dieser Activity weiß,
du kannst nicht erwarten dass eine selber erstellte zweite Activity auch in allen Umfang funktioniert,
findViewById() macht, XMLs kennt usw.

aber davon ist ja inzwischen schon einiger Abstand genommen



> die Zeilen:
> 
> 
> 
> ...


und in einer anderen Klasse sollen genau diese Aufrufe, genau bei diesem Activitiy-Objekt (welches ja übergeben wird) aufgerufen nicht mehr gehen? zum in etwa gleichen Zeitpunkt?
das erscheint wenig realistisch, widerspricht den Java-Grundsätzen

deswegen ist "Leider ohne Erfolg." zum Trolok-Code komisch, 
verwendest du ihn genau so, welche Fehlermeldung, welche Code-Abweichung? usw.



> Na nu (sächsisch für "na klar"): java.lang.NullPointerException


das ist nicht die vollständige Info, die man haben könnte,
mit StackTrace erkennt man, in welche Methode in welcher Tiefe der Fehler liegt,
ist 'R.id' schon null, scheitert findViewById() relativ hoch oder niedrig usw.


```
Exception in thread "main" java.lang.NullPointerException
	at test.Test.methode(Test.java:21)
	at test.Test.<init>(Test.java:16)
	at test.Test.main(Test.java:11)
```
bietet mehr


----------



## Gast2 (3. Sep 2012)

Nun ja,
ich werde es für mich erst einmal so handhaben, dass ich Oberflächenrelevante Einstellungen in der MainActivity mache und nur Algorithmen u.Ä. auslagere. Das funktioniert problemlos.

Interessant wird das Thema spätestens wieder, wenn ich eine zweite Oberfläche anlege und dazu eine Klasse schreiben will / muss. Aber darum kümmere ich mich, wenn es so weit ist.

Danke für Euer aller Hilfe.
Noch ein kurzes Wort zum Schlingel: Das was Du mir geschrieben hast überstieg mein Niveau um mindestens 2 Level und das ist mindestens 1 Level zu viel. 

Frank


----------

