我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Unity与Android交互(3)——需要了解的Andorid基础知识

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Unity与Android交互(3)——需要了解的Andorid基础知识

【前言】

在上一篇文章中只是说了如何实现unity和android交互的问题,要了解其中的原理还必须要先了解一些Android的基础知识,了解后也能搞清楚如何接入SDK或者写Native插件。

(以下只是简要介绍,详细的内容需要自己去看链接)

Android四大组件

Activitiy

它提供了一个窗口,可以包含用户界面相关的组件,主要用于和用户进行交互,这个窗口通常会填满整个屏幕(可以将Activity理解为Unity中的Canvas)。Android应用程序通常由多个彼此松散绑定的Activity组成,通常,会有一个Activity被指定为MainActivity,启动应用程序时该Activity被激活呈现画面给用户(类似游戏中的主界面),每个Activity可以启动另一个Activity(类似在一个Canvas中打开另一个Canvas),Activity之间的切换基于堆栈机制(这个机制由Android系统实现,游戏中一般是在UIManager中自己实现),Activity之间通过Intent通信。这些Activity需要在AndroidM

在Unity游戏中,通常只有一个Activity,即UnityPlayerActivity。这个Activity会作为游戏的主界面,在启动游戏时被创建并显示,而且在游戏运行期间一直保持活跃状态。UnityPlayerActivity负责加载Unity引擎,并协调游戏界面和游戏逻辑的交互。在Unity中,所有的UI元素、游戏场景、特效等都是通过Unity引擎进行渲染和展示的,因此不需要像原生Android应用那样创建多个Activity来管理多个窗口或界面。

Activity有自己的生命周期,在这个生命周期中进行调用,与Unity的生命周期中的部分关联起来,即可让游戏运行起来。

Service

Service非常适用于去执行那些不需要和用户交互而且还要长期运行在后台的任务,例如播放音效、下载文件等。在Android中,后台的运行是完全不依赖UIService一般默认是后台的,其运行时不依赖任何用户界面,即使Activity被销毁,程序被切换到后台或者打开另外一个应用程序,Service仍然可以保存正常运行(这时Acvivity已经停止运行了)。只有当应用程序进程被杀掉时,所有依赖于该进程的Service才会停止运行。

注意,Service是运行在主线程中的,也即生命周期由主线程控制,所有不能在Service中做耗时长的操作,这会导致主线程阻塞,引发引发ANRApplication Not Responding)异常。耗时操作,通常在Service中开子线程来完成的。

在Android系统中,Service的优先级较低,当系统出现内存不足情况时,就有可能会回收掉正在后台运行的Service。如果希望Service可以一直保持运行状态,而不会由于系统内存不足的原因导致被回收,就可以考虑使用前台Service。前台Service会一直有一个正在运行的图标在系统的状态栏显示,下拉状态栏后可以看到更加详细的信息,非常类似于通知的效果。

Content Provider

Android的数据存储方式总共有五种,分别是:Shared Preferences、网络存储、文件存储、外储存储、SQLite。但一般这些存储都只是在单独的一个应用程序之中达到一个数据的共享,有时候我们需要操作其他应用程序的一些数据,就会用到ContentProvider。其以相对安全的方式封装数据(表)并且提供简易的处理机制和统一的访问接口供其他程序调用。而且Android为常见的一些数据提供了默认的ContentProvider(包括音频、视频、图片和通讯录等)。

如果自己的应用程序里的数据需要其他应用程序访问,需要自己实现ContentProvider,通过uri(统一资源定位符,Universal Resource Identifier)来标识哪些数据其他应用程序可以访问,每个资源都有一个uri。其他应用程序通过ContentResolver来访问ContentProvider提供的数据,通过uri来定位自己要访问的数据,还可以通过ContentProvider来监听ContentProvider的数据变化。(UnityAddressable有和这套机制相似的概念)

Broadcast Receiver

看到广播,不管是在哪,我们都知道是用于做跨模块通信的,在Android中用于应用内多个不同组件之间、不同应用组件之间的消息通信。广播分为有序广播,粘性广播、本地广播、系统广播等。像手机开启、网络状态改变、开始充电、屏幕开启关闭等都会发出系统广播 ,注册了相关广播的app就能知道了,广播被封装在Intent里面,会包含广播类型、广播参数等必要信息。

在发布到Android平台的Unity游戏中,是否需要使用Service、ContentProvider、broadcast receiver,取决于游戏的具体需求。Unity提供了Android Java插件的机制,让我们可以使用Java代码来创建和管理这些组件以实现更加复杂的功能。

【AndroidManifest.xml】

每个Android的应用程序都必须包含一个 AndroidManifest.xml,且文件名是固定的,不能修改。应用程序需要通过它向Android系统提供一些必需的信息,且需要在运行前提供给系统。这些信息包括:

  1. 应用的软件包名称,其通常与代码的命名空间相匹配
  2. 应用的组件,即所需使用的四大组件。每个Activity、Service、Content Provider都需要在文件中进行配置,未配置则不会启动,也即用不了。而Broadcast Receiver的注册分静态注册(在AndroidManifest文件中进行配置)和通过代码动态创建并以调用Context.registerReceiver()的方式注册至系统。静态注册会随系统的启动而一直处于活跃状态,即使程序未运行,只要接收到感兴趣的广播就会触发。
  3. 应用为访问系统或其他应用的受保护部分所需的权限
  4. 应用需要的硬件和软件功能

AndroidManifest文件结构

文件结果官网上说的很详细,不懂的直接在官网上搜即可,这点是必须要看的

Unity如何生成AndroidManifest

首先,Unity有一个默认的AndroidManifest文件,位于:

Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Apk

其次,自己可以根据需要重写AndroidManifest文件:

再次,所有接入的插件或SDK可能以后自己的的AndroidManifest文件

最后,在构建应用时,Unity会将上述所有的文件合成一个文件,修改清单,自动向清单添加权限、配置选项、使用的特性和其他信息,生成最终的AndroidManifest文件。

实例AndroidManifest解析

以之前的例子打包出来的apk的文件并添加些其他东西作为例子进行解析

                                                                                                                                                                                                                                                                                      

【UI线程】

在Android中UI线程是一个应用程序的主线程, 其在app启动时就会被创建(即每个app都有一个UI线程),Activity中涉及到UI组件的更新必须在主线程中进行(这和UnityAPI只能在主线程中使用是一个道理)。从其他线程的调用如果最终涉及到UI组件,就会报错甚至崩溃。其他线程调用UI线程的组件实际上就是多线程之间的通信,Android 提供了几种途径来从其他线程访问 UI 线程,在Unity中一般只用到Activity.runOnUiThread(Runnable)

runOnUiThread()方法是Activity类的一个方法,可以通过当前Activity对象来调用。该方法接受一个Runnable对象作为参数,该Runnable对象中的run()方法会在主线程中执行。如果当前线程时UI线程,那么会立即执行,如果不是那会发到UI线程的一个事件队列里等待执行。其源码如下:

public final void runOnUiThread(Runnable action) {    if(Thread.currentThread() != mUiThread) {        mHandler.post(action);    } else {        action.run();    }}

前文说过,Unity并不使用Android来渲染UI界面,所以Unity有自己的主线程,和Android的UI线程不是同一个线程,但我们可以在UI线程中通过UnitySendMessage发消息给Unity主线程(如上一篇文章所示)。像播放广告、浏览网页等,一般用的是Android UI组件是实现,注意要在UI线程中进行一些处理,需要用到runOnUiThread。

arr与jar

Android工程中, app最终被编译打包成能在Android设备上运行的APK文件,Android library在目录结构上与Android App相同。

其包含构建APP所需的一切(如源代码、资源文件、Android Manifest),但在构建时被编译成供其它Android App依赖的Android Archive (AAR)文件,也即多个app可以使用同一个arr文件(类似Unity中的Package)。

一个arr文件包含了源代码、资源文件、Android Manifest等,将arr文件解压出来,可以得到只包含源代码的Java Archive(JAR)文件。

静态链接库与动态链接库】 

静态库和动态库都是从其他工程里build出来的可重定位目标文件,里面都是二进制的代码,可以被链接生成可执行文件。

在构建形成可执行文件的链接步骤中,会将自己的代码和从静态链接库拷贝出来的代码(仅需要拷贝自己代码使用的那部分库代码,没用的不拷贝)形成一个整体的代码,对动态链接库只会拷贝一些重定位和符号表信息。

在程序运行时,静态链接库中的代码和自己的代码作为一个整体被加载到内存中,而动态链接库在使用时根据重定位和符号表信息加载库并找到需要调用的函数。

因此,对于同样的一份代码,使用静态库构建出来的可执行文件比用动态库的大,多个不同的可执行文件使用了同样的静态库,那么内存中会有多份静态库的代码,而动态库只会有一份。

Linux/Unix 系统里静态库扩展名一般是 .a(archive),动态库扩展名一般是 .so(share object)

Windows 系统里 VC 编译器用的静态库扩展名一般是 .lib,动态库扩展名一般是 .dll(dynamic link library)

Android so文件

Android基于Linux Kernl,开发Android应用时,有时候Java层的编码不能满足实现需求,就需要到C/C++实现后生成的so文件,再用System.loadLibrary()加载进行调用。常见的场景如:加解密算法,音视频编解码等。不同的CPU架构对所执行的二进制文件的规范是不同的,所以在生成so文件时,需要考虑适配市面上不同手机CPU架构。

【SDK的生成】

  1. 编写源代码:一般使用C/C++编写需要实现的功能代码,方便跨平台
  2. 编译源代码:使用编译器将源代码编译成库文件,如.so或.a文件
  3. 创建调用接口:如果是面向Android平台,需要Java Native Interface(JNI)创建Java接口,以便Java代码能够使用库文件中的函数和方法
  4. 打包SDK:如果是面向Android平台,将库文件和写好的Java接口打包成Android SDK,以便其他开发者使用
  5. 测试SDK:对生成的SDK进行测试,确保其能够正常运行
  6. 撰写SDK开发、API接口说明等文档
  7. 发布SDK

来源地址:https://blog.csdn.net/enternalstar/article/details/130999970

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Unity与Android交互(3)——需要了解的Andorid基础知识

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

学习 SQL 之前需要了解的基础知识

目录一、数据库基础1.1 数据库1.2 表1.3 列和数据类型1.4 行1.5 主键二、什么是 SQL三、动手实践3.1 该选哪个 DBMS?四、小结本文为 SQL 初学者介绍了 SQL 究竟是什么,以及它能做什么事情。因为 SQL 是用来与数据库打交道的,所
学习 SQL 之前需要了解的基础知识
2016-05-04

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录