Межмодульное (библиотечные проекты) общение в приложении для Android

На приведенной ниже схеме у меня есть 3 модуля (в виде библиотеки Android), которые расширяют базовый "модуль общих компонентов", и все эти 3 модуля будут добавлены в одно приложение Android. Все 3 модуля являются независимыми модулями, но когда речь идет о приложении, требуется обмен некоторыми данными, запуск другого модуля и требует большего взаимодействия.

Так может ли кто-нибудь дать мне знать, как мы можем реализовать "Уровень обмена данными" и "Контроллер навигации" в такой архитектуре?

Пример: Module1 -> Login, Module2 -> Profile Management и т. Д., И может быть "n" количество модулей в зависимости от потребности приложения.

введите описание изображения здесь

2 ответа

То, что вы ищете, в основном чистый подход к тому, как общаться с другими классами. На самом деле нет разницы в том, находятся ли они в разных модулях.

Следующий пример описывает, как LoginActivity может перейти к некоторому профилю деятельности. Это просто базовый пример, который нужно улучшить с тем, что вам действительно нужно и вы собираетесь делать!

  1. Определите ваши интерфейсы

Напишите интерфейсы того, что вам нужно. Ваш логин должен быть в состоянии открыть страницу профиля? Ну, это звучит так, как будто это нужно LoginNavigator!

interface LoginNavigator {
    void showProfile();
}

Включите эти интерфейсы в ваши общие компоненты. В действительности нет возможности обойтись без определения интерфейсов. Вы можете сделать их более абстрактными или более мелкозернистыми, это полностью зависит от вас.

  1. Объявите свои зависимости

Помните, как ваш логин нуждается в LoginNavigator? Реальная проблема заключается в том, как предоставить его вашему классу. Вы должны взглянуть на внедрение зависимостей, так как есть фреймворки liks dagger-2, которые (могут) сделать это проще. На данный момент мы определяем интерфейс для общего компонента, чтобы мы могли получить необходимые нам зависимости.

interface NavigatorProvider {
    LoginNavigator provideNavigator();
}

Вы можете догадаться - этот метод используется для получения фактического LoginNavigator что вы можете использовать, чтобы получить реализацию этого интерфейса. Обычно вы просто объявляете эту зависимость в конструкторе, но поскольку android является чем-то особенным, вам нужно получить его откуда-то самостоятельно.

  1. Укажите ваши зависимости

Самый простой способ - это заставить ваше приложение реализовать этот интерфейс (или сохранить объект, который это делает).

class MyApp extends Application implements NavigatorProvider {

    LoginNavigator provideNavigator() {
        return new LoginNavigator() {
            void showProfile() {
                // just some sample code. You should probably not use an
                // anonymous class
                startActivity(new Intent(this, MyProfileActivity.class));
            }
        };
    }
}

Опять же, вы также можете вернуть объект, который реализует этот интерфейс. Это просто базовый образец.

  1. Используйте интерфейс. (И не заботятся о реализации)

Теперь внедрение зависимостей почти завершено. У нас есть интерфейс, в котором мы нуждаемся, у нас есть какой-то способ обеспечить зависимость, все, что осталось, это получить и использовать его.

class LoginActivity extends Activity {

    LoginNavigator mNavigator;

    void onCreate() {
        // get the dependency
        mNavigator = ((NavigatorProvider) getApplicationContext()).provideNavigator();

        // use it where needed. (again, just sample code)
        findShowProfileView().setOnClickListener(new OnClickListener() {
            void onClick(View view) {
                mNavigator.showProfile();
            }
        });
    }
}

Теперь зависимость предоставлена ​​и готова к использованию.


Этот пример показывает, как в основном использовать интерфейсы для разделения логики. Вам все еще понадобится некоторая точка входа, так как android не позволяет реализовывать ваши собственные конструкторы - вот почему используется класс приложения.

I found that solution using which is implemented in and send event on Local Broadcast which is received in Application Class.

      class AppApplication : Application() {
   
    override fun onCreate() {
        super.onCreate()
        registerBroadcast()
    }

    private fun startProfileActivity() {
        val intent = newIntent<MyProfileActivity>(this)
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        this.startActivity(intent)

    }

    private fun registerBroadcast() {
        LocalBroadcastManager.getInstance(this)
          .registerReceiver(broadCastReceiver,IntentFilter(BROADCAST_VIEW_PROFILE))
    }

    private fun unregisterBroadcast() {
        LocalBroadcastManager.getInstance(this)
            .unregisterReceiver(broadCastReceiver)
    }

    private val broadCastReceiver = object : BroadcastReceiver() {
        override fun onReceive(contxt: Context?, intent: Intent?) {
            when (intent?.action) {
                BROADCAST_VIEW_PROFILE -> {
                    startProfileActivity()
                }
            }
        }
    }

    override fun onTerminate() {
        super.onTerminate()
        unregisterBroadcast()
    }
} 

When you send the event in an Application like this

      private fun viewProfileEventSend() {
    // Send Broadcast for view profile to `APP`
    val intent = Intent(BROADCAST_VIEW_PROFILE)
    LocalBroadcastManager.getInstance(requireContext()).sendBroadcast(intent)
}

Because your module doesn't need to get the instance of Application or any interface.

Другие вопросы по тегам