文章目录
- 一、Android studio 环境搭建
- 1. 安装软件
- 2. 配置软件
- 3. 构建项目
- 3. 配置项目
- 1) 解决超时的报错
- 2) 导入本地 sdk 的 jar
- 二. 编写 app
作者: baron
一、Android studio 环境搭建
环境搭建花了很久, 编写 app 调用 HelloManager 提供的服务. app 开发自然离不开 Android Studio. 这个工具是专门用来开发 app 的. 而不同版本之间对各个 api 的支持差异很大. 以下是我尝试使用过的不同版本的 Android Studio . 还有些被我删掉了. 总共试了十几个版本.只有一个成功了. 各版本下载地址.

本次实验成功使用的版本信息如下, 为 Android Studio 4.2 Beta 6
Android Studio 4.2 Beta 6
Build #AI-202.7660.26.42.7188722, built on March 6, 2021
Runtime version: 11.0.8+10-b944.6842174 amd64
VM: OpenJDK 64-Bit Server VM by N/A
Windows 10 10.0
GC: G1 Young Generation, G1 Old Generation
Memory: 1280M
Cores: 20
Registry: external.system.auto.import.disabled=true
对应的名字为 android-studio-ide-202.7188722-windows.exe, 重要的事情说三遍, 一定要用这个版本, 一定要用这个版本, 一定要用这个版本 !!!. 这个破软件向下兼容性极差. =-=
1. 安装软件
双击 exe 文件, 会出现下面安装提示, 点击 next

这里记得勾选 android vitual device.

接着设置安装路径, 我设置在 d 盘, 根据实际情况设置即可

接下来一直点 next 就行了

出现这个界面点击 cancel, 之后又是点击 next. 之后会提示配置 sdk 路径, 这里我选择默认 c 盘

接下来等待 sdk 的安装, 安装完成后界面如下.

到这里软件安装完成.
2. 配置软件
在打开新项目(project)之前要先配置 SDK manager. 这一点很重要, 因为直接打开默认的 api 接口是 34 版本的, 而且使用的工具是也是 34 版本的.

如图所示在左下角打开 SDK manager, 打开之后如下所示.

如图首先去掉 android api 34然后勾选上 android 11. 然后点击 SDK Tools, 配置对应的工具

首先点击右下角 show package details显示出详细的版本, 然后同样的把 34.0.0去掉, 勾选上 30.0.2和 30.0.3. 之后点击 apply.

如图点击 next 进入安装. 等待安装完成

SKD Platforms: 表示使用哪个 sdk , 安卓 11 对应的 sdk 是 30SDK Tools: 和前面的版本需要对应
3. 构建项目
下载完成之后回到前面, 点击创建新项目 project

选择一个 empty activity.

语言选择 java, sdk 选择 Android 11, 之后点击 finish

这里选择 project 方便看代码

接下来会报错如下

到这里项目构建就结束了, 接下来就是配置项目解决报错
3. 配置项目
对目录结构有个了解. 此部分请参考 Android studio项目目录结构. 其中需要关注的目录如下.

| 目录 | 功能 |
|---|---|
| libs | 存放第三方 jar 包的目录, 我们要用我们自己的sdk编译出来包替换掉 as 中默认的包 |
| MainActivity.java | 程序从这里开始运行, 可以理解为 c 语言的 main 函数 |
| app/build.gradle | app 模块的构建配置, 包括 sdk 版本, 以及包含哪些 jar 包等 |
| /build.gradle | 根目录下的 build.gradle 是整个项目的配置文件, 用来指定整具体使用哪个 gradle 插件 |
| gradle-wrapper.properties | 指定了那个 gradle 工具 |
- gradle 插件: 插件提供一些默认的 api 版本, 比如这里使用的安卓 11 就需要使用
gradle:4.2.0 - gradle 工具: 用于整个项目的构建, 测试和部署.
gradle 插件, gradle 工具, 和 java 版本(jdk版本)之间的对应关系请参考 Android Studio Gradle插件版本与Gradle 版本对应关系.
1) 解决超时的报错
有了上述知识之后我们开始配置我们的项目, 首先解决超时报错, 修改文件 gradle\-wrapper.properties, 首先更换 gradle 工具的下载地址.
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-6.7.1-bin.zip
具体修改如图所示

然后打开根目录下 build.gradle做如下修改
buildscript {repositories {maven { url 'https://maven.aliyun.com/repository/jcenter' }maven { url 'https://maven.aliyun.com/repository/google'}maven { url 'https://maven.aliyun.com/repository/gradle-plugin'}maven { url 'https://maven.aliyun.com/repository/public'}google()mavenCentral()}dependencies {//classpath "com.android.tools.build:gradle:4.2.0-beta06"classpath "com.android.tools.build:gradle:4.2.0"// NOTE: Do not place your application dependencies here; they belong// in the individual module build.gradle files}
}
具体修改如图所示

完成之后点击右上角的 try again, 这个选项只有选中这个文件才会出现, 所以要构建项目要先选中这个文件, 不然右上角是不会出现这个选项的. 点击之后等待项目构建完成, 这个构建的时间比较长. 编译完成之后会有如下警告.

这个警告没有任何影响, 假装没看见就行了, 不要去注释掉 jcenter(), 注释掉会报错. 插上机器, 点击运行, 如下所示显示 hello world 就是编译成功了.

2) 导入本地 sdk 的 jar
虽然编译成功了但是调用的接口是, gradle 工具提供的默认接口, 现在还没法调用, 我们需要我们的 app 调用我们 sdk 中添加的 hello 服务能编译通过, 得加入 sdk 中编译出来的 jar 包. 对应的路径
$ ls out/target/common/obj/JAVA_LIBRARIES/framework-minus-apex_intermediates/
classes-header.jar classes.jar javalib.jar
我们需要 classes.jar , 记得在编译之前要把这个删掉再编译, 不然这个可能不会更新的, 导致这个包里面没有更新接口. 把这个拷贝到 app 的 libs 目录, 并且改名为 framework.jar, 然后在 app/gradle 中添加以下内容
gradle.projectsEvaluated {tasks.withType(JavaCompile) {Set<File> fileSet = options.bootstrapClasspath.getFiles()List<File> newFileList = new ArrayList<>();//JAVA语法,可连续调用,输入参数建议为相对路径newFileList.add(new File("libs/framework.jar"))//最后将原始参数添加newFileList.addAll(fileSet)options.bootstrapClasspath = files(newFileList.toArray())}
}dependencies {implementation 'androidx.appcompat:appcompat:1.2.0'implementation 'com.google.android.material:material:1.2.1'implementation 'androidx.constraintlayout:constraintlayout:2.0.1'testImplementation 'junit:junit:4.+'androidTestImplementation 'androidx.test.ext:junit:1.1.2'androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'compileOnly files('libs/framework.jar')
}
修改如图所示

注意了设置里面需要将 “generate *imx” 勾选上用于创建自动创建 imx 文件, 这个文件用来调整使用的 sdk 的顺序. 可以在这里将我们的 jar 提前.接着在根目录下的 build_gradle 中添加下面的内容
allprojects {repositories {google()mavenCentral()jcenter() // Warning: this repository is going to shut down soon}tasks.withType(JavaCompile) {options.compilerArgs.add('-Xbootclasspath/p:app\\libs\\framework.jar')}
}task clean(type: Delete) {delete rootProject.buildDir
}gradle.projectsEvaluated {tasks.withType(JavaCompile) {options.compilerArgs.add('-Xbootclasspath/p:app\\libs\\framework.jar')}
}
具体修改内容如图所示

然后点击右上角的 sync now再次构建. 构建完之后可以看到 framework.jar已经是可以打开的状态. 同时自动为我们创建了 My_Application.app.imx文件, 现在需要修改编译顺序, 将默认的sdk 放到最后面, 这样就会优先使用我们的 framework.jar中的内容了.

这里的修改请参考 如何访问 android系统hide的类或接口, 到这里 Android studio 的环境就搭建完成了, 终于可以开始 app 的编写了.
二. 编写 app
这一步就比较简单了, 修改文件
MyApplication\app\src\main\java\com\example\myapplication\MainActivity.java
修改内容如下
package com.example.myapplication;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.app.HelloManager;
import android.content.Context;
import android.util.Slog;public class MainActivity extends AppCompatActivity {private HelloManager mHelloManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 通过 HELLO_SERVICE 这个静态变量获取到 HelloManagermHelloManager = (HelloManager)getSystemService(Context.HELLO_SERVICE);mHelloManager.setVal("Hello"); // 调用 setVal 方法// 调用 getVal方法并打印 logSlog.i("HelloServiceTest", "HelloService TEST getVal = "+mHelloManager.getVal());}
}
修改完之后点击运行, 如下图所示.

同步 adb shell 之后 logcat 查看 log 如下, 系统服务接口调佣成功 ∧_∧
01-26 02:27:10.359 2251 2251 I SystemServiceRegistry: registerService HELLO_SERVICE b = android.os.BinderProxy@48b7bd8
01-26 02:27:10.360 2251 2251 I SystemServiceRegistry: registerService HELLO_SERVICE service = android.os.IHelloService$Stub$Proxy@2fbb31
01-26 02:27:10.360 2251 2251 E HelloManager: HelloManager setVal
01-26 02:27:10.361 434 1429 I HelloService: setVal value = Hello
01-26 02:27:10.362 2251 2251 E HelloManager: HelloManager getVal
01-26 02:27:10.362 434 1429 I HelloService: getVal
01-26 02:27:10.363 2251 2251 I HelloServiceTest: HelloService TEST getVal = getVal