我有一个 Android 项目,由两个模块组成:“SDK”和“演示 Android 应用程序”。
目前,SDK 位于 /path/to/work/dir/sdk
中,应用程序位于 /path/to/work/dir/demo-app
中。开发人员在 Android Studio 中打开“/path/to/work/dir/demo-app”,可以同时查看和编辑两个模块的源代码。
我们有另一个 Android 应用程序,但其中包含作为已编译的 .aar 文件的 SDK,并且它无法查看或编辑“实时”源代码,只能查看或编辑反编译/调试符号的源代码,如果这有意义的话?
TL;DR 我想将 SDK 制作成一个纯 Java 库,以便它可以在非 Android 应用程序中使用,但仍然可以在 Android Studio 中完全编辑它演示应用程序“项目”的。我该怎么做?
详细信息
SDK详细信息
SDK 的工作是控制套接字另一端的一些硬件设备。它几乎完全是纯 Java,但有一些 Android 库的附带用途:
android.util.Log
、类中关联的TAG
常量以及用于禁用日志消息的运行时检查 (BuildConfig.DEBUG
)静态分析注释:
@Nullable
、@AnyThread
、@NonNull
、 @Nullable、@UiThread、@WorkerThread、@IntRange、@Size
、@SuppressLint
偶然使用缺少 Java stdlib 的库:
android.text.TextUtils
android.support.v4.util.Pair
它的测试套件都是“测试”。有一个无用的“androidTest”,可以将其删除。
Gradle 构建环境仍然是针对 Android 量身定制的 目录结构。即存储库目录如下所示:
/path/to/work/dir/sdk ├───.git │ └───...etc... ├───.gradle │ └───...etc... ├───app │ ├───app.iml │ ├───Mobile-SDK-Android.iml │ ├───proguard-rules.pro │ ├───build │ │ ├───generated │ │ │ └───...etc... │ │ ├───intermediates │ │ │ └───...etc... │ │ ├───outputs │ │ │ └───aar │ │ └───tmp │ │ ├─... │ ├───docs │ ├───libs │ └───src │ ├───androidTest │ │ └───java │ │ └───com │ │ └───...etc... │ ├───main │ │ ├───java │ │ │ └───com │ │ │ └───...etc... │ │ └───res │ │ └───values │ │ └───strings.xml │ └───test │ ├───java │ │ └───com │ │ └───...etc... │ └───resources ├───build │ ├───android-profile │ ├───generated │ └───intermediates └───gradle └───wrapper
和
build.gradle
如下:apply plugin: 'com.android.library' android { compileSdkVersion 25 buildToolsVersion '25.0.2' defaultConfig { minSdkVersion 16 targetSdkVersion 25 versionCode 1 versionName "0.7" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { debuggable false } } packagingOptions { exclude 'META-INF/LICENSE' exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/NOTICE' exclude 'META-INF/ASL2.0' } productFlavors { } publishNonDefault true } repositories { ... etc ... } dependencies { // For @Nullable/@NonNull compile 'com.android.support:support-annotations:25.3.1' testCompile 'junit:junit:4.12' ... etc ... }
“发布版本”说明包含以下内容:
$ ./gradlew check $ ./gradlew assembleRelease # Then copies and packages app/build/outputs/aar/app-release.aar
应用程序详细信息
“Android 应用程序”模块似乎是普通的 Android 应用程序,例如它使用 Activity 类和 Android 库,Android Studio 可以很好地将其部署到设备上。有这些 gradle 脚本:
/path/to/work/dir/demo-app/build.gradle (Project: Demo-App)
/path/to/work/dir/demo-app/settings.gradle (Project Settings)
/path/to/work/dir/demo-app/app/build.gradle (Module: app)
settings.gradle
完整内容:
include ':app', ':Mobile-SDK-Android'
project(':Mobile-SDK-Android').projectDir = new File('/path/to/work/dir/sdk/app')
build.gradle
不包含任何我能看到的相关内容?
app/build.gradle
包含这些相关位:
apply plugin: 'com.android.application'
android {
... etc
}
dependencies {
compile project(path: ':Mobile-SDK-Android', configuration: 'debug')
... etc
}
需要更改吗?
将 SDK 转换为“正常”且惯用的 Java 库的适当步骤顺序是什么?
例如:
- 将
android.util.Log
的所有使用转换为使用例如SLF4J
- 将所有注释转换为 ???
- 重新实现或使用
TextUtils
和Pair
的替代方案? - 对 gradle 脚本施展一些魔法
- 因此输出是 .jar 而不是 .aar
- 并且不名为 app-release.aar
- 是否仍然可以拥有像
minSdkVersion
这样的东西? - 这个 jar 文件是否有可能具有“android 风格”,以防我们将来需要将 Android 特定代码放入 SDK 中?
- 因此输出是 .jar 而不是 .aar
- 是否可以重组 SDK 的目录以删除“app”目录?
- ???
名词利润
最佳答案
Android 是一个庞大的 API,并且有很多替代方案。因此,我想澄清的是,更改库没有固定的规则。大部分代码需要从头开始重写。大量的代码基本上是“无用的”。 Log.x,用于打印的类消失了。这可以由库、Logger
或仅 System.out
替换。
至于注释,这取决于来源。
库注释通常适用于桌面和 Android,例如 Lombok。 Android 特定注释 (@TargetApi
) 消失了。无法使用 minSdk
(因为它不是 Java 中 API 的一部分)。我希望你在这里明白了。
如果您没有:您不能将 Java 库转换为 Android 或反之亦然。为给定平台编写的代码太多,而在其他平台上则没有。
解决方案是从头开始创建它。与桌面 Java 相比,Android 框架运行一个完全不同的系统,导致很多代码无法使用。 Activity 系统会删除任何该代码,然后就有 .xml 资源。如果您为字符串资源创建 .xml 解析器,则可以继续使用 Strings.xml。创建处理器需要太多的布局。单位dp
也消失了。
所以回答标题:
What steps need to be performed to convert an Android Java module into a normal Java one?
一旦你运行了库(或一个想法),你就需要重写它。除了桌面Java(也就是你所说的普通java)语言不同之外,它还有不同的系统。默认情况下没有 .xml 资源(JavaFX 使用 .fxml 进行布局,但 JavaFX 是一个完全不同的系统)。您需要自己解析任何文件并处理字符串的区域设置。布局、JavaFX。
What is an appropriate sequence of steps to convert the SDK into a "normal" and idiomatic Java library?
像任何其他项目一样,从核心开始。创建主类,然后展开。
注释
您提供了注释列表。
@Nullable
工作正常
@AnyThread
安卓
@NonNull
工作正常
@UiThread
安卓
@WorkerThread
安卓
@IntRange
安卓
@Size
@SuppressLint
桌面 Java 中不存在 SuppressLint。 They have SuppressWarnings虽然(不相关的问题,但它解释了注释是什么)
如果还不清楚,上面标记为 Android
的注释无法使用桌面 Java,这意味着它们是为 Android 编写的
So the output is .jar instead of .aar and isn't called app-release.aar
当您使用 Java 库时,它最终会成为 .jar。
Is it still possible to have things like minSdkVersion ?
没有
Is it possible to have an 'android flavour' of this jar file, incase we need to put android specific code in the SDK in future?
没有
至于下达命令来解决问题,那是不可能下达的。正如我希望我现在已经明确表示的那样,您不能仅在 Java 和 Android 之间转换代码。差异太多,意味着你必须从头开始。因此,如何设置该列表取决于您。但你或多或少需要重写整个事情。有些地方可以复制粘贴,但这样的地方很少。
我已将 Android 项目转换为 Java(从 native Android 移至 LibGDX),并且必须重写整个代码。只有一些段是可复制粘贴的,主要是构造函数和一些字段、基本操作等。没有什么可以复制粘贴基本Java的方式,问题是任何项目都没有那么多基本Java(如构造函数、字段、数学运算等)
关于java - 将 Android Java 模块转换为普通 Java 模块需要执行哪些步骤?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46056343/