【问题标题】:Intermodule (library projects) communication in android applicationandroid应用程序中的模块间(库项目)通信
【发布时间】:2016-06-13 21:58:24
【问题描述】:

在下图中,我有 3 个模块(作为 android 库)扩展了基本的“通用组件模块”,所有这 3 个模块都将添加到单个 android 应用程序中。 3个模块都是独立的模块,但是作为一个应用程序,它需要共享一些数据,启动其他模块,并且需要更多的相互通信。

那么谁能告诉我如何在这种架构中实现“数据共享层”和“导航控制器”?

示例:模块 1 -> 登录、模块 2 -> 配置文件管理等,根据应用程序需要,可能有“n”个模块。

【问题讨论】:

  • 朋友们请不要在没有理由的情况下投反对票。任何建议也将不胜感激
  • 对于数据共享,您可以使用内容提供商
  • @ankitaggarwal,我们可以寻找内容提供者,以防我们的应用程序暴露给其他应用程序,但这里是模块到模块。
  • @Dinash 为什么不在主项目 gradle 中包含所有模块?您还可以在另一个模块的 gradle 中包含特定模块。这将允许每个模块利用来自其他模块的特定类
  • @Dinash 在模块之间共享数据的一个例子是this

标签: android module navigation library-project data-sharing


【解决方案1】:

您正在寻找的基本上是关于如何与其他类进行通信的干净方法。它们是否在不同的模块中并没有真正的区别。

以下示例描述了LoginActivity 如何导航到某些配置文件活动。 这只是一个基本示例,需要根据您的实际需要和打算进行改进!

  1. 定义您的接口

编写您需要的接口。您的登录名应该能够打开个人资料页面吗?这听起来像是需要LoginNavigator

interface LoginNavigator {
    void showProfile();
}

在您的共享组件中包含这些接口。没有定义接口是不可能的。你可以让它们更抽象或更细粒度,这完全取决于你。

  1. 声明你的依赖关系

还记得您的登录需要LoginNavigator吗?真正的问题是如何将它提供给你的班级。你应该看看依赖注入,因为有一些框架喜欢(可以)使这更容易。现在,我们为一个通用组件定义一个接口,以便我们可以检索我们需要的依赖项。

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 不允许实现您自己的构造函数——这就是使用应用程序类的原因。

【讨论】:

  • 感谢您的详细回答。它是否更具可扩展性,因为在实际应用程序中,我们将有更多模块和大量数据要共享以及模块之间的大量通信
  • @Dinash 拥有干净且记录在案的界面在大多数情况下都可以很好地扩展
  • 关于如何分离网络或数据库的任何想法,因为假设您使用改造+gson+okhttp 跨模块使用相同的对象很好,一种方法是将它们作为依赖项添加到每个项目。分析、数据库、实用程序也是如此?
  • @DavidMedenjak 非常有帮助的答案.. 对此有什么想法吗? stackoverflow.com/q/61359745/4806942
【解决方案2】:

我发现使用Local Broadcast 的解决方案在Application Class 中实现,并在Local Broadcast 上发送事件,在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()
    }
} 

当您在这样的应用程序中发送事件时

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

因为您的模块不需要获取 Application 的实例或任何接口。

【讨论】:

    猜你喜欢
    • 2019-08-03
    • 2014-12-28
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多