Android, dostanie się z projektu dependency do App

0

Hej,
mam problem. Moja aplikacja korzysta z zewnętrznego projektu, podpiętego jako dependency. Chcę z tego projektu dostać się do Aplikacji, która posiada klasy do zarządzania bazą danych itp.
(średnio da się to obejść, bo projekt służy do otrzymywania notyfikacji i chciałbym je filtrować pod kątem już istniejących danych, które przyszły kiedyś).

Tak jak dostać się z App do Dependency jest łatwo, tak odwrotnie do App jako takiego nie mam dostępu. Wiem, że powinienem korzystać ze wstrzykiwania interfejsów, ale nie czuję się z nimi chyba tak komfortowo aby to zrobić...

Czy możecie podrzucić mi jakieś podstawy teoretyczne tego problemu, abym przynajmniej wiedział od której strony to ugryźć?

1

Bedzie ciezko tak jak chyba chcesz, bo jak dodasz zaleznosc z liba do app to masz cykliczne zaleznosci a to nigdy nie jest dobre. Pomysl: zeby skompilowac aplikacje potrzebujesz biblioteke, ale zeby skompilowac biblioteke potrzebujesz aplikacje? Nawet jak przeczytasz druga polowe tego zdania to wyjdzie ze to bez sensu - nigdy biblioteka nie moze wymagac aplikacji do kompilacji. Biblioteka nie moze wiedziec jak i dokad, w jakim formacie chcesz zapisac dane, i powinna byc na tyle elastyczna zeby pozwalac na dowolnosc. Jak? Pokaze nizej.

Jesli biblioteka nie upublicznia zadnych interfejsow ktore ty mozesz w twojej aplikacji implementowac i jakos zarejestrowac w klasach liba, to jedynym sposobem bedzie modyfikacja kodu liba. Albo dodasz do niego odpowiednie interfejsy, on bedzie wolal metody z tych interfejsow, a aplikacja dostarczy ich implementacje (wariant standardowy) lub skopiujesz kod liba do app (tak ze bedziesz mial tylko jeden modul) i tam na zywca mozesz robic co chcesz (wariant *ujowy).

Pokaze ci w prosty sposob o co chodzi z tymi interfejsami, to jest pseudokod ale powinienes zrozumiec:

lib - zbiera powiadomienia z jakichstam zrodel i jak przyjdzie nowe to wywoluje jakas metode gdzie je przekazuje

interface NotificationReceivedListener { void notificationReceived(Notification n); }

class Library {
// a lot of code
public void addDataGenerationListener(DataGeneratedListener l) {...}
}


app - chce wiedziec kiedy przychodza nowe powiadomienia, filtrowac je i zapisac do bazy danych
<code lang=java>
class PersistingNotificationReceivedListener implements NotificationReceivedListener {
    public void notificationReceived(Notification n) {
        if (shouldSaveNotification(n)) {
            save(n);
        }
    }
    private boolean shouldSaveNotification(Notification n) { ... }
    private void save(Notification n) { SQLite.save(n); }
}

To jest typowa struktura wzorca observer - biblioteka definiuje interfejs dla obserwatora, aplikacja dostarcza jego implementacje i robi w nim co jej sie podoba. Praktycznie kazda aplikacja ma jakos gdzies ten wzorzec zaimplementowany - a to jakies callbacki/listenery na klikniecia guzika, a to callback ze telefon zostal odwrocony do portrait, a to callback ze jest malo pamieci (przyklad z iOS)... To jest tez absolutna podstawa, musisz to umiec i rozumiec bo inaczej lipa.

Ale przeciez juz to umiesz - Button.setOnClickListener(new OnClickListener() { ... }); na pewno widziales i pisales? Przez analogie:

lib ktorego uzywasz to API androida
NotificationReceivedListener to OnClickListener z androida
twoja implementacja ktora costam gdziestam zapisuje to tak jakby twoja implementacja zdarzenia klikniecia
Notification to tak jakby TouchEvent z Androida

Mam nadzieje ze przez ta analogie bedzie latwiej zrozumiec, i rowniez dojdziesz do wniosku, ze bez sensu jest oczekiwac zeby biblioteka uzywala jakichs klas aplikacji do zapisywania czegos.

Mozesz powiedziec jaka biblioteke uzywasz, co chcesz zrobic, ktos moze tam zajrzy i podpowie czy sie da i co masz zaimplementowac i gdzie zarejestrowac.

0

Pozwolę sobie doprecyzować, bo mam wrażenie że mówimy trochę o innych rzeczach.

Więc tak, mamy projekt Dependency. Zajmuje się on w dużym skrócie obsługiwaniem GCMa. Jedną z metod jest metoda zajmująca się Tworzeniem notyfikacji i wypuszczaniem jej na pasek stanu (składanie treści, ikonki itp).
Jest jednak taki przypadek użycia, gdzie przychodząca notyfikacja jest zbędna, bo pojawiła się wcześniej, innym kanałem. W idealnym świecie, chciałbym zrobić to tak

Dependency dostało notyfikację z GCMa -> Porównaj intent z istniejącymi danymi wewnątrz bazy danych -> Jeśli nie istnieje, wypuść true, uruchom metodę showNotification();

No ale problem jest, jak możesz się domyślić w punkcie drugim. Nie mogę odnieść się do DB, bo implementacja tej znajduje się we właściwej Aplikacji.
Własnie, w temacie bazy danych. Korzystam z biblioteki GreenDAO. W gruncie rzeczy jest to taki translator SQLek na obiekty. Jej obsługa odbywa się za pomocą klasy Menadżera, która jest singletonem. Więc jak chcę dodać coś do Db, to wygląda to tak: Manager.INSTANCE.addToDB(obj); i heja.

Rozumiesz?

0

Mysle ze rozmawiamy dokladnie o tym samym. Dependency musi udostepnic interfejs Filter czy cos, ktory ma metoda ktora zwraca boolean dla danego owiadomienia. Aplikacja implementuje ten interfejs na podstawie wlasnej bazy dancych, i jesli nie bylo jeszcze takiego, to moze zapisac (chyba ze robisz to juz gdzie indziej, w sumie filter nie jest dobrym miejscem do zapisywania) i zwraca np. true, a jesli byl juz wczesniej to zwraca false. Koniec.

1 użytkowników online, w tym zalogowanych: 0, gości: 1