处理库项目中的依赖关系

Handling dependencies in Library projects

我有一个Android open source library project in which I have been using a separate library for logging(也是我开发的)。

日志库不是那么重要,但它使开发和调试更容易(对我和主库的用户来说)。 我正在使用 gradle(和 Jitpack)来使用这两个库。现在日志库实际上在清单中有一些额外的权限(用于将日志写入文件,主库不需要)。

现在一位用户要求我删除额外的权限。而且我不知道如何在不删除日志库(或更改日志库本身的功能)的情况下做到这一点。 我什至意识到很少有人可能根本不需要日志库,所以有没有办法让它成为可选的,比如如果用户没有在他们的 build.gradle 中包含日志库,它就不会得到我可以检测到并且不调用日志记录函数的导入?

我知道这听起来令人困惑,但我想知道如何分离这两个库。事实上,如果您也知道来自任何流行图书馆的任何此类示例,请告诉我。

是的,你可以通过一些聪明的技巧来做到这两点。

第 1 部分权限

关于清单权限。很简单,不要向日志库添加权限,而是在运行时检查它。像这样:

if (context.checkPermission(
              Manifest.permission.WRITE_EXTERNAL_STORAGE, 
              android.os.Process.myPid(),
              Process.myUid()) == PackageManager.PERMISSION_GRANTED) {
      carry on with your write to disk operation ...
}

然后在您的文档中写道,如果使用该库的开发人员想要进行本地日志记录,他们必须在清单上声明 WRITE_EXTERNAL_STORAGE。

第 2 部分。(不)导入库

我要在这里写的所有内容都是用心写的,100% 没有经过测试。可能(将)有一些错误需要您改正,但希望我能传达一个可靠的想法。

首先,在 NoobCameraFlash 库中,您将在 build.gradle 文件中使用 provided 而非 compile 定义 LumberJack。这将使编译器知道 LumberJack,因此编译可以通过,但不会将其包含在实际构建中。

然后在您的 NoobCameraFlash 库中创建一个 class 作为库功能的镜像。这意味着方法 d(String, String)e(String, String)

然后你在这个镜像中 class 你会像下面这样检查 lumberjack 是否真的可用。

private static boolean lumberJackAvailable = false;
private static boolean lumberJackTested = false;
private static boolean isLumberJackAvailable() {
   if(lumberJackTested) return lumberJackAvailable;
   lumberJackTested = true;
   try {
      if(Class.forName("") != null) {
          lumberJackAvailable = true;
      }
   } catch(Throwable e){
       // ClassNotFoundException, LinkageError, ExceptionInInitializerError
   }
   return lumberJackAvailable;
}

public static LumberJackMirror create() {
     // could also be a singleton
    if(isLumberJackAvailable() return new LumberJackMirror();
    else return null;
}

那当然要检查if(lumberJackMirror != null)。因此,正如您所见,这并不是最直接的做事方式。

另一种稍微简化这一点的方法是在不同的库中创建一个接口,镜像和实际的 LumberJack 实现并使用工厂可以 return 接口的空实现而不是必须一直进行空检查。

另外,在文档中包括,如果开发人员想要拥有日志记录功能,他们必须将其添加到 build.gradle。类似于 compile 'your_groud_id:lumberjack:version'

编辑

另一种常见的做法是在 NoobCameraFlash 初始化代码中明确说明。类似于:

  NoobCameraFlash.config()
       .setLogger(new LumberJack());

这样就迫使开发人员了解 LumberJack,而不是通过 Class 进行检查。但这意味着您需要某些版本的 LumberJack,而不仅仅是 static 方法。

end_edit

但希望仅删除权限就足够了,您不必执行此部分。2 =]

编码愉快。