gitweixin
  • 首页
  • 小程序代码
    • 资讯读书
    • 工具类
    • O2O
    • 地图定位
    • 社交
    • 行业软件
    • 电商类
    • 互联网类
    • 企业类
    • UI控件
  • 大数据开发
    • Hadoop
    • Spark
    • Hbase
    • Elasticsearch
    • Kafka
    • Flink
    • 数据仓库
    • 数据挖掘
    • flume
    • Kafka
    • Hive
    • shardingsphere
    • solr
  • 开发博客
    • Android
    • php
    • python
    • 运维
    • 技术架构
    • 数据库
  • 程序员网赚
  • bug清单
  • 量化投资
  • 在线查询工具
    • 去行号
    • 在线时间戳转换工具
    • 免费图片批量修改尺寸在线工具
    • SVG转JPG在线工具

分类归档Android

精品微信小程序开发门户,代码全部亲测可用

  • 首页   /  
  • 分类归档: "Android"
  • ( 页面3 )
Android 8月 27,2024

为什么要引入Project Butter改进Android的屏幕刷新机制?

Project Butter是Google在Android 4.1 Jelly Bean版本中推出的一项优化措施,旨在显著提升Android设备的屏幕流畅度和响应速度。引入Project Butter的主要原因包括:

  1. 提升用户体验:通过优化屏幕渲染流程,减少画面卡顿和延迟,使得滚动、动画和触摸操作更加平滑,从而提供更加直观和愉悦的用户交互体验。
  2. 增强系统响应性:Project Butter通过引入三重缓冲(Triple Buffering)和垂直同步(VSync)技术,确保屏幕刷新与设备处理速度同步,减少画面撕裂现象,提高系统的整体响应速度。
  3. 适应硬件发展:随着移动设备硬件性能的提升,用户对流畅体验的期望也在提高。Project Butter利用了当时更强大的处理器和图形处理能力,充分发挥硬件潜力,提供了更加流畅的视觉效果。
  4. 统一和简化开发流程:通过改进屏幕刷新机制,Google也为开发者提供了更加稳定和高效的开发环境,简化了开发流程,使得开发者能够更容易地创建流畅的应用界面。
作者 east
Android 8月 27,2024

Android系统是如何通过VSync信号实现屏幕刷新的?

在Android系统中,VSync(垂直同步)信号是由显示器产生的,用于指示屏幕的垂直刷新时刻。系统通过捕捉这个信号来同步屏幕的刷新与图形处理单元(GPU)的输出,以避免画面撕裂和减少视觉闪烁。

当VSync信号到来时,系统会通知GPU准备下一帧的渲染。GPU执行渲染操作,并在VSync信号的下一个到来时刻将渲染好的帧发送到屏幕。这样,屏幕刷新与GPU输出之间就保持了同步,确保了图像的连续性和流畅性。

Android系统中的SurfaceFlinger是负责管理和合成屏幕上显示内容的服务。它接收来自不同应用和系统组件的渲染请求,并将这些请求合并成最终的帧缓冲区。当VSync信号到达时,SurfaceFlinger会将这个帧缓冲区发送到显示器,完成屏幕的刷新过程。

通过这种机制,Android系统能够有效地管理屏幕刷新,提供稳定的视觉体验,并减少因帧率不稳定导致的问题。

作者 east
Android 8月 15,2024

Android Studio常用的调试工具有哪些及其用法?

Android Studio常用调试工具及用法

1. Logcat

  • 用途: Logcat 是 Android Studio 中用于查看实时日志输出的工具。开发者可以通过它来监视应用程序的系统输出、调试信息以及异常堆栈跟踪。
  • 用法: 在 Android Studio 底部窗口中找到 Logcat 标签页,选择相应的设备和进程,即可查看日志。可以使用过滤器来筛选特定的日志信息。

2. Device File Explorer

  • 用途: Device File Explorer 允许开发者浏览、编辑和传输文件到连接的设备上。
  • 用法: 在 Android Studio 顶部菜单栏中选择 “View” > “Tool Windows” > “Device File Explorer”。在这里,可以导航到设备的文件系统,并对其进行操作。

3. Debugger

  • 用途: Debugger 是一个强大的代码调试工具,它允许开发者设置断点、单步执行代码、检查变量值和调用栈等。
  • 用法: 在代码编辑器中点击行号旁边的空白区域设置断点,运行应用程序并在达到断点时暂停执行。使用调试视图监控变量和表达式,或者使用控制按钮来控制程序的执行流程。

4. Profiler

  • 用途: Profiler 提供了性能分析工具,帮助开发者识别和优化应用程序的 CPU、内存和网络使用情况。
  • 用法: 在 Android Studio 顶部菜单栏中选择 “Profile” 或使用快捷键 Ctrl+Shift+F12 (Windows/Linux) / Cmd+Shift+F12 (macOS) 打开 Profiler 窗口。选择相应的分析器开始收集数据,并根据收集到的信息进行性能分析。
作者 east
Android 8月 15,2024

Android应用程序性能优化通常需要注意哪些方面?

Android应用程序性能优化的关键点

Android应用程序性能优化是确保应用流畅运行、响应迅速的关键步骤。以下是在进行性能优化时需要特别注意的几个方面:

  1. 代码优化:编写高效、简洁的代码,减少不必要的计算和内存分配,使用性能分析工具找到代码瓶颈,优化数据库查询,减少循环和递归的使用。 
  2. 内存管理:理解内存泄漏和内存碎片的概念,使用内存池或对象池减少内存分配和释放开销,避免不必要的内存拷贝操作。 
  3. 并发和多线程:使用线程池、异步编程等技术提高程序的并发性能,学习如何优化锁的使用,减少线程间的竞争。 
  4. I/O优化:减少磁盘I/O操作,优化网络I/O,使用缓存、批量写入等技术,压缩和解压缩数据以减少传输量。 
  5. 系统调优:调整操作系统参数设置,使用性能监控工具观察系统状态,根据需要调整JVM、数据库等中间件的参数设置。 
  6. 启动速度与执行效率优化:优化应用的启动流程,减少初始化时间,优化布局以减少渲染时间。 
  7. 内存优化:避免内存泄漏,合理分配和释放内存,使用内存监控工具监控内存使用情况。 
  8. 图形渲染优化:避免过度绘制,使用硬件加速,选择合适的图片格式和尺寸,使用高效的图像处理算法。 
  9. 网络优化:避免频繁的网络请求,使用缓存机制减少重复请求,压缩网络数据,使用合理的网络超时机制。 
  10. 电池优化:避免过度频繁的CPU和GPU活动,减少不必要的网络唤醒和定位操作,降低屏幕亮度以减少耗电量。 
  11. APK大小优化:压缩资源文件,移除未使用的代码和资源,使用资源混淆和Shrink Resources功能减小APK体积。 
  12. 性能测试与监控:定期进行性能测试,使用性能分析工具监控应用性能,以便及时发现和解决性能问题。 
作者 east
Android 8月 15,2024

Android开发中常见的内存管理机制有哪些?

A

Android开发中的内存管理机制

在Android开发中,内存管理是确保应用性能和稳定性的关键因素。以下是一些常见的内存管理机制:

  1. 垃圾回收(Garbage Collection, GC):
    Android使用垃圾回收机制来自动管理堆内存。垃圾回收器负责检测不再被引用的对象,并回收它们占用的内存空间,以减少内存泄漏和溢出的风险。垃圾回收算法通常包括标记-清除(Mark-Sweep)和复制算法,其中年轻代对象经常使用复制算法来减少碎片化。 
  2. 内存分区:
    Android系统将内存分为不同的区域,主要包括堆(用于存放应用程序的对象)和栈(用于存放方法调用时的局部变量和方法参数)。堆内存进一步分为新生代和老年代,以优化垃圾回收效率。 
  3. 内存泄漏检测:
    内存泄漏是指应用程序中的对象占用了内存资源,但在不再需要时未能及时释放。为了帮助开发者检测和修复内存泄漏问题,Android提供了工具如LeakCanary,它可以自动检测内存泄漏并生成详细的报告。 
  4. 内存碎片管理:
    内存碎片化是由于小块内存的分配和释放导致的,这些小块内存之间可能存在未利用的空间。为了减少碎片化,可以使用对象池和Bitmap复用池等技术,这些技术通过重用内存来减少新的内存分配请求。 
  5. 内存管理策略:
    Android系统还实施了一系列内存管理策略,如Low Memory Killer(LMK)和Activity Manager,这些策略监控应用程序的内存使用情况,并在必要时采取措施回收内存,以防止系统整体内存不足。 

这些机制共同构成了Android应用程序的内存管理框架,帮助开发者有效地管理和优化内存使用,以提供流畅的用户体验。

作者 east
Android, spring 4月 29,2022

生产环境app和后台都看不到日志的异常调试方法

最近调试一个项目,调试到让人亏崩溃。

由于是特殊行业,手机不开usb调试模式,这样没法看到android app的日志。由于疫情等原因,又无法到现场看后台日志。在调试app登录时,app一直报“ 网络异常,请稍后重试” 。

由于网络是经过第三方转发的,刚开始以为是第三方转发那方面没配置好。经过费劲周折,先后发现app的key、secret、url配错了,又测了后台直接调用的接口是通的,反复找第三方转发公司确认,才确认第三方转发是正确的,整个网络是通的。

全面的测试用例查找问题:

app端对网络异常处理不够完善,当后台500出错时,app没准确提示,还是提示统一的“网络异常,请稍后重试”。怀疑app访问超时导致这样问题,修改超时时间还是没返回。后来别的同事加入讨论,他测试的账号是不存在的,终于有了后台提示。我之前一直是用正确存在的账号测试,反而一直没有收到后台返回结果。看来测试还是要考虑正常和非正常等多元化测试,考虑全面的测试用例,这样可以覆盖代码多个分支。

替代排除法:

通过上面的步骤,已经确认了app能正确访问到生产环境的后台,但不确定是app和后台都有问题,还只是后台有问题。想到生产环境还有一套接口一模一样生产环境的后台,是能正常使用的。把app的url修改成那个后台的地址,发现app登录等一切正常。

通过日志分析:

没办法调试app和后台,但日志还是可以想办法拿到的。android的日志可以上传到后台,也可以保存到本地,通过文件浏览器来找到日志文件。例如在Android把调试日志保存到本地,然后在手机找到安装包包名对应的目录,就可以查找到日志。

通过上面的方法,看到app日志报的是500错误,那么是后台接口报错,后来通过查看后台日志,果然看到空指针错误了。处理好问题了,果然app能正常登录后台和正常使用了。

作者 east
Android, Harmony 6月 11,2021

鸿蒙Harmony和Android服务Service对比

Harmony和Android都提供了后台服务,当用户切换别的应用时,都可以使用服务来播放音乐保证不中断。

图1 鸿蒙Harmony Service Ability 生命周期
图2 Android Service的生命周期

Harmony Service Ability:

基于Service模板的Ability(以下简称“Service”)主要用于后台运行任务(如执行音乐播放、文件下载等),但不提供用户交互界面。Service可由其他应用或Ability启动,即使用户切换到其他应用,Service仍将在后台继续运行。

Service是单实例的。在一个设备上,相同的Service只会存在一个实例。如果多个Ability共用这个实例,只有当与Service绑定的所有Ability都退出后,Service才能够退出。由于Service是在主线程里执行的,因此,如果在Service里面的操作时间过长,开发者必须在Service里创建新的线程来处理(详见线程间通信),防止造成主线程阻塞,应用程序无响应。

与Page类似,Service也拥有生命周期,如图1所示。根据调用方法的不同,其生命周期有以下两种路径:

  • 启动Service该Service在其他Ability调用startAbility()时创建,然后保持运行。其他Ability通过调用stopAbility()来停止Service,Service停止后,系统会将其销毁。
  • 连接Service该Service在其他Ability调用connectAbility()时创建,客户端可通过调用disconnectAbility​()断开连接。多个客户端可以绑定到相同Service,而且当所有绑定全部取消后,系统即会销毁该Service。图1 Service生命周期

一般情况下,Service都是在后台运行的,后台Service的优先级都是比较低的,当资源不足时,系统有可能回收正在运行的后台Service。

在一些场景下(如播放音乐),用户希望应用能够一直保持运行,此时就需要使用前台Service。前台Service会始终保持正在运行的图标在系统状态栏显示。

使用前台Service并不复杂,开发者只需在Service创建的方法里,调用keepBackgroundRunning()将Service与通知绑定。调用keepBackgroundRunning()方法前需要在配置文件中声明ohos.permission.KEEP_BACKGROUND_RUNNING权限,同时还需要在配置文件中添加对应的backgroundModes参数。在onStop()方法中调用cancelBackgroundRunning​()方法可停止前台Service。

Android Service:

Service 是一种可在后台执行长时间运行操作而不提供界面的应用组件。服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。此外,组件可通过绑定到服务与之进行交互,甚至是执行进程间通信 (IPC)。例如,服务可在后台处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序进行交互。

以下是三种不同的服务类型:前台前台服务执行一些用户能注意到的操作。例如,音频应用会使用前台服务来播放音频曲目。前台服务必须显示通知。即使用户停止与应用的交互,前台服务仍会继续运行。后台后台服务执行用户不会直接注意到的操作。例如,如果应用使用某个服务来压缩其存储空间,则此服务通常是后台服务。

注意:如果您的应用面向 API 级别 26 或更高版本,当应用本身未在前台运行时,系统会对运行后台服务施加限制。在诸如此类的大多数情况下,您的应用应改为使用计划作业。绑定当应用组件通过调用 bindService() 绑定到服务时,服务即处于绑定状态。绑定服务会提供客户端-服务器接口,以便组件与服务进行交互、发送请求、接收结果,甚至是利用进程间通信 (IPC) 跨进程执行这些操作。仅当与另一个应用组件绑定时,绑定服务才会运行。多个组件可同时绑定到该服务,但全部取消绑定后,该服务即会被销毁。

虽然本文档分开概括讨论启动服务和绑定服务,但您的服务可同时以这两种方式运行,换言之,它既可以是启动服务(以无限期运行),亦支持绑定。唯一的问题在于您是否实现一组回调方法:onStartCommand()(让组件启动服务)和 onBind()(实现服务绑定)。

无论服务是处于启动状态还是绑定状态(或同时处于这两种状态),任何应用组件均可像使用 Activity 那样,通过调用 Intent 来使用服务(即使此服务来自另一应用)。不过,您可以通过清单文件将服务声明为私有服务,并阻止其他应用访问该服务。使用清单文件声明服务部分将对此做更详尽的阐述。

作者 east
Android, Harmony 6月 11,2021

鸿蒙Harmony和Android的Intent对比

鸿蒙harmony和android都有Intent,用于一个操作界面调用另一个操作界面,并可用于传递数据。

Harmony Intent:

Intent是对象之间传递信息的载体。例如,当一个Ability需要启动另一个Ability时,或者一个AbilitySlice需要导航到另一个AbilitySlice时,可以通过Intent指定启动的目标同时携带相关数据。Intent的构成元素包括Operation与Parameters,具体描述参见表1。

属性子属性描述
OperationAction表示动作,通常使用系统预置Action,应用也可以自定义Action。例如IntentConstants.ACTION_HOME表示返回桌面动作。
Entity表示类别,通常使用系统预置Entity,应用也可以自定义Entity。例如Intent.ENTITY_HOME表示在桌面显示图标。
Uri表示Uri描述。如果在Intent中指定了Uri,则Intent将匹配指定的Uri信息,包括scheme, schemeSpecificPart, authority和path信息。
Flags表示处理Intent的方式。例如Intent.FLAG_ABILITY_CONTINUATION标记在本地的一个Ability是否可以迁移到远端设备继续运行。
BundleName表示包描述。如果在Intent中同时指定了BundleName和AbilityName,则Intent可以直接匹配到指定的Ability。
AbilityName表示待启动的Ability名称。如果在Intent中同时指定了BundleName和AbilityName,则Intent可以直接匹配到指定的Ability。
DeviceId表示运行指定Ability的设备ID。
Parameters–Parameters是一种支持自定义的数据结构,开发者可以通过Parameters传递某些请求所需的额外信息。

当Intent用于发起请求时,根据指定元素的不同,分为两种类型:

  • 如果同时指定了BundleName与AbilityName,则根据Ability的全称(例如“com.demoapp.FooAbility”)来直接启动应用。
  • 如果未同时指定BundleName和AbilityName,则根据Operation中的其他属性来启动应用。

说明

Intent设置属性时,必须先使用Operation来设置属性。如果需要新增或修改属性,必须在设置Operation后再执行操作。

关于Intent最简单的使用方法,可参见快速入门的示例代码。其中“实现页面跳转”重点描述了使用Intent实现两个页面跳转关系的操作。

根据Ability的全称启动应用

通过构造包含BundleName与AbilityName的Operation对象,可以启动一个Ability、并导航到该Ability。示例代码如下:

Intent intent = new Intent();
// 通过Intent中的OperationBuilder类构造operation对象,指定设备标识(空串表示当前设备)、应用包名、Ability名称Operation operation = new Intent.OperationBuilder()        .withDeviceId("")        .withBundleName("com.demoapp")        .withAbilityName("com.demoapp.FooAbility")        .build();
// 把operation设置到intent中intent.setOperation(operation);startAbility(intent);

作为处理请求的对象,会在相应的回调方法中接收请求方传递的Intent对象。以导航到另一个Ability为例,导航的目标Ability可以在其onStart()回调的参数中获得Intent对象。

根据Operation的其他属性启动应用

有些场景下,开发者需要在应用中使用其他应用提供的某种能力,而不感知提供该能力的具体是哪一个应用。例如开发者需要通过浏览器打开一个链接,而不关心用户最终选择哪一个浏览器应用,则可以通过Operation的其他属性(除BundleName与AbilityName之外的属性)描述需要的能力。如果设备上存在多个应用提供同种能力,系统则弹出候选列表,由用户选择由哪个应用处理请求。以下示例展示使用Intent跨Ability查询天气信息。

请求方

在Ability中构造Intent以及包含Action的Operation对象,并调用startAbilityForResult()方法发起请求。然后重写onAbilityResult()回调方法,对请求结果进行处理。

private void queryWeather() {    Intent intent = new Intent();    Operation operation = new Intent.OperationBuilder()            .withAction(Intent.ACTION_QUERY_WEATHER)            .build();    intent.setOperation(operation);    startAbilityForResult(intent, REQ_CODE_QUERY_WEATHER);}
@Overrideprotected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {    switch (requestCode) {        case REQ_CODE_QUERY_WEATHER:            // Do something with result.            ...            return;        default:            ...    }}

处理方

  1. 作为处理请求的对象,首先需要在配置文件中声明对外提供的能力,以便系统据此找到自身并作为候选的请求处理者。
    1. {
    2. “module”: {
    3. …
    4. “abilities”: [
    5. {
    6. …
    7. “skills”:[
    8. {
    9. “actions”:[
    10. “ability.intent.QUERY_WEATHER”
    11. ]
    12. }
    13. ]
    14. …
    15. }
    16. ]
    17. …
    18. }
    19. …
    20. }
  2. 在Ability中配置路由以便支持以此action导航到对应的AbilitySlice。
    1. @Override
    2. protected void onStart(Intent intent) {
    3. …
    4. addActionRoute(Intent.ACTION_QUERY_WEATHER, DemoSlice.class.getName());
    5. …
    6. }
  3. 在Ability中处理请求,并调用setResult()方法暂存返回结果。
    1. @Override
    2. protected void onActive() {
    3. …
    4. Intent resultIntent = new Intent();
    5. setResult(0, resultIntent); //0为当前Ability销毁后返回的resultCode。
    6. …
    7. }

Android Intent:

Intent 是一个消息传递对象,您可以用来从其他应用组件请求操作。尽管 Intent 可以通过多种方式促进组件之间的通信,但其基本用例主要包括以下三个:

  • 启动 ActivityActivity 表示应用中的一个屏幕。通过将 Intent 传递给 startActivity(),您可以启动新的 Activity 实例。Intent 用于描述要启动的 Activity,并携带任何必要的数据。如果您希望在 Activity 完成后收到结果,请调用 startActivityForResult()。在 Activity 的 onActivityResult() 回调中,您的 Activity 将结果作为单独的 Intent 对象接收。如需了解详细信息,请参阅 Activity 指南。
  • 启动服务Service 是一个不使用用户界面而在后台执行操作的组件。使用 Android 5.0(API 级别 21)及更高版本,您可以启动包含 JobScheduler 的服务。如需了解有关 JobScheduler 的详细信息,请参阅其 API-reference documentation。对于 Android 5.0(API 级别 21)之前的版本,您可以使用 Service 类的方法来启动服务。通过将 Intent 传递给 startService(),您可以启动服务执行一次性操作(例如,下载文件)。Intent 用于描述要启动的服务,并携带任何必要的数据。如果服务旨在使用客户端-服务器接口,则通过将 Intent 传递给 bindService(),您可以从其他组件绑定到此服务。如需了解详细信息,请参阅服务指南。
  • 传递广播广播是任何应用均可接收的消息。系统将针对系统事件(例如:系统启动或设备开始充电时)传递各种广播。通过将 Intent 传递给 sendBroadcast() 或 sendOrderedBroadcast(),您可以将广播传递给其他应用。

本页的其余部分将说明 Intent 的工作方式及如何使用 Intent。对于相关信息,请参阅与其他应用交互和共享内容。

Intent 类型

Intent 分为两种类型:

  • 显式 Intent:通过提供目标应用的软件包名称或完全限定的组件类名来指定可处理 Intent 的应用。通常,您会在自己的应用中使用显式 Intent 来启动组件,这是因为您知道要启动的 Activity 或服务的类名。例如,您可能会启动您应用内的新 Activity 以响应用户操作,或者启动服务以在后台下载文件。
  • 隐式 Intent :不会指定特定的组件,而是声明要执行的常规操作,从而允许其他应用中的组件来处理。例如,如需在地图上向用户显示位置,则可以使用隐式 Intent,请求另一具有此功能的应用在地图上显示指定的位置。

图 1 显示如何在启动 Activity 时使用 Intent。当 Intent 对象显式命名某个具体的 Activity 组件时,系统立即启动该组件。

图 1. 隐式 Intent 如何通过系统传递以启动其他 Activity:[1] Activity A 创建包含操作描述的 Intent,并将其传递给 startActivity()。[2] Android 系统搜索所有应用中与 Intent 匹配的 Intent 过滤器。找到匹配项之后,[3] 该系统通过调用匹配 Activity (Activity B) 的 onCreate() 方法并将其传递给 Intent,以此启动匹配 Activity。

使用隐式 Intent 时,Android 系统通过将 Intent 的内容与在设备上其他应用的清单文件中声明的 Intent 过滤器进行比较,从而找到要启动的相应组件。如果 Intent 与 Intent 过滤器匹配,则系统将启动该组件,并向其传递 Intent 对象。如果多个 Intent 过滤器兼容,则系统会显示一个对话框,支持用户选取要使用的应用。

Intent 过滤器是应用清单文件中的一个表达式,用于指定该组件要接收的 Intent 类型。例如,通过为 Activity 声明 Intent 过滤器,您可以使其他应用能够直接使用某一特定类型的 Intent 启动 Activity。同样,如果您没有为 Activity 声明任何 Intent 过滤器,则 Activity 只能通过显式 Intent 启动。

注意:为了确保应用的安全性,启动 Service 时,请始终使用显式 Intent,且不要为服务声明 Intent 过滤器。使用隐式 Intent 启动服务存在安全隐患,因为您无法确定哪些服务将响应 Intent,且用户无法看到哪些服务已启动。从 Android 5.0(API 级别 21)开始,如果使用隐式 Intent 调用 bindService(),系统会抛出异常。

构建 Intent

Intent 对象携带 Android 系统用来确定要启动哪个组件的信息(例如,准确的组件名称或应当接收该 Intent 的组件类别),以及收件人组件为了正确执行操作而使用的信息(例如,要采取的操作以及要处理的数据)。

Intent 中包含的主要信息如下:组件名称要启动的组件名称。

这是可选项,但也是构建显式 Intent 的一项重要信息,这意味着 Intent 应当仅传递给由组件名称定义的应用组件。如果没有组件名称,则 Intent 则为隐式,且系统将根据其他 Intent 信息(例如,以下所述的操作、数据和类别)决定哪个组件应当接收 Intent。如需在应用中启动特定的组件,则应指定该组件的名称。

请注意:启动 Service 时,应始终指定组件名称。否则,您无法确定哪项服务会响应 Intent,且用户无法看到哪项服务已启动。

Intent 的这一字段是 ComponentName 对象,您可以使用目标组件的完全限定类名指定此对象,其中包括应用的软件包名称。例如,com.example.ExampleActivity。您可以使用 setComponent()、setClass()、setClassName(),或 Intent 构造函数设置组件名称。操作指定要执行的通用操作(例如,查看或选取)的字符串。

对于广播 Intent,这是指已发生且正在报告的操作。操作会在很大程度上决定其余 Intent 的构成,特别是数据和 extra 中包含的内容。

您可以指定自己的操作,供 Intent 在您的应用内使用(或者供其他应用在您的应用中调用组件)。但是,您通常应该使用由Intent 类或其他框架类定义的操作常量。以下是一些用于启动 Activity 的常见操作:ACTION_VIEW如果您拥有一些某项 Activity 可向用户显示的信息(例如,要使用图库应用查看的照片;或者要使用地图应用查看的地址),请通过 Intent 将此操作与 startActivity() 结合使用。ACTION_SEND这也称为共享 Intent。如果您拥有一些用户可通过其他应用(例如,电子邮件应用或社交共享应用)共享的数据,则应使用 Intent 将此操作与 startActivity() 结合使用。

有关更多定义通用操作的常量,请参阅 Intent 类参考文档。其他操作在 Android 框架中的其他位置定义。例如,对于在系统的设置应用中打开特定屏幕的操作,将在 Settings中定义。

您可以使用 setAction() 或 Intent 构造函数为 Intent 指定操作。

作者 east
Android, Harmony 6月 10,2021

鸿蒙Harmony和Android生命周期对比

Android发展了这么多年了,其生命周期已经是非常完善,鸿蒙harmony也是借鉴android生命周期,甚至生命周期名字都类似。

harmony鸿蒙生命周期

鸿蒙Harmony的Page Ability生命周期

系统管理或用户操作等行为均会引起Page实例在其生命周期的不同状态之间进行转换。Ability类提供的回调机制能够让Page及时感知外界变化,从而正确地应对状态变化(比如释放资源),这有助于提升应用的性能和稳健性。

  • onStart()当系统首次创建Page实例时,触发该回调。对于一个Page实例,该回调在其生命周期过程中仅触发一次,Page在该逻辑后将进入INACTIVE状态。开发者必须重写该方法,并在此配置默认展示的AbilitySlice。
    1. @Override
    2. public void onStart(Intent intent) {
    3. super.onStart(intent);
    4. super.setMainRoute(FooSlice.class.getName());
    5. }
  • onActive()Page会在进入INACTIVE状态后来到前台,然后系统调用此回调。Page在此之后进入ACTIVE状态,该状态是应用与用户交互的状态。Page将保持在此状态,除非某类事件发生导致Page失去焦点,比如用户点击返回键或导航到其他Page。当此类事件发生时,会触发Page回到INACTIVE状态,系统将调用onInactive()回调。此后,Page可能重新回到ACTIVE状态,系统将再次调用onActive()回调。因此,开发者通常需要成对实现onActive()和onInactive(),并在onActive()中获取在onInactive()中被释放的资源。
  • onInactive()当Page失去焦点时,系统将调用此回调,此后Page进入INACTIVE状态。开发者可以在此回调中实现Page失去焦点时应表现的恰当行为。
  • onBackground()如果Page不再对用户可见,系统将调用此回调通知开发者用户进行相应的资源释放,此后Page进入BACKGROUND状态。开发者应该在此回调中释放Page不可见时无用的资源,或在此回调中执行较为耗时的状态保存操作。
  • onForeground()处于BACKGROUND状态的Page仍然驻留在内存中,当重新回到前台时(比如用户重新导航到此Page),系统将先调用onForeground()回调通知开发者,而后Page的生命周期状态回到INACTIVE状态。开发者应当在此回调中重新申请在onBackground()中释放的资源,最后Page的生命周期状态进一步回到ACTIVE状态,系统将通过onActive()回调通知开发者用户。
  • onStop()系统将要销毁Page时,将会触发此回调函数,通知用户进行系统资源的释放。销毁Page的可能原因包括以下几个方面:
    • 用户通过系统管理能力关闭指定Page,例如使用任务管理器关闭Page。
    • 用户行为触发Page的terminateAbility()方法调用,例如使用应用的退出功能。
    • 配置变更导致系统暂时销毁Page并重建。
    • 系统出于资源管理目的,自动触发对处于BACKGROUND状态Page的销毁。

Android Activity 生命周期:

当用户浏览、退出和返回到您的应用时,您应用中的 Activity 实例会在其生命周期的不同状态间转换。Activity 类会提供许多回调,这些回调会让 Activity 知晓某个状态已经更改:系统正在创建、停止或恢复某个 Activity,或者正在销毁该 Activity 所在的进程。

在生命周期回调方法中,您可以声明用户离开和再次进入 Activity 时 Activity 的行为方式。例如,如果您正构建流媒体视频播放器,当用户切换至另一应用时,您可能要暂停视频或终止网络连接。当用户返回时,您可以重新连接网络并允许用户从同一位置继续播放视频。换言之,每个回调都支持您执行适合给定状态变更的特定作业。在合适的时间执行正确的作业,并妥善处理转换,这将提升应用的稳健性和性能。例如,良好的生命周期回调实现有助于防止应用出现以下问题:

  • 当用户在使用应用时接听来电,或切换至另一应用时崩溃。
  • 当用户未主动使用它时,消耗宝贵的系统资源。
  • 当用户离开应用并在稍后返回时,丢失用户的进度。
  • 当屏幕在横向和纵向之间旋转时,崩溃或丢失用户的进度。

本文档将详细介绍 Activity 生命周期。首先介绍生命周期范例。接着介绍每个回调:它们执行时内部发生了什么,以及您应该在执行期间实现什么。然后,简要介绍 Activity 状态与导致进程被系统终止的漏洞之间的关系。最后,讨论与在 Activity 状态之间转换相关的若干主题。

如需了解有关处理生命周期的信息(包括最佳做法的相关指导),请参阅使用生命周期感知型组件处理生命周期和保存界面状态。如需了解如何将 Activity 与架构组件结合使用,以构建生产质量的稳健应用,请参阅应用架构指南。

Activity 生命周期概念

为了在 Activity 生命周期的各个阶段之间导航转换,Activity 类提供六个核心回调:onCreate()、onStart()、onResume()、onPause()、onStop() 和 onDestroy()。当 Activity 进入新状态时,系统会调用其中每个回调。

图 1 是对此范例的直观展现。

图 1. Activity 生命周期的简化图示。

当用户开始离开 Activity 时,系统会调用方法来销毁该 Activity。在某些情况下,此销毁只是部分销毁;Activity 仍然驻留在内存中(例如当用户切换至另一应用时),并且仍然可以返回到前台。如果用户返回到该 Activity,Activity 会从用户离开时的位置继续运行。除了少数例外,应用在后台运行时会受到限制,无法启动 Activity。

系统终止给定进程及其中 Activity 的可能性取决于当时 Activity 的状态。Activity 状态和从内存中弹出 会更详细地介绍状态与弹出漏洞之间的关系。

根据 Activity 的复杂程度,您可能不需要实现所有生命周期方法。但是,请务必了解每个方法,并实现能够确保应用按用户预期方式运行的方法,这非常重要。

在下一部分中,本文档将详细介绍用于处理状态间转换的回调。

生命周期回调

本部分介绍 Activity 生命周期中所用回调方法的相关概念及实现信息。

某些操作(例如调用 setContentView())属于 Activity 生命周期方法本身。不过,用于实现依赖组件操作的代码应放在组件本身内。为此,您必须使依赖组件具有生命周期感知能力。请参阅使用生命周期感知型组件处理生命周期,了解如何让您的依赖组件获得生命周期感知能力。

onCreate()

您必须实现此回调,它会在系统首次创建 Activity 时触发。Activity 会在创建后进入“已创建”状态。在 onCreate() 方法中,您需执行基本应用启动逻辑,该逻辑在 Activity 的整个生命周期中只应发生一次。例如,onCreate() 的实现可能会将数据绑定到列表,将 Activity 与 ViewModel 相关联,并实例化某些类作用域变量。此方法会接收 savedInstanceState 参数,后者是包含 Activity 先前保存状态的 Bundle 对象。如果 Activity 此前未曾存在,Bundle 对象的值为 null。

如果您有一个生命周期感知型组件与您的 Activity 生命周期相关联,该组件将收到 ON_CREATE 事件。系统将调用带有 @OnLifecycleEvent 注释的方法,以使您的生命周期感知型组件可以执行已创建状态所需的任何设置代码。

onCreate() 方法的以下示例显示执行 Activity 某些基本设置的一些代码,例如声明界面(在 XML 布局文件中定义)、定义成员变量,以及配置某些界面。在本示例中,系统通过将文件的资源 ID R.layout.main_activity 传递给 setContentView() 来指定 XML 布局文件。

onStart()

当 Activity 进入“已开始”状态时,系统会调用此回调。onStart() 调用使 Activity 对用户可见,因为应用会为 Activity 进入前台并支持互动做准备。例如,应用通过此方法来初始化维护界面的代码。

当 Activity 进入已开始状态时,与 Activity 生命周期相关联的所有生命周期感知型组件都将收到 ON_START 事件。

onStart() 方法会非常快速地完成,并且与“已创建”状态一样,Activity 不会一直处于“已开始”状态。一旦此回调结束,Activity 便会进入“已恢复”状态,系统将调用 onResume() 方法。

onResume()

Activity 会在进入“已恢复”状态时来到前台,然后系统调用 onResume() 回调。这是应用与用户互动的状态。应用会一直保持这种状态,直到某些事件发生,让焦点远离应用。此类事件包括接到来电、用户导航到另一个 Activity,或设备屏幕关闭。

当 Activity 进入已恢复状态时,与 Activity 生命周期相关联的所有生命周期感知型组件都将收到 ON_RESUME 事件。这时,生命周期组件可以启用在组件可见且位于前台时需要运行的任何功能,例如启动相机预览。

当发生中断事件时,Activity 进入“已暂停”状态,系统调用 onPause() 回调。

如果 Activity 从“已暂停”状态返回“已恢复”状态,系统将再次调用 onResume() 方法。因此,您应实现 onResume(),以初始化在 onPause() 期间释放的组件,并执行每次 Activity 进入“已恢复”状态时必须完成的任何其他初始化操作。

onPause()

系统将此方法视为用户将要离开您的 Activity 的第一个标志(尽管这并不总是意味着 Activity 会被销毁);此方法表示 Activity 不再位于前台(尽管在用户处于多窗口模式时 Activity 仍然可见)。使用 onPause() 方法暂停或调整当 Activity 处于“已暂停”状态时不应继续(或应有节制地继续)的操作,以及您希望很快恢复的操作。Activity 进入此状态的原因有很多。例如:

  • 如 onResume() 部分所述,某个事件会中断应用执行。这是最常见的情况。
  • 在 Android 7.0(API 级别 24)或更高版本中,有多个应用在多窗口模式下运行。无论何时,都只有一个应用(窗口)可以拥有焦点,因此系统会暂停所有其他应用。
  • 有新的半透明 Activity(例如对话框)处于开启状态。只要 Activity 仍然部分可见但并未处于焦点之中,它便会一直暂停。
onStop()

如果您的 Activity 不再对用户可见,说明其已进入“已停止”状态,因此系统将调用 onStop() 回调。例如,当新启动的 Activity 覆盖整个屏幕时,可能会发生这种情况。如果 Activity 已结束运行并即将终止,系统还可以调用 onStop()。

当 Activity 进入已停止状态时,与 Activity 生命周期相关联的所有生命周期感知型组件都将收到 ON_STOP 事件。这时,生命周期组件可以停止在组件未显示在屏幕上时无需运行的任何功能。

在 onStop() 方法中,应用应释放或调整在应用对用户不可见时的无用资源。例如,应用可以暂停动画效果,或从精确位置更新切换到粗略位置更新。使用 onStop() 而非 onPause() 可确保与界面相关的工作继续进行,即使用户在多窗口模式下查看您的 Activity 也能如此。

您还应使用 onStop() 执行 CPU 相对密集的关闭操作。例如,如果您无法找到更合适的时机来将信息保存到数据库,可以在 onStop() 期间执行此操作。

作者 east
Android, Harmony 6月 9,2021

鸿蒙Harmony和Android应用组件对比

在Android开发中,有我们熟知的四大组件,
activity、service、content provider、broadcast receiver。 而在harmony中,则抽象为 Ability ,

分为FA(Feature Ability)和PA(Particle Ability)两种类型:

  • FA支持Page Ability:Page模板是FA唯一支持的模板,用于提供与用户交互的能力。(类同于Android的Activity)
  • PA支持Service Ability和Data Ability:Service模板用于提供后台运行任务的能力;Data模板用于对外部提供统一的数据访问抽象。(
    Service模板 类似于Android 的Service,
    Data模板 类似于Android的
    content provider )

在Android开发中,用Broadcast Receiver并不是非常多,更多是用EventBus等消息框架,在harmony设计中,也是借鉴EventsBus等消息框架的思想。

HarmonyOS通过CES(Common Event Service,公共事件服务)为应用程序提供订阅、发布、退订公共事件的能力,通过ANS(Advanced Notification Service,即通知增强服务)系统服务来为应用程序提供发布通知的能力。

  • 公共事件可分为系统公共事件和自定义公共事件。
    • 系统公共事件:系统将收集到的事件信息,根据系统策略发送给订阅该事件的用户程序。 例如:用户可感知亮灭屏事件,系统关键服务发布的系统事件(例如:USB插拔,网络连接,系统升级等)。
    • 自定义公共事件:应用自定义一些公共事件用来处理业务逻辑。
  • 通知提供应用的即时消息或通信消息,用户可以直接删除或点击通知触发进一步的操作。
  • IntentAgent封装了一个指定行为的Intent,可以通过IntentAgent启动Ability和发布公共事件。

应用如果需要接收公共事件,需要订阅相应的事件。

约束与限制

公共事件的约束与限制

  • 目前公共事件仅支持动态订阅。部分系统事件需要具有指定的权限,具体的权限见API参考。
  • 目前公共事件订阅不支持多用户。
  • ThreadMode表示线程模型,目前仅支持HANDLER模式,即在当前UI线程上执行回调函数。
  • deviceId用来指定订阅本地公共事件还是远端公共事件。deviceId为null、空字符串或本地设备deviceId时,表示订阅本地公共事件,否则表示订阅远端公共事件。

通知的约束与限制

  • 通知目前支持六种样式:普通文本、长文本、图片、社交、多行文本和媒体样式。创建通知时必须包含一种样式。
  • 通知支持快捷回复。

IntentAgent的限制

使用IntentAgent启动Ability时,Intent必须指定Ability的包名和类名。

作者 east
Android, Harmony 6月 9,2021

鸿蒙Harmony和Android应用权限管理 对比

早期的Android对权限管理不严格,导致了一些app获取各种超过需要的权限,甚至做一些损害用户的行为,例如后台自动下载,监听短信内容,自动打电话等等。后来google认识这些问题,后期版本对权限管理严格了很多。Harmony作为后起之秀,自然在设计之初就考虑了这个问题。

Harmony应用权限管理 :

HarmonyOS中所有的应用均在应用沙盒内运行。默认情况下,应用只能访问有限的系统资源,系统负责管理应用对资源的访问权限。

应用权限管理是由接口提供方(Ability)、接口使用方(应用)、系统(包括云侧和端侧)以及用户等多方共同参与的整个流程,保证受限接口是在约定好的规则下被正常使用,避免接口被滥用而导致用户、应用和设备受损。

本节重点介绍应用权限管理的基本思想。有关权限使用的详细信息,请参阅权限。

权限声明
  • 应用需要在config.json中使用“reqPermissions”属性对需要的权限逐个进行声明。
  • 若使用到的三方库也涉及权限使用,也需统一在应用的config.json中逐个声明。
  • 没有在config.json中声明的权限,应用就无法获得此权限的授权。
动态申请敏感权限

动态申请敏感权限基于用户可知可控的原则,需要应用在运行时主动调用系统动态申请权限的接口,系统弹框由用户授权,用户结合应用运行场景的上下文,识别出应用申请相应敏感权限的合理性,从而做出正确的选择。

即使用户向应用授予了请求的权限,应用在调用受此权限管控的接口前,也应该先检查自己有无此权限,而不能把之前授予的状态持久化,因为用户在动态授予后还可以通过设置取消应用的权限。

有关于应用动态申请敏感权限的详细信息,请参阅动态申请权限。

自定义权限

HarmonyOS为了保证应用对外提供的接口不被恶意调用,需要对调用接口的调用者进行鉴权。

大多情况下,系统已定义的权限满足了应用的基本需要,若有特殊的访问控制需要,应用可在config.json中以”defPermissions”: []属性来定义新的权限,并通过“availableScope”和“grantMode”两个属性分别确定权限的开放范围和授权方式,使得权限定义更加灵活且易于理解。有关HarmonyOS权限开放范围和授权方式详细的描述,请参阅权限授予方式字段说明和权限限制范围字段说明。

为了避免应用自定义新权限出现重名的情况,建议应用对新权限的命名以包名的前两个字段开头,这样可以防止不同开发者的应用间出现自定义权限重名的情况。

权限保护方法
  • 保护Ability:通过在config.json里对应的Ability中配置”permissions”: [“权限名“]属性,即可实现保护整个Ability的目的,无指定权限的应用不能访问此Ability。
  • 保护API:若Ability对外提供的数据或能力有多种,且开放范围或保护级别也不同,可以针对不同的数据或能力在接口代码实现中通过verifyPermission(String permissionName, int pid, int uid)来对uid标识的调用者进行鉴权。
权限使用原则
  • 权限申请最小化。跟用户提供的功能无关的权限,不要申请;尽量采用其他无需权限的操作来实现相应功能(如:通过intent拉起系统UI界面由用户交互、应用自己生成uuid代替设备ID等)。
  • 权限申请完整。应用所需权限(包括应用调用到的三方库依赖的权限)都要逐个在应用的config.json中按格式声明。
  • 满足用户可知。应用申请的敏感权限的目的需要真实准确告知用户。
  • 权限就近申请。应用在用户触发相关业务功能时,就近提示用户授予实现此功能所需的权限。
  • 权限不扩散。在用户未授权的情况下,不允许提供给其他应用使用。
  • 应用自定义权限防止重名。建议以包名为前缀来命名权限,防止跟系统定义的权限重名。

Android应用权限管理 :

Android 将权限分为不同的类型,包括安装时权限、运行时权限和特殊权限。每种权限类型都指明了当系统授予应用该权限后,应用可以访问的受限数据范围以及应用可以执行的受限操作范围。

安装时权限
左图所示为某个应用的安装时权限列表。右图显示了一个弹出式对话框,其中包含 2 个选项:允许和拒绝。
图 2. 某应用商店中显示的某个应用的安装时权限列表。

安装时权限授予应用对受限数据的受限访问权限,并允许应用执行对系统或其他应用只有最低影响的受限操作。如果您在应用中声明了安装时权限,系统会在用户安装您的应用时自动授予应用相应权限。应用商店会在用户查看应用详情页面时向其显示安装时权限通知,如图 2 所示。

Android 提供多个安装时权限子类型,包括普通权限和签名权限。

普通权限

此类权限允许访问超出应用沙盒的数据和执行超出应用沙盒的操作。但是,这些数据和操作对用户隐私及对其他应用的操作带来的风险非常小。

系统会为普通权限分配“normal”保护级别,如权限 API 参考文档页面中所示。

签名权限

当应用声明了其他应用已定义的签名权限时,如果两个应用使用同一证书进行签名,系统会在安装时向前者授予该权限。否则,系统无法向前者授予该权限。注意:有些签名权限不适合第三方应用使用。

系统会为签名权限分配“signature”保护级别,如权限 API 参考文档页面中所示。

运行时权限
一个弹出式对话框,其中包含 2 个选项:允许和拒绝。
图 3. 当应用请求运行时权限时显示的系统权限提示。

运行时权限也称为危险权限,此类权限授予应用对受限数据的额外访问权限,并允许应用执行对系统和其他应用具有更严重影响的受限操作。因此,您需要先在应用中请求运行时权限,然后才能访问受限数据或执行受限操作。当应用请求运行时权限时,系统会显示运行时权限提示,如图 3 所示。

许多运行时权限会访问用户私有数据,这是一种特殊的受限数据,其中包含可能比较敏感的信息。例如,位置信息和联系信息就属于用户私有数据。

系统会为运行时权限分配“dangerous”保护级别,如权限 API 参考文档页面中所示。

特殊权限

特殊权限与特定的应用操作相对应。只有平台和原始设备制造商 (OEM) 可以定义特殊权限。此外,如果平台和 OEM 想要防止有人执行功能特别强大的操作(例如通过其他应用绘图),通常会定义特殊权限。

系统设置中的特殊应用访问权限页面包含一组用户可切换的操作。其中的许多操作都以特殊权限的形式实现。

每项特殊权限都有自己的实现细节。如需查看使用每项特殊权限的说明,请访问权限 API 参考文档页面。系统会为特殊权限分配“appop”保护级别。

最佳做法

应用权限基于系统安全功能,并有助于 Android 支持与用户隐私相关的以下目标:

  • 控制:用户可以控制他们与应用分享的数据。
  • 透明度:用户了解应用使用了哪些数据以及应用为何访问相关数据。
  • 数据最小化:应用仅访问和使用用户调用的特定任务或操作所需的数据。

本部分将介绍一组在应用中有效使用权限的核心最佳做法。如需详细了解如何在 Android 中使用权限,请访问应用权限最佳做法页面。

请求最少数量的权限

当用户在应用中请求执行特定操作时,应用应当只请求完成该操作所需的权限。根据您使用权限的方式,您可以通过其他方式实现应用的用例,而无需依赖于访问敏感信息。

将运行时权限与特定操作相关联

尽可能往后推迟到在应用的用例流程中请求权限。例如,如果应用允许用户向他人发送语音消息,请等到用户已导航到消息屏幕并已按下发送语音消息按钮后再请求权限。待用户按下该按钮后,应用再请求麦克风使用权限。

考虑应用的依赖项

添加某个库时,您也会继承它的权限要求。请注意每个依赖项所需的权限以及这些权限的用途。

公开透明

请求权限时,请清晰说明您要访问的内容以及访问原因,以便用户可以做出明智的决策。

以显式方式访问系统

当您访问敏感数据或硬件(例如相机或麦克风)时,请在应用中持续提供指示。此提醒可帮助用户确切了解应用何时会访问受限数据或执行受限操作。

系统组件中的权限

权限不仅仅用于请求系统功能。应用的系统组件可以限制哪些其他应用可以与您的应用交互,如介绍如何限制与其他应用的交互的页面中所述。

对比说明:

对于敏感权限,无论是Harmony还是新版本的Android都是需要动态申请。
Harmony在config.json中以”defPermissions”来描述 ,Android是在AndroidManifest.xml中描述。而且相对于Android,Harmony权限控制更严,通讯录不给随便读取和修改了。

Harmony受限开放的权限

受限开放的权限通常是不允许三方应用申请的。如果有特殊场景需要使用,请提供相关申请材料到应用市场申请相应权限证书。如果应用未申请相应的权限证书,却试图在config.json文件中声明此类权限,将会导致应用安装失败。另外,由于此类权限涉及到用户敏感数据或危险操作,当应用申请到权限证书后,还需按照动态申请权限的流程向用户申请授权。

权限分类名称典型场景权限名说明
通讯录社交、通讯、备份和恢复用户信息、电话拦截等ohos.permission.READ_CONTACTS允许应用读取联系人数据。
通讯、备份和恢复用户信息等ohos.permission.WRITE_CONTACTS允许应用添加、移除和更改联系人数据。
作者 east
Android, Harmony 6月 8,2021

鸿蒙Harmony和Android共享数据对比

在现在多应用互动,多屏互动的时代,共享数据在日常应用中非常多,harmony和android共享数据的机制也比较类似。

Harmony共享数据:

harmony使用Data模板的Ability(以下简称“Data”)有助于应用管理其自身和其他应用存储数据的访问,并提供与其他应用共享数据的方法。Data既可用于同设备不同应用的数据共享,也支持跨设备不同应用的数据共享。

数据的存放形式多样,可以是数据库,也可以是磁盘上的文件。Data对外提供对数据的增、删、改、查,以及打开文件等接口,这些接口的具体实现由开发者提供。

URI介绍

Data的提供方和使用方都通过URI(Uniform Resource Identifier)来标识一个具体的数据,例如数据库中的某个表或磁盘上的某个文件。HarmonyOS的URI仍基于URI通用标准,格式如下:

  • scheme:协议方案名,固定为“dataability”,代表Data Ability所使用的协议类型。
  • authority:设备ID。如果为跨设备场景,则为目标设备的ID;如果为本地设备场景,则不需要填写。
  • path:资源的路径信息,代表特定资源的位置信息。
  • query:查询参数。
  • fragment:可以用于指示要访问的子资源。

URI示例:

  • 跨设备场景:dataability://device_id/com.domainname.dataability.persondata/person/10
  • 本地设备:dataability:///com.domainname.dataability.persondata/person/10

Android共享数据:

在Android中有很多的内容提供者,包括内置的、自己编写的和他人编写的。那么,如何识别和找到需要的内容提供者呢?Android提供了一种叫做Content URI技术,通过它可以指定一个内容提供者,访问内容提供者后面的资源。

Android中的Content URI就是Android平台的内容资源定位符,与Web上的应用一样,Android平台上的Content URI定义的时候也要全球唯一,因此它的命名可以借助所在应用的包名命名,但是要注意这种命名方式不是必须的,而是推荐的命名方式。因为一个应用的包名是唯一的,不会重复的。

(1)协议名字。content是URI协议名字,content表明这个URI是一个内容提供器。类似于http://www.acme.com/icons/logo.gif中的HTTP,协议名不可以修改。

(2)权限。URI的权限部分,用来标识内容提供者,它的命名必须确保唯一性,类似于http://www.acme.com/icons/logo.gif中的www.acme.com部分。

(3)路径。用来判断请求数据类型的路径。在Content URI中可以有0个或多个路径。类似http://www.acme.com/icons/logo.gif中的icons部分。

(4)id。被指定的特定记录的id,如果没有指定特定id记录,这个部分可以省略,类似于http://www.acme.com/icons/logo.gif中的logo.gif部分。

对比说明:

从上面看,harmony和android共享数据定义的协议URI非常类似,harmony多了一个填写设备ID可用于跨屏。

作者 east

上一 1 2 3 4 … 7 下一个

关注公众号“大模型全栈程序员”回复“小程序”获取1000个小程序打包源码。回复”chatgpt”获取免注册可用chatgpt。回复“大数据”获取多本大数据电子书

标签

AIGC AI创作 bert chatgpt github GPT-3 gpt3 GTP-3 hive mysql O2O tensorflow UI控件 不含后台 交流 共享经济 出行 图像 地图定位 外卖 多媒体 娱乐 小程序 布局 带后台完整项目 开源项目 搜索 支付 效率 教育 日历 机器学习 深度学习 物流 用户系统 电商 画图 画布(canvas) 社交 签到 联网 读书 资讯 阅读 预订

官方QQ群

小程序开发群:74052405

大数据开发群: 952493060

近期文章

  • 详解Python当中的pip常用命令
  • AUTOSAR如何在多个供应商交付的配置中避免ARXML不兼容?
  • C++thread pool(线程池)设计应关注哪些扩展性问题?
  • 各类MCAL(Microcontroller Abstraction Layer)如何与AUTOSAR工具链解耦?
  • 如何设计AUTOSAR中的“域控制器”以支持未来扩展?
  • C++ 中避免悬挂引用的企业策略有哪些?
  • 嵌入式电机:如何在低速和高负载状态下保持FOC(Field-Oriented Control)算法的电流控制稳定?
  • C++如何在插件式架构中使用反射实现模块隔离?
  • C++如何追踪内存泄漏(valgrind/ASan等)并定位到业务代码?
  • C++大型系统中如何组织头文件和依赖树?

文章归档

  • 2025年6月
  • 2025年5月
  • 2025年4月
  • 2025年3月
  • 2025年2月
  • 2025年1月
  • 2024年12月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年6月
  • 2024年5月
  • 2024年4月
  • 2024年3月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年1月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年7月
  • 2018年6月

分类目录

  • Android (73)
  • bug清单 (79)
  • C++ (34)
  • Fuchsia (15)
  • php (4)
  • python (43)
  • sklearn (1)
  • 云计算 (20)
  • 人工智能 (61)
    • chatgpt (21)
      • 提示词 (6)
    • Keras (1)
    • Tensorflow (3)
    • 大模型 (1)
    • 智能体 (4)
    • 深度学习 (14)
  • 储能 (44)
  • 前端 (4)
  • 大数据开发 (488)
    • CDH (6)
    • datax (4)
    • doris (30)
    • Elasticsearch (15)
    • Flink (78)
    • flume (7)
    • Hadoop (19)
    • Hbase (23)
    • Hive (40)
    • Impala (2)
    • Java (71)
    • Kafka (10)
    • neo4j (5)
    • shardingsphere (6)
    • solr (5)
    • Spark (99)
    • spring (11)
    • 数据仓库 (9)
    • 数据挖掘 (7)
    • 海豚调度器 (10)
    • 运维 (34)
      • Docker (3)
  • 小游戏代码 (1)
  • 小程序代码 (139)
    • O2O (16)
    • UI控件 (5)
    • 互联网类 (23)
    • 企业类 (6)
    • 地图定位 (9)
    • 多媒体 (6)
    • 工具类 (25)
    • 电商类 (22)
    • 社交 (7)
    • 行业软件 (7)
    • 资讯读书 (11)
  • 嵌入式 (70)
    • autosar (63)
    • RTOS (1)
    • 总线 (1)
  • 开发博客 (16)
    • Harmony (9)
  • 技术架构 (6)
  • 数据库 (32)
    • mongodb (1)
    • mysql (13)
    • pgsql (2)
    • redis (1)
    • tdengine (4)
  • 未分类 (6)
  • 程序员网赚 (20)
    • 广告联盟 (3)
    • 私域流量 (5)
    • 自媒体 (5)
  • 量化投资 (4)
  • 面试 (14)

功能

  • 登录
  • 文章RSS
  • 评论RSS
  • WordPress.org

All Rights Reserved by Gitweixin.本站收集网友上传代码, 如有侵犯版权,请发邮件联系yiyuyos@gmail.com删除.