# Auf innere (Thread)Klasse zugreifen, von anderer Klasse aus



## camou (18. Sep 2013)

Hi all,

ich bin manchmal noch ein wenig verwirrt bei den Java-Strukturen.

Also ich habe folgende Klassenstruktur: Die Main-Klasse, die eine innere Klasse (oder Unterklasse?)  namens Counter enthält und als Thread funktioniert.

Nun habe ich auch noch eine andere Klasse "ServiceTemplate". Die soll zur bestimmten Zeit, den Thread starten. 

Im Code sieht es ungefähr so aus:

```
public class MainAcitivity extends Activity {


class Counter extends Thread{
//Thread tut, was ein Thread so tut
}

protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main_acitivity);

//hier ist es mir (logischerweise) möglich den Thread normal zu starten
}


}

// neue Klasse

public class ServiceTemplate extends Service {

  public void onStart(Intent intent, int startid) {

Counter c = new Counter(); //Fehlermeldung


}

}
```
Wie kann ich nun von ServiceTemplate auf Counter zugreifen?
Ich habe Counter counter = new Counter(); ausprobiert, aber da meckert der Compiler.


*Fehlermeldung:*
"No enclosing instance of type MainAcitivity is accessible. Must qualify the allocation with an enclosing instance of type MainAcitivity (e.g. x.new A() where x is an instance of MainAcitivity)."

Allem Anschein nach, soll ich erst über die MainAcitivity gehen. Aber wie genau? Und warum nicht direkt? Wie gesagt, manchmal blicke ich sowas noch nicht so ganz... bei Java bzw. OO allgemein.

Ich würde mich über ein wenig Hilfe oder Stichpunkte freuen. 

Gruß


----------



## geqoo (18. Sep 2013)

Man sollte keine nicht-statischen inneren Klassen von einer Activity instanzieren. 
Wenn du die innere Klasse instanzierst, dann musst du zuerst die äußere Klasse (also deine Activity) instanzieren. Activities sind aber nur zum Laufen gedacht, und sollen nicht über new instanziert werden.

Es können also nur statische innere Klassen ohne den äußeren Kontext instanziert werden 
Daher: Mache deine Thread-Klasse static, dann sollte es gehen.


----------



## dzim (18. Sep 2013)

eine "public static" vor die Klassendefinition könnte helfen, *Aber:* In dem Fall wäre es sinnvoll, die Threadklasse gleich ordentlich aus der anderen zu entfernen.

Nur zur Info: Ich denke mal, du willst einen Service, der einen Counter startet, welcher wiederum in der GUI irgend etwas macht. Ohne deine Implemementierung zu kennen, denke ich aber, das die von dir hier aufgezeigte Architektur möglicherweise nicht funktionieren könnte (aber probiere es von mir aus vorher).
Du solltest die Kommunikation zwischen Service und UI via Messanger abwickeln, bei der der Message Handler dann auch auf die UI zugreifen darf (sonst kann es zu InvalidThreadAccess kommen). von dem Handler (der darf auch gerne eine innere/anonyme Klasse der Aktivity sein) aus kannst du dann den Thread starten/stoppen/... (in dem Fall kann er auch weiterhin als innere Klasse in deiner Aktivity bleiben).
Entweder also registrierst du in allen UI Klassen, die es interessiert, einen Handler für die entsprechenden Nachrichten, oder aber (so mache ich es) du hast einen zentralen Handler, der die anderen UIs via langweiligem und selbstgeschriebenen EventHandler benachrichtigt (auch nicht so schön, aber fand ich zu dem Zeitpunkt am übersichtlichsten).

BTW: Ich seh gerade du kannst natürlich auch mit Broadcasts um dich werfen, dann brauchst du halt den entsprechenden BoradcastReceiver...

Bsp.: Android Service Tutorial (Lars Vogel präferiert anscheinend Broadcasts)
Service | Android Developers (Hier werden die Remote Message Services gezeigt)


----------



## camou (18. Sep 2013)

Hey, mit static hat es funktioniert. Danke 

An dzim: Das werde ich mir mal merken für (m)ein nächstes Projekt. Weil du hast mit deiner Vermutung ganz gut ins Schwarze getroffen. Aber so funktioniert es und iwo habe ich mal den Spruch gelesen: never change a running system... oder so? Also auch an dich dank


----------

