目录
- 命名和目录约定
- 基本技巧
- 创建主 Android 项目
- 创建自定义 Android 库
- 从主 Android 项目中引用自定义 Android 库
- 创建 Java 库/模块
- 从主项目中引用 Java 库
- 请编辑
命名和目录约定
首先我们建立我们的命名和目录约定(如果您不喜欢以下内容,请建立您自己的约定)。
项目名称:PascalCase。
..\LibraryRefDemo\MyMainProject
..\LibraryRefDemo\Libraries\MyAndroidLibrary
..\LibraryRefDemo\Libraries\MyJavaLibrary
创建新项目向导> 创建 Android 项目:
Application Name: MyMainProject
Project Location: ..\MyMainProject
包名:小写。
// (package name for MyMainProject's root module: "app")
au.com.example.mymainproject
// (package name for MyAndroidLibrary's root module: "malmodule")
au.com.example.malmodule
// (package name for MyJavaLibrary' module where we placed our
// java code to be shared: "mjlmodule")
au.com.example.mjlmodule
模块名称:小写。以下之一:
app (MyMainProject's root module)
malmodule (MyAndroidLibrary's root module)
mjlmodule (The MyJavaLibrary's module where we placed our java code to be
shared. The MyJavaModule will also contain a root "app" module
for reasons of gradle integration)
基本技巧
以下基本技巧和后续的分步过程适用于 Android Studio 3.0.1 的 2018 年 3 月 10 日。
在完成分步过程之前,完成这项工作的基本技巧是:
- 使用 Android Studio 而不是其他 IDE(如 IDEA IntelliJ)来创建 MyMainProject、MyAndroidLibrary 和 MyJavaLibrary。一旦设置了基本框架,就可以从任何现有项目中复制代码和资源(例如使用 Windows 资源管理器)。
-
在主 Android 项目 ("MyMainProject") settings.gradle (Project Settings) 中,我们使用如下方式引用库模块(而不是库项目本身):
include ':app'
include ':malmodule'
// Despite the name "project" we actually need to reference the module directory
// of a project. It doesn't matter whether there is a trailing slash '/' or not.
project(':malmodule').projectDir =
new File(settingsDir, '../Libraries/MyAndroidLibrary/malmodule/')
include ':mjlmodule'
// Despite the name "project" we actually need to reference the module directory
// of a project. It doesn't matter whether there is a trailing slash '/' or not.
project(':mjlmodule').projectDir =
new File(settingsDir, '../Libraries/MyJavaLibrary/mjlmodule/')
-
在Android Project(“MyMainProject”)根模块的build.gradle文件中,默认build.gradle (Module: app),添加:
dependencies {
...
// Reference module rather than project.
implementation project(':malmodule')
implementation project(':mjlmodule')
...
}
- 创建 MyJavaLibrary 时使用独立安装的 JDK,而不是 Android 的嵌入式 JDK:
- 文件 > 项目结构 > |SDK 位置| > JDK位置:
- “使用嵌入式 JDK(推荐)”:未勾选。
- C:\Program Files\Java\jdk1.8.0_161
- 不要删除 MyJavaLibrary 项目的根模块 app。
分步过程如下。字符串中的正斜杠“/”将表示项目窗格中的路径,Android 视图(从组合框中选择)。字符串中的反斜杠“\”表示文件系统中的路径……
创建主 Android 项目
创建一个 Android 项目(“MyMainProject”):
- 打开 {Android Studio} 到“欢迎使用 Android Studio”屏幕 > [开始一个新的 Android Studio 项目] ...
-
向导“创建新项目”> |创建 Android 项目|:
- 应用程序名称(概念上这也是“项目名称”):
MyMainProject
- 公司域名:
example.com.au
- 项目地点:
..\LibraryRefDemo\MyMainProject
- 包名:
au.com.example.mymainproject
- [下一个]
向导|目标 Android 设备:选择外形规格和最小 SDK|。接受默认值(或根据需要)。 [下一步]。
- 向导|将活动添加到移动设备|。空活动。 [下一步]。
- 向导|配置活动|。向后兼容性 (AppCompat):未勾选(或根据需要)。 [完成]
-
添加一些“hello world”资源和代码。在项目窗格中切换到 Android 视图(从组合框中):
-
res/layout/activity_main.xml。添加id。
<TextView
android:id="@+id/mymainproject_output"
android:layout_width="wrap_content"
-
res/values/strings.xml。添加字符串资源。
<string name="mymainproject_cool_string">From My Main Project</string>
-
au.com.example.mymainproject.MainActivity。从 java 代码中引用字符串资源。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.mymainproject_output);
String someString = getResources().getString(R.string.mymainproject_cool_string) + "\r\n";
textView.setText(someString);
}
}
要正确导入引用的类,您可能必须: 将光标插入 TextView; alt+输入;
-
针对模拟器运行以验证确定:运行 > 运行应用程序 (Shift+F10)...“选择部署目标”>(单击所需的可用虚拟设备)> [确定]。
-
等待 gradle 完成构建。观察应用程序中的字符串:
From My Main Project
创建自定义 Android 库
首先我们创建另一个普通的 Android 项目,然后我们把它变成一个 Android 库。
将库创建为另一个普通的 Android 项目:
- 在 Android Studio 中关闭打开的项目(如果已打开)。
-
打开 {Android Studio} 到“欢迎使用 Android Studio”屏幕 > [开始一个新的 Android Studio 项目]:
- 向导“创建新项目”,|创建 Android 项目|。
- 应用程序名称:
MyAndroidLibrary
- 公司域名:
example.com.au
- 项目地址:
..\LibraryRefDemo\Libraries\MyAndroidLibrary
- 包名称。 [编辑]:
au.com.example.malmodule(我们使用此名称而不是默认名称,以便稍后清楚地表明我们直接引用模块而不是项目)。
- [下一个]
- 向导|Target Android Devices|:“选择外形规格和最小”SDK。接受默认值(或根据需要)。[下一步]。
- 向导|向移动设备添加活动| > 空活动 > [下一步]。
- 向导|配置活动|。向后兼容性 (AppCompat):未勾选(或根据需要)。 [完成]
等待 gradle 完成构建。
- {Android Studio} > 项目窗格 > Android 视图(来自组合框)>“应用程序”> 右键单击 > 重构 ...> 重命名:
malmodule
-
添加一些 hello-world 类型代码:
-
在malmodule/res/values/strings.xml中,添加:
<string name="myandroidlibrary_cool_string">From My Android Library</string>
-
../res/layout/activity_main.xml(文本视图)。添加id。
<TextView
android:id="@+id/myandroidlibrary_output"
android:layout_width="wrap_content"
-
在 ..\LibraryRefDemo\Libraries\MyAndroidLibrary\malmodule\src\main\java\au\com\example\malmodule\MainActivity.java 中,添加 onCreate 方法(并导入相关类,alt+enter 光标在 TextView ):
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView myText = (TextView) findViewById(R.id.myandroidlibrary_output);
String someString = getResources().getString(R.string. myandroidlibrary_cool_string) + "\r\n";
myText.setText(someString);
}
}
要正确导入引用的类,您可能必须: 将光标插入 TextView; alt+输入;
从其他地方复制任何现有代码(和资源)。将android代码复制到:..\LibraryRefDemo\Libraries\MyAndroidLibrary\malmodule\src\main\java\au\com\example\malmodule
-
验证它是否可以作为项目运行:运行 > 运行“malmodule”。等待 gradle 完成构建。在模拟器中观察字符串:
From My Android Library
(从上面开始)将项目的模块转换为 Android 库:
-
{Android Studio} > 项目面板 > Android 视图 > Gradle 脚本 > build.gradle(模块:malmodule)> 双击(打开)。那么……
// Change ...
apply plugin: 'com.android.application'
// To ...
apply plugin: 'com.android.library'
-
同样在 build.gradle (Module: malmodule) 中注释掉 applicationID。
...
android {
compileSdkVersion 26
defaultConfig {
// applicationId "au.com.example.malmodule"
...
注释掉而不是删除,以防我们想将malmodule作为一个普通的Android项目重新运行以进行测试。
Android Studio 1.0 and error "Library projects cannot set applicationId"
工具 > Android > 将项目与 Gradle 文件同步(或单击黄色提示栏中的“立即同步”链接)。等待 gradle 构建完成。
从主 Android 项目中引用自定义 Android 库
要引用您的自定义 Android 库项目(位于主项目目录之外):
- {Android Studio} > 文件 > 打开最近 > MyMainProject > '打开项目' > [此窗口]。
- 项目窗格 > Android 视图(从下拉菜单中)。
-
打开 MyMainProject 的 settings.gradle (Project Settings) 文件。添加:malmodule引用如下..
include ':app'
include ':malmodule'
// Despite the name "project" we actually need to reference the module directory
// of a project. It doesn't matter whether there is a trailing slash '/' or not.
project(':malmodule').projectDir =
new File(settingsDir, '../Libraries/MyAndroidLibrary/malmodule/')
-
打开MyMainProject的根模块的build.gradle文件(即build.gradle (Module: app))。然后添加...
dependencies {
...
// Reference module rather than project.
implementation project(':malmodule')
...
}
工具 > Android > 将项目与 Gradle 文件同步(或单击黄色提示栏中的“立即同步”链接)。
- 观察到现在可以通过项目窗格(例如在 Android 视图中)访问 malmodule 的源文件。
-
验证您是否可以从库中引用字符串资源:
-
检查 ..malmodule/res/values/strings.xml 是否有以下字符串 ...
<string name="myandroidlibrary_cool_string">From My Android Library</string>
-
检查 MyMainProject app/res/layout/activity_main.xml ...
<TextView
android:id="@+id/mymainproject_output"
android:layout_width="wrap_content"
...
-
在主项目 app/java/au.com.example.mymainproject/MainActivity 中添加对 myandroidlibrary_cool_string 的引用。
public class MainActivity extends Actvity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView myText = (TextView) findViewById(R.id.mymainproject_output);
String someString = getResources().getString(R.string.mymainproject_cool_string) + "\r\n";
someString += getResources().getString(au.com.example.malmodule.R.string.myandroidlibrary_cool_string) + "\r\n";
myText.setText(someString);
}
}
-
从您的库清单中注释掉 MAIN/LAUNCHER 意图。否则,您的应用程序的两个图标将出现在应用程序抽屉中。
<activity android:name=".MainActivity">
<!-- Don't make a main/launcher activity when being called by main app -->
<!--<intent-filter>-->
<!--<action android:name="android.intent.action.MAIN" />-->
<!--<category android:name="android.intent.category.LAUNCHER" />-->
<!--</intent-filter>-->
</activity>
-
运行您的主项目。运行 > 运行应用程序 (Shift+F10)。等待 gradle 构建并等待模拟器加载您的应用程序。观察来自您的库的字符串反映在您的模拟器中:
From My Main Project
From My Anroid Library
-
从 ..malmodule/res/values/strings.xml 更改字符串
<string name="myandroidlibrary_cool_string">My Android Library XXX</string>
运行 > 应用更改 (Ctrl+F10)。等待 gradle 构建并等待模拟器重新加载您的应用程序。观察更改后的字符串是否反映在您的模拟器中。
(Google,n.d. Gradle 插件用户指南)http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-projects
(Goolge Android 工具,2014 年。开发 > 工具)https://developer.android.com/studio/projects/android-library.html
创建 Java 库/模块
使用 Java 库模块创建项目 ...
首先用一个Android Module创建一个普通的Android Project:
创建一个 Java 库模块:
- 文件 > 新建 ... > 新模块 ...
-
向导“创建新模块”。
- |新模块| > Java 库。 [下一步]
-
|Java 库| “配置你的新模块”。
- 库名称:
mjlmodule
- Java 包名:
au.com.example.mjlmodule
- Java 类名:
Start
- [完成]
不要删除 MyJavaLibrary 项目的根模块 app。如果您这样做,默认情况下,您的 mjlmodule 将成功运行一次,但后续的代码更新不会合并到第二次和后续运行中。
可能有一种方法可以正确整理 gradle 文件,但我的 gradle 知识有限。
在你的 Java 库模块中插入一些代码:
-
在您新创建的 Java 类 Start 中,添加一个 main 方法。确保您的主要方法具有正确的签名(特别包括“String[] args”)。例如,将以下类用于 hello world 目的。 mjlmodule/java/au.com.example.mjlmodule/开始...
package au.com.example.mjlmodule;
public class Start {
public static void main(String[] args) {
System.out.println(getCoolString());
}
// Must be public because we want to reference the method directly later
public static String getCoolString() {
return "From My Java Library";
}
}
-
项目窗格 > Android 视图(来自组合框)> Gradle 脚本 > build.gradle (Module: mjlmodule):
-
验证应用插件集属性:
apply plugin: 'java-library'
-
验证依赖如下:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
// You can delete or comment out ...
//sourceCompatibility = "1.7"
//targetCompatibility = "1.7"
-
使用独立安装的 JDK,而不是 Android 的嵌入式 JDK。
工具 > Android > 将项目与 Gradle 文件同步(或单击黄色提示栏中的“立即同步”链接)。
-
运行 > 编辑配置……
- 点击加号+符号>应用程序
- 姓名:
MyJavaRun
- 主类:
au.com.example.mjlmodule.Start
- 工作目录:...
\LibraryRefDemo\Libraries\MyJavaLibrary
- 使用模块的类路径:
mjlmodule
- JRE:
Default
- [确定]
-
验证模块是否可以运行...
从其他地方复制java代码文件(如果有的话):
将 java 代码复制到:..\LibraryRefDemo\Libraries\MyJavaLibrary\mjlmodule\src\main\java\au\com\example\mjlmodule。
您可能需要在复制的代码中更改包名称。
在 Android Studio 的项目窗格中,观察这些文件的显示(您可能需要等待刷新事件。如果需要强制刷新,请重新启动 {Android Studio})。
再次试运行配置OK:
-
对您的代码进行一些更改,例如:
public class Start {
public static void main(String[] args) {
System.out.println(getCoolString());
}
// Must be public because we want to reference the method directly later
public static String getCoolString() {
return "From My Java Library YYY";
}
}
在运行三角形附近的工具栏上,确保选中“MyJavaRun”配置。点击运行绿色三角形。
-
观察更新后的字符串出现在“运行”窗格中。
From My Java Library YYY
请注意,截至 2018 年 3 月 3 日,Intellij IDEA 2017.3 由于不支持最新的 gradle 插件,现在无法运行 MyJavaLibrary。我预计这将从 IDEA 2018.1 开始发生变化。
看...
它有时会在 3.0-alpha2 和插件的最终 3.0 版本之间停止工作。
gradle 插件导出到 Studio/IJ 以设置项目的模型正在发生重大变化。现在它以旧的和新的方式发送信息,尽管前者并不总是准确的,具体取决于构建设置。这很快就会改变,这将破坏 IJ,直到他们可以捆绑 Studio 插件 3.0。
https://www.reddit.com/r/androiddev/comments/6c71av/using_android_gradle_plugin_300alpha1_with/dhssvlk/
Can't use Android Gradle Plugin 3.0.+ with IntelliJ IDEA
从主项目中引用 Java 库
从 MyMainProject 引用 MyJavaLibrary 模块(“mjlmodule”):
{Android Studio} > 文件 > 打开最近 > [MyMainProject]。在[此窗口]中打开。
-
在Android项目(“MyMainProject”)settings.gradle (Project Settings)添加mjlmodule信息:
include ':app'
include ':malmodule'
// Despite the name "project" we actually need to reference the module directory
// of a project. It doesn't matter whether there is a trailing slash '/' or not.
project(':malmodule').projectDir =
new File(settingsDir, '../Libraries/MyAndroidLibrary/malmodule/')
include ':mjlmodule'
// Despite the name "project" we actually need to reference the module directory
// of a project. It doesn't matter whether there is a trailing slash '/' or not.
project(':mjlmodule').projectDir =
new File(settingsDir, '../Libraries/MyJavaLibrary/mjlmodule/')
-
在MyMainProject的根模块build.gradle (Module:app)中,添加mjmodule信息:
dependencies {
implementation project(':malmodule')
implementation project(':mjlmodule')
...
}
Tools > Android > Sync Project with Gradle files(或点击黄色提示栏“Sync Now”)。
- 观察 mjlmodule 现在在项目窗格(Android 视图)中被引用。
- 按照上面的创建 Java 项目/模块 中的说明添加运行配置。
请注意,我们可以使用 Android 的 Embedded JDK,因为我们可以正常运行 Java 模块(可能是因为我们有一个带有完整根 android 模块的项目)。
-
验证模块可以作为 Java 应用程序运行 ...
- 在运行三角形附近的工具栏上,确保选择了“MyJavaRun”配置。点击运行绿色三角形。
- 在“运行”窗格中观察字符串输出:“From My Java Library YYY”。
-
验证您是否可以从 MyMainProject 引用 MyJavaLibrary 中的字符串资源:
-
在 ..LibraryRefDemo\Libraries\MyJavaLibrary\mjlmodule\src\main\java\au\com\example\mjlmodule\Start.java 中验证
package au.com.example.mjlmodule;
public class Start {
public static void main(String[] args) {
System.out.println(getCoolString());
}
// Must be public because we want to reference the method directly later
public static String getCoolString() {
return "From MyJavaLibrary YYY";
}
}
-
在 MyMainProject app/res/layout/activity_main.xml 中验证
<TextView
android:id="@+id/mymainproject_output"
android:layout_width="wrap_content"
...
-
在 MyMainProject 中添加一些代码以从 MyJavaLibary 中获取代码。在 MyMainProject/app/java/au.com.example.mymainproject/MainActivity 添加对 mjlmodule 字符串的引用 ...
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.mymainproject_output);
String someString = getResources().getString(R.string.mymainproject_cool_string) + "\r\n";
someString += getResources().getString(au.com.example.malmodule.R.string.myandroidlibrary_cool_string) + "\r\n";
someString += au.com.example.mjlmodule.Start.getCoolString() + "\r\n";
myText.setText(someString);
}
}
运行 MyMainProject。在工具栏上选择“应用程序”配置。单击绿色箭头。
如果您收到“无法安装”错误,则 Build > Clean MyMainProject。
-
观察来自您的库的字符串是否反映在您的模拟器(或连接的设备)中。
From MyMainProject
From My Android Library XXX
From My Java Library YYY
-
修改 MyJavaLibrary 中的字符串。 ...\LibraryRefDemo\Libraries\MyJavaLibrary\mjlmodule\src\main\java\au\com\example\mjlmodule\Start.java
public static String getCoolString() {
return "From My Java Library ZZZ";
}
-
运行 > 应用更改。观察字符串是否反映在您的模拟器(或连接的设备)中。
From MyMainProject
From My Android Library XXX
From My Java Library ZZZ
请编辑
如果出现以下情况,请大胆编辑答案:
- 有错误;
- 它变得过时了;
- 你觉得有些事情可以说得更清楚;
- 可以简化步骤;或
- 您可以想出其他一些好的理由来进行编辑。
更新:
- 2018-03-14 04:52Z。首次发布...遵循了一次程序并对其完整性和正确性进行了审查(进行了一些小的更正)。捷豹路虎。
- 2018-10-16 04:11Z。在“从主 Android 项目中引用自定义 Android 库”中添加了注释掉自定义 Android 库的 MAIN/LAUNCHER 意图的步骤。