2013-07-03 12 views
13

Postaram naprawdę trudno przekształcić jednego kompleksowego pytanie:Kontekst Androida bez aktywności? I inne programowanie bez czynności?

Piszę metodę, aby uzyskać ciąg, który zawiera nazwę miasta androida urządzenia, jak określono w LocationManager i getLastKnownLocation() i wszystko, .

Potem zdałem sobie sprawę, że muszę zrobić to samo jeszcze raz w innej czynności, więc dlaczego nie zrobić zupełnie oddzielnej klasy (LocationFinder), którą mógłbym użyć w moim programie, zamiast pisać wszędzie duplikat kodu?

Ale mam problemy, które mnie dezorientują. Na przykład, jeśli zrobię tę klasę (LocationFinder), czy powinna ona rozszerzyć działanie, nawet jeśli nigdy nie jest faktycznie wizualizowana? Cała ta klasa mogłaby mieć różne atrybuty, takie jak getLastKnownCity() lub getCurrentCity() i zwracać ciągi. Sądziłem, że nie trzeba będzie rozszerzać klasy aktywności, ponieważ tak naprawdę nie jest to działanie.

Ale co Kontekst mogę użyć do:

Geocoder geocoder = new Geocoder(Context context, Locale locale) 

?

To spowodowało, że zakładam, że MUSI to być działalność. Więc przedłużone działanie, a zastąpił konstruktora z

@Override 
protected void onCreate(.............. 

ale z jakiegoś powodu, że nigdy nie kończy się nazywa zaczyna, nawet kiedy kładę

String city = new LocationFinder().getLastKnownCity(); 

Moja pierwsza linia LocationFinder „s onCreate() jest

System.out.println("HEY!") 

i nigdy do tego nie dojdzie. Dostaję zerowy wskaźnik na android.internal.os.LoggingPrintStream.println() i inne rzeczy.

Dodatkowo, istnieje kilka stałych systemowych, które pochodzą z klas aktywności. Na przykład, muszę uzyskać numer LOCATION_SERVICE, który jest ciągiem znaków, którego nie mogę uzyskać bez rozszerzenia działania. Pewnie, mógłbym oszukać i po prostu wstawić literalną strunę, ale to źle działa.

Odpowiedz

10

Podczas tworzenia klasy można mieć konstruktora, który przyjmuje kontekst i przypisuje mu lokalny obiekt Context w klasie.

public class LocationFinder { 
    private Context myContext; 
    private Geocoder geocoder; 

    public LocationFinder(Context context) 
    { 
     myContext = context; 
     geocoder = new Geocoder(myContext); 
    } 

} 

A potem przy próbie dostępu do tej klasy, upewnij się zainicjować to lubią:

public class TestActivity extends Activity { 
    protected void onCreate(Bundle savedInstanceState) 
    { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.main); 
      LocationFinder lFinder = new LocationFinder(getApplication()); 
    } 
} 

Oczywiście, nie można uzyskać dostępu do kontekstu z każdej klasy, która będzie uruchomiona. Tak więc wystarczające może być odniesienie do widoku.

LocationFinder lFinder = new LocationFinder(anyView.getApplication()); 
+0

Dzięki! Zastanawiasz się, czy nie byłoby użyteczne użycie getApplicationContext() zamiast przekazywania kontekstu działania, tak jak polecasz? Nadal nie rozumiem kontekstów, mimo że wciąż czytam ich definicję ... Po prostu nie rozumiem, co powoduje, że Kontekst działania różni się od innego. – andy

+0

To prawda, odniesienie do kontekstu zostanie zniszczone, gdy zostanie wywołana funkcja onDestroy. – frogmanx

15

EDYCJA: Jeśli to możliwe, użyj odpowiedzi frogmanx. To powinno być używane tylko wtedy, gdy jego odpowiedź nie jest możliwa. (singletony, które potrzebują kontekstu bezpośrednio od bat.)

Wygląda na to, że powinieneś przedłużyć Application, a nie Aktywność.

Dokonaj coś Zastosowanie takiego:

public class MyApplication extends Application { 
    private static MyApplication instance; 

    public MyApplication() { 
     instance = this; 
    } 

    public static MyApplication getInstance() { 
     return instance; 
    } 

następnie dodać ten atrybut do tagu aplikacji w manifeście:

<application android:name=".your.package.MyApplication" ... /> 

Po tym wszystkim, że można dostać kontekst wywołując MyApplication.getInstance() od gdziekolwiek.

+0

Niezupełnie moje pytanie, ale Twoja odpowiedź mi pomogła! Dzięki –

+2

Niesamowite +1 dokładnie mój przypadek, singleton, który potrzebuje kontekstu. Zajęło mi wieki, aby to znaleźć! – Juicy

2
should it extend Activity, even though it is never actually visualized? 

nr Z Android docs

działalności jest pojedynczym, koncentruje się coś, co użytkownik może zrobić. Prawie wszystkie działania interakcji z użytkownikiem, więc klasa aktywny trwa opieką tworząc okno dla Ciebie, w którym można umieścić swój UI z setContentView (Widok)

myśleć o działalność jako ekranu użytkownik widzi.

Ale co Kontekst mogę używać do geocoder geokodera = new geocoder (kontekstowego Context, Locale regionu)

Klasa Activity rozciąga Context, podobnie jak wiele innych klas w tym Application. Kontekst zapewnia dostęp do zasobów powiązanych z klasą, która rozszerza kontekst.

Potrzebny jest i powinien być używany tylko kontekst działania, gdy jest wymagany do interakcji z zasobami powiązanymi z tym działaniem i metodami wdrożonymi przez konkretną klasę aktywności. Kiedy potrzebujesz dostępu do tego kontekstu, przekazujesz go do klasy, która potrzebuje dostępu, zwykle jako argument do konstruktora tej klasy.

Jeśli kiedykolwiek zdasz kontekst działania poza rozszerzeniem działania, upewnij się, że zakres i cykl życia odwołania jest mniejszy lub równy rozszerzonemu działaniu, w przeciwnym razie wyciekniesz dużej ilości pamięci, jeśli aktywność jest zniszczone, ponieważ śmieciarz nie może uwolnić pamięci, ponieważ istnieje odniesienie do kontekstu.

Jeśli spojrzysz na konstruktor Geocodera, zauważysz, że jako argument bierze on Kontekst. Jest to wskazówka, dlaczego kontekst jest potrzebne w opisie:

 Geocoder(Context context, Locale locale) 
Constructs a Geocoder whose responses will be localized for the given Locale. [1]: 

Powodem jest potrzebny kontekst jest uzyskanie dostępu do systemu informacji o lokalizacjach na pomoście i bieżącej lokalizacji systemu.

Tak w przykładzie, można po prostu przejść kontekst aplikacji do konstruktora, który można uzyskać odniesienie do z getApplicationContext()

Na przykład, muszę się dostać na LOCATION_SERVICE, która jest ciągiem znaków, które nie mogę uzyskać bez rozszerzania Aktywności

Możesz pobrać z kontekstu aplikacji.

+0

Dziękujemy! Zastanawiasz się, czy byłoby nierozsądnie używać getApplicationContext() jako mojego kontekstu w Geokodorze (Kontekstowy kontekst ...)? Inni zalecili przekazanie w kontekście działania, które tworzy tę nową klasę, i nie jestem pewien, który jest najlepszy sposób. Dzięki jeszcze raz. – andy

+0

Kluczem jest, czy potrzebujesz dostępu do swojego "działania" z "Geokodera"? Dobry projekt mówi nie. Jeśli chcesz przekazać wartości do swojej aktywności, użyj detektora. Zawsze możesz zdefiniować swój własny interfejs do wykonywania niestandardowych połączeń zwrotnych, np. zaktualizować 'TextView'. Nie ma nic "złego" w używaniu kontekstu aplikacji. Gwarantuje to, że jest to singleton i istnieje konsekwentnie dla cyklu życia aplikacji, więc pytanie jest lepiej zadane jako "dlaczego potrzebuję kontekstu działania"? – Simon

Powiązane problemy