rk3566-Android11 从驱动到 app 第四章编写 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.230.0.3. 之后点击 apply.

在这里插入图片描述

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

在这里插入图片描述

  • SKD Platforms: 表示使用哪个 sdk , 安卓 11 对应的 sdk 是 30
  • SDK 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;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 通过 HELLO_SERVICE 这个静态变量获取到 HelloManager
        mHelloManager = (HelloManager)getSystemService(Context.HELLO_SERVICE);
        mHelloManager.setVal("Hello"); // 调用 setVal 方法
        // 调用 getVal方法并打印 log
        Slog.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

最近更新

  1. TCP协议是安全的吗?

    2024-01-28 18:36:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-28 18:36:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-28 18:36:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-28 18:36:01       18 阅读

热门阅读

  1. Linux delay相关函数实现

    2024-01-28 18:36:01       25 阅读
  2. 无人机调试开源软件

    2024-01-28 18:36:01       45 阅读
  3. Writing and Using a Simple Plugin

    2024-01-28 18:36:01       34 阅读
  4. 电脑上显示U盘多个盘符怎么办?

    2024-01-28 18:36:01       42 阅读