简体   繁体   English

如何从导入它的应用程序配置 Android 库?

[英]How to configure Android library from an app that imports it?

I'm kinda new to Android development so my question might be weird or not even possible.我对 Android 开发有点陌生,所以我的问题可能很奇怪,甚至不可能。 I wouldn't know!我不会知道!

Anyway, I'm building multiple apps that will have a lot of shared elements, so I decided to build a library with those components and use it in all of the apps, rather than stupid copying and pasting code.无论如何,我正在构建多个包含许多共享元素的应用程序,因此我决定使用这些组件构建一个库并在所有应用程序中使用它,而不是愚蠢的复制和粘贴代码。 For example, the library handles the welcome screen and login/signup flow activities, among other things.例如,库处理欢迎屏幕和登录/注册流程活动等。 So here are the problems this approach might cause:所以这里是这种方法可能导致的问题:

  1. While the behavior is the same across the apps, but the logo that I show at the welcome screen is different.虽然跨应用程序的行为是相同的,但我在欢迎屏幕上显示的徽标是不同的。 Right now I populate it with an image resource from the library resources (R class) which will be the same for all apps and is obviously not correct.现在我用库资源(R 类)中的图像资源填充它,这对于所有应用程序都是相同的,显然是不正确的。
  2. The login/signup process is based on Firebase, which will require the app to have a key to be able to use them.登录/注册过程基于 Firebase,这将要求应用程序拥有密钥才能使用它们。 Right now I also populate it with a dummy string resource from the library resources.现在我还使用库资源中的虚拟字符串资源填充它。

So my question really boils down to 3 parts:所以我的问题实际上可以归结为 3 个部分:

  1. Is there anyway I could pass this info from the app to the library?无论如何我可以将这些信息从应用程序传递到图书馆吗? can I somehow modify the R class of the library?我可以以某种方式修改库的 R 类吗? Or can I use the app's R class from the library?或者我可以使用库中应用程序的 R 类吗? I can also call this part of the library as a function passing the parameters I need.我也可以将库的这一部分称为传递我需要的参数的函数。 But the first solution looks maybe more clean to me?但是第一个解决方案对我来说看起来可能更干净?
  2. Whatever the answer to Q1 is.无论 Q1 的答案是什么。 Where would I do this and how?我会在哪里做这个以及如何做? The library has the welcome activity itself which is supposed to be the first activity in the app.图书馆有欢迎活动本身,它应该是应用程序中的第一个活动。 How and where do I do this once the app starts and before the first activity starts?应用程序启动后和第一个活动开始之前,我应该如何以及在何处执行此操作?
  3. If what I'm doing is wrong or impossible, is there any other way to achieve it?如果我正在做的事情是错误的或不可能的,还有其他方法可以实现吗?
  1. Is there anyway I could pass this info from the app to the library?无论如何我可以将这些信息从应用程序传递到图书馆吗? can I somehow modify the R class of the library?我可以以某种方式修改库的 R 类吗? Or can I use the app's R class from the library?或者我可以使用库中应用程序的 R 类吗? I can also call this part of the library as a function passing the parameters I need.我也可以将库的这一部分称为传递我需要的参数的函数。 But the first solution looks maybe more clean to me?但是第一个解决方案对我来说看起来可能更干净?

You don't need to modify the R class because you can override the resource file by creating a file with the same name.您不需要修改 R 类,因为您可以通过创建同名文件来覆盖资源文件。 But it's not a clean solution because you constantly need to ensure your project and library resources name are the same.但这不是一个干净的解决方案,因为您经常需要确保您的项目和库资源名称相同。

  1. Whatever the answer to Q1 is.无论 Q1 的答案是什么。 Where would I do this and how?我会在哪里做这个以及如何做? The library has the welcome activity itself which is supposed to be the first activity in the app.图书馆有欢迎活动本身,它应该是应用程序中的第一个活动。 How and where do I do this once the app starts and before the first activity starts?应用程序启动后和第一个活动开始之前,我应该如何以及在何处执行此操作?

Instead of overriding the resources name, you're better to modify your library to receive a configuration as a contract to use the library.与其覆盖资源名称,不如修改您的库以接收配置作为使用库的合同。 Here the sample:这里的示例:

First , create the class for holding the configuration:首先,创建用于保存配置的类:

public class Configuration {
  private int welcomeImageDrawableId;
  private int logoDrawableId;

  // constructor
  public Configuration(int welcomeImageDrawableId, int logoDrawableId) {
    this.welcomeImageDrawableId = welcomeImageDrawableId;
    this.logoDrawableId = logoDrawableId;
  }

  // setter and getter.
  public int getLogoDrawableId() {
    return logoDrawableId;
  }
}

Second , use the configuration class for the library by creating a Singleton class which will be used internally by the library:其次,通过创建一个将由库内部使用的单例类来使用库的配置类:

public class MyLibrary {
    private static MyLibrary myLibrary;
    private Configuration configuration;

    private MyLibrary(){}
    private MyLibrary(Configuration configuration) {
      this.configuration = configuration;
    }

    public static MyLibrary getInstance() {
        if(myLibrary == null) {
            throw new RuntimeException("Need call createInstanceWith method first!!");
        }
        return myLibrary;
    }

    public static MyLibrary createInstanceWith(Configuration configuration) {
        if(myLibrary == null) {
            synchronized(MyLibrary.class) {
                if (myLibrary == null) {
                  myLibrary = new MyLibrary(configuration);
                }
            }
        }
        return test;
    }

    public Configuration getConfiguration() {
      return configuration;
    }
}

Third , use the configuration class in your library via the singleton class.第三,通过单例类使用库中的配置类。 something like this:像这样:

// assume imvLogo is an existing ImageView
Configuration configuration = MyLibrary.getInstance().getConfiguration();
imvLogo.setImageResource(configuration.getLogoDrawableId());

Last , register the contract when the library is used with:最后,在使用库时注册合约:

Configuration configuration = new Configuration(R.drawable.welcome, R.drawable.logo);
MyLibrary.createInstanceWith(configuration);

Note: all the code isn't tested yet, error is to be expected.注意:所有代码尚未测试,错误是可以预料的。

Apart from the solution above, I also found another way to achieve this whole thing without having to initialize libraries and whatnot.除了上面的解决方案,我还找到了另一种方法来实现这一切,而无需初始化库和诸如此类的东西。 I think the correct way to do this is to use productFlavors in the library.我认为正确的方法是在库中使用 productFlavors 。 This allows the library to share the one main set of source code, one main set of resources, then an extra set of resource per app/flavors.这允许库共享一组主要源代码、一组主要资源,然后是每个应用程序/风格的一组额外资源。 This is very sufficient for my purposes.这对我的目的来说已经足够了。

For more info about build variants and flavors: https://developer.android.com/studio/build/build-variants有关构建变体和风格的更多信息: https : //developer.android.com/studio/build/build-variants

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM