Android:Android 应用权限详解

简介: 这篇文章为大家系统的梳理一下 Android 权限相关的知识,在日常开发中,我们都用过权限,但是对于权限的一些细节我们可能掌握的还不够全面,这篇文章会全面的为大家介绍权限相关的知识。

这篇文章为大家系统的梳理一下 Android 权限相关的知识,在日常开发中,我们都用过权限,但是对于权限的一些细节我们可能掌握的还不够全面,这篇文章会全面的为大家介绍权限相关的知识。当然,本篇文章依然是参考了 Google 的官方文档:应用权限

本文目录

目录

一、认识 Android 权限

(一)Android 系统为什么需要权限?

Android 系统设置权限的目的是保护 Android 用户的隐私。对于用户的敏感数据 Android 应用程序必须向用户申请授权后才能访问(如联系人和短信),另外还包括某些系统功能(如摄像头、麦克风)的权限。根据功能的不同,系统可能会自动授予权限或提示用户批准请求。Android 安全架构的一个核心设计要点是,在默认情况下,没有应用程序可以执行任何可能对其他应用程序、操作系统或用户造成不利影响的操作。这包括读取或写入用户的私人数据(如联系人或电子邮件)、读取或写入另一个应用程序的文件、执行网络访问等等。

(二)权限分类

权限分为几个保护级别。保护级别影响是否需要运行时权限请求:

  1. Normal permissions 正常权限
  2. Signature permissions 签名权限
  3. Dangerous permissions 危险权限

需要我们了解的是正常权限和危险权限。

1.正常权限

正常的权限覆盖了应用程序需要访问沙箱之外的数据或资源的区域,但这些区域对用户隐私或其他应用程序的操作几乎没有风险。例如,设置时区的权限是正常的权限。
如果应用程序在它的清单中声明它需要一个正常的权限,系统会在安装时自动授予该权限。系统不提示用户授予正常权限,用户也不能撤销这些权限。

  • ACCESS_LOCATION_EXTRA_COMMANDS
  • ACCESS_NETWORK_STATE
  • ACCESS_NOTIFICATION_POLICY
  • ACCESS_WIFI_STATE
  • BLUETOOTH
  • BLUETOOTH_ADMIN
  • BROADCAST_STICKY
  • CHANGE_NETWORK_STATE
  • CHANGE_WIFI_MULTICAST_STATE
  • CHANGE_WIFI_STATE
  • DISABLE_KEYGUARD
  • EXPAND_STATUS_BAR
  • GET_PACKAGE_SIZE
  • INSTALL_SHORTCUT
  • INTERNET
  • KILL_BACKGROUND_PROCESSES
  • MODIFY_AUDIO_SETTINGS
  • NFC
  • READ_SYNC_SETTINGS
  • READ_SYNC_STATS
  • RECEIVE_BOOT_COMPLETED
  • REORDER_TASKS
  • REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
  • REQUEST_INSTALL_PACKAGES
  • SET_ALARM
  • SET_TIME_ZONE
  • SET_WALLPAPER
  • SET_WALLPAPER_HINTS
  • TRANSMIT_IR
  • UNINSTALL_SHORTCUT
  • USE_FINGERPRINT
  • VIBRATE
  • WAKE_LOCK
  • WRITE_SYNC_SETTINGS

2.危险权限

危险权限包括应用程序需要涉及用户私人信息的数据或资源的区域,也包括可能影响用户存储的数据或其他应用程序的操作的区域。例如,读取用户的联系人是一种危险的权限。如果一个应用程序声明它需要一个危险的权限,用户必须显式地授予该应用程序权限。在用户批准该权限之前,应用程序不能提供依赖于该权限的功能。
要使用危险的权限,应用程序必须在运行时提示用户授予权限。

(三)如何声明一个权限?

应用程序必须通过在清单文件(AndroidManifest.xml)中使用 <uses-permission> 标记来公布它需要的权限。例如声明网络访问权限:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.myapp">
    //声明网络访问权限
    <uses-permission android:name="android.permission.INTERNET"/>

    <application ...>
        ...
    </application>
</manifest>

如果在应用程序的清单文件中列出的是正常的权限(即不会对用户隐私或设备操作造成太大风险的权限),系统会自动将这些权限授予给应用程序。

如果在应用程序的清单中列出的是危险的权限(即可能影响用户隐私或设备正常操作的权限),则必须经过用户的同意才能授权相应的权限。

(四)Android 不同版本对危险权限的处理方式

Android 请求用户授予危险权限的方式取决于用户设备上运行的 Android 版本,以及我们在应用中设置的 targetSdkVersion 。主要有两种处理方式:

  • 运行时请求:Android 6.0 以及更高的版本
  • 安装时请求:Android 5.1.1 以及更低的版本
  1. 运行时请求:

如果手机 Android 系统的版本是 6.0 (API级别23) 或者更高,而应用程序的 targetSdkVersion 是 23 或者更高,用户在安装时不会收到任何应用程序权限通知。应用程序必须要求用户在运行时授予危险的权限。当应用程序请求权限时,用户会看到一个系统对话框,告诉用户应用程序试图访问哪个权限组。对话框包含一个拒绝和允许按钮。

如果用户拒绝权限请求,那么下一次应用程序请求该权限时,对话框将包含一个复选框,选中该复选框后,用户不会再收到权限申请提示。

下面通过申请拍照权限为例:

运行时请求
可以看到,第一次弹框时选择拒绝,第二次弹框出现了一个“不再询问”的复选框,勾选以后,再次拒绝,则之后都不会再弹出权限申请的对话框。

假如用户选择了“允许”,也不能表示应用就会一直拥有该权限。用户还可以进入系统设置页面,将之前那授予的权限关闭掉,因此,我们在开发中必须在运行时去检查和申请相应的权限,以防止在运行时出现 SecurityException 的错误,导致应用奔溃。

  1. 安装时请求:

如果手机 Android 系统的版本是 5.1.1 (API级别22) 或者更低,而应用程序的 targetSdkVersion 是 22 或者更低,系统会自动要求用户在安装时为应用程序授予所有危险的权限。

安装时请求
如果用户单击 Accept,应用程序请求的所有权限都将被授予。如果用户拒绝权限请求,系统将取消应用程序的安装。如果应用程序更新需要额外的权限,用户在更新应用程序之前会被提示接受这些新的权限。

(五)特殊的两个权限

有两个权限的行为不像正常权限和危险权限:SYSTEM_ALERT_WINDOWWRITE_SETTINGS

这是两个特别敏感的权限,所以大多数应用程序不应该使用它们。如果应用程序需要这些权限之一,它必须在清单中声明该权限,并发送一个意图请求用户的授权。系统通过向用户显示详细的管理屏幕来响应这个意图。

以申请 SYSTEM_ALERT_WINDOW 为例:

step 1:首先在清单文件中声明权限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

step 2:申请权限(6.0 及其以上版本)

//在 6.0 以前的系统版本,悬浮窗权限是默认开启的,直接使用即可。 
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
   
   
    if (!Settings.canDrawOverlays(context)) {
   
   
        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
        startActivity(intent);
        return;
    }
}

请求悬浮窗权限

(六)权限组

Android 系统对所有的危险权限进行了分组,称为 权限组

权限组 权限
CALENDAR READ_CALENDAR
WRITE_CALENDAR
CAMERA CAMERA
CONTACTS READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
LOCATION ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
MICROPHONE RECORD_AUDIO
PHONE READ_PHONE_STATE
CALL_PHONE
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
SENSORS BODY_SENSORS
SMS SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
STORAGE READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE

如果手机 Android 系统的版本是 6.0 (API级别23) 或者更高,而应用程序的 targetSdkVersion 是 23 或者更高,则当应用程序请求危险权限时,系统会有如下行为:

如果应用程序当前在权限组中没有任何权限,则系统向描述应用程序希望访问的权限组的用户显示权限请求对话框。对话框没有描述该组中的特定权限。例如,如果一个应用程序请求READ_CONTACTS权限,系统对话框只告诉应用程序需要访问设备的联系人。如果用户给予批准,系统只会给应用程序它所请求的权限。
如果应用程序已经在同一权限组中被授予了另一个危险权限,系统会立即授予该权限,而不与用户进行任何交互。例如,如果一个应用程序之前请求并被授予了READ_CONTACTS权限,然后它请求WRITE_CONTACTS,系统立即授予该权限,而不向用户显示权限对话框。

上面是官方的原话,简而言之就是:属于同一组的危险权限将自动合并授予,用户授予应用某个权限组的权限,则应用将获得该权限组下的所有权限(前提是相关权限在 AndroidManifest.xml 中有声明)。

然而事实真的如此吗?我们来试验一下属于同一个权限组下的 READ_CONTACTS 权限和 WRITE_CONTACTS 权限。按照官方的说法,如果我先授权了 READ_CONTACTS 权限,那么 WRITE_CONTACTS 权限会被自动授予,我们来看看实际运行的效果:
权限组
可以看到,当我们先授予了 READ_CONTACTS 权限后,再去申请 WRITE_CONTACTS 权限时,依旧弹出了对话框让用户授权,这明显和官方文档说明的不一致。但是同时官方建议我们,不要将应用程序的逻辑建立在这些权限组的结构上,因为在未来的版本中,可能会将一个特定的权限从一个组移动到另一个组,因此,我们的代码逻辑不应该依赖权限组,而是应该显式地请求它需要的每个权限,即使用户已经在同一组中授予了另一个权限。

二、如何请求权限

每款 Android 应用都在访问受限的沙盒中运行。如果应用需要使用其自己的沙盒外的资源或信息,则必须请求相应权限。 要声明应用需要某项权限,可以在应用清单中列出该权限,然后在运行时请求用户批准每项权限(适用于 Android 6.0 及更高版本)。

(一)向清单文件添加权限

无论应用需要什么权限,都需要在清单文件中对权限进行声明。系统会根据声明权限的敏感程度采取不同的操作。有些权限被视为“常规”权限,系统会在安装应用时立即授予这些权限。还有些则被视为“危险”权限,需要用户明确授予相应访问权限。

(二)检查权限

如果应用需要一项危险权限,那么每次执行需要该权限的操作时,都必须检查自己是否具有该权限。从 Android 6.0(API 级别 23)开始,用户可随时从任何应用撤消权限,即使应用以较低的 API 级别为目标平台也是如此。因此,即使应用昨天使用了相机,也不能认为它今天仍具有该权限。

要检查应用是否具有某项权限,请调用 ContextCompat.checkSelfPermission() 方法。例如,以下代码段展示了如何检查 Activity 是否具有向日历写入数据的权限:

    if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
            != PackageManager.PERMISSION_GRANTED) {
   
   
        // Permission is not granted
    }

如果应用具有此权限,该方法将返回 PERMISSION_GRANTED,并且应用可以继续操作。如果应用不具备此权限,该方法将返回 PERMISSION_DENIED,且应用必须明确要求用户授予权限。

(三)请求权限

当应用从 checkSelfPermission() 收到 PERMISSION_DENIED 时,需要提示用户授予该权限。Android 提供了几种可用来请求权限的方法(如 requestPermissions()),如下面的代码段所示。调用这些方法时,会显示一个无法自定义的标准 Android 对话框。

    // Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(thisActivity,
            Manifest.permission.READ_CONTACTS)
            != PackageManager.PERMISSION_GRANTED) {
   
   

        // Permission is not granted
        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                Manifest.permission.READ_CONTACTS)) {
   
   
            // Show an explanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.
        } else {
   
   
            // No explanation needed; request the permission
            ActivityCompat.requestPermissions(thisActivity,
                    new String[]{
   
   Manifest.permission.READ_CONTACTS},
                    MY_PERMISSIONS_REQUEST_READ_CONTACTS);

            // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    } else {
   
   
        // Permission has already been granted
    }

在某些情况下,需要帮助用户理解为什么应用需要某项权限。例如,如果用户启动一款摄影应用,用户或许不会对该应用请求使用相机的权限感到惊讶,但用户可能不理解为什么该应用想要访问用户的位置或联系人。在应用请求权限之前,可以向用户提供解释。一种比较好的做法是在用户之前拒绝过该权限请求的情况下提供解释。我们通过调用 shouldShowRequestPermissionRationale() 方法来实现。如果用户之前拒绝了该请求,该方法将返回 true。如果用户之前拒绝了该权限并且选中了权限请求对话框中的不再询问选项,或者如果设备政策禁止该权限,该方法将返回 false(注意,如果用户拒绝了该权限,并且勾选了“不再询问”,即使在返回false的逻辑中调用了requestPermissions方法,系统也不会再弹出选择框)。

(四)处理权限请求响应

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
   
   
        switch (requestCode) {
   
   
            case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
   
   
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
   
   
                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
                } else {
   
   
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request.
        }
    }

三、自定义权限

(一)背景

Android 是一个特权分离的操作系统,其中每个应用程序都使用一个唯一的系统标识(Linux 用户 ID 和 组 ID)运行。系统也被称不同的部分,每个部分都有自己的标识。因此,Linux 将应用程序彼此隔离,并与系统隔离。应用程序可以自定义权限来提供给其他应用程序访问自己的功能。

(二)如何自定义权限

要自定义权限,可以在 AndroidManifest.xml 中使用 <permission> 标签来声明。

<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.myapp" >

    <permission
      android:name="com.example.myapp.permission.DEADLY_ACTIVITY"
      android:label="@string/permlab_deadlyActivity"
      android:description="@string/permdesc_deadlyActivity"
      android:permissionGroup="android.permission-group.COST_MONEY"
      android:protectionLevel="dangerous" />
    ...
</manifest>

属性解释:

  1. name:自定义权限的名字。如果其他 app 引用该权限需要填写这个名字。
  2. lable:标签,用于描述该权限保护的关键功能(尽量简短)。显示给用户的,它的值可是一个 string 数据。
  3. description:描述,比 label 更长的对权限的描述。值是通过 resource 文件中获取的,不能直接写 string 值。
  4. permissionGroup:权限组,可选属性。在大多数情况下,应该将其设置为一个标准系统组(android.Manifest.permission_group),尽管可以自己定义一个组。
  5. protectionLevel:保护级别,它是必须的属性。

下面我们来写一个具体的例子:我们在进程1中定义一个 Activity,并为该 Activity 设置访问权限,然后让进程2来访问它。

进程1:

AndroidManifest.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.chenyouyu.permissiondemo">

    //自定义的权限,权限级别为 normal
    <permission
        android:name="com.example.myapp.permission.SECOND_ACTIVITY"
        android:label="abc"
        android:description="@string/permdesc_SecondActivity"
        android:permissionGroup="android.permission-group.COST_MONEY"
        android:protectionLevel="normal" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        //为SecondActivity加上android:permission="com.example.myapp.permission.SECOND_ACTIVITY"
        <activity
            android:name=".SecondActivity"
            android:exported="true"
            android:permission="com.example.myapp.permission.SECOND_ACTIVITY">
            <intent-filter>
                <action android:name="com.cyy.jump" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        ......
</manifest>

进程2:

AndroidManifest.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.chenyouyu.permissiondemo2">
    //在AndroidManifest中声明权限
    <uses-permission android:name="com.example.myapp.permission.SECOND_ACTIVITY"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

MainActivity.java

Intent intent = new Intent();
intent.setAction("com.cyy.jump");
intent.addCategory(Intent.CATEGORY_DEFAULT);
if (intent.resolveActivity(getPackageManager()) != null) {
   
   
    startActivity(intent);
}

首先运行进程1,然后运行进程2。
自定义权限

(三)自定义权限注意点

1.两个应用声明了相同的权限

Android 不允许两个不同的应用定义一个相同名字的权限(除非这两个应用拥有相同的签名),所以在命名的时候,需要特别注意。拥有相同自定义权限的软件必须使用同样的签名,否则后一个程序无法安装。

2.和应用安装顺序的关系。

场景:App A中声明了权限PermissionA,App B中使用了权限PermissionA。

情况一:PermissionA的保护级别是normal或者dangerous
App B先安装,App A后安装,此时App B无法获取PermissionA的权限,从App B打开App A会报权限错误。
App A先安装,App B后安装,从App B打开App A一切正常。

情况二:PermissionA的保护级别是signature或者signatureOrSystem
App B先安装,App A后安装,如果App A和App B是相同的签名,那么App B可以获取到PermissionA的权限。如果App A和App B的签名不同,则App B获取不到PermissionA权限。即,对于相同签名的app来说,不论安装先后,只要是声明了权限,请求该权限的app就会获得该权限。

这也说明了对于具有相同签名的系统app来说,安装过程不会考虑权限依赖的情况。安装系统app时,按照某个顺序(例如名字排序,目录位置排序等)安装即可,等所有app安装完了,所有使用权限的app都会获得权限。

3.权限的获取以及版本兼容

Android6.0引入了动态权限,这个大家都知道了。前面说到的自定义的权限的安全级别android:protectionLevel会影响权限在Android6.0+系统的使用

android:protectionLevel="normal",不需要动态申请
android:protectionLevel="dangerous",需要动态申请

相关文章
|
10天前
|
IDE Java 开发工具
深入探索安卓应用开发:从环境搭建到第一个"Hello, World!"应用
本文将引导读者完成安卓应用开发的初步入门,包括安装必要的开发工具、配置开发环境、创建第一个简单的安卓项目,以及解释其背后的一些基本概念。通过一步步的指导和解释,本文旨在为安卓开发新手提供一个清晰、易懂的起点,帮助读者顺利地迈出安卓开发的第一步。
189 65
|
10天前
|
存储 Java Android开发
探索安卓应用开发:构建你的第一个"Hello World"应用
【9月更文挑战第24天】在本文中,我们将踏上一段激动人心的旅程,深入安卓应用开发的奥秘。通过一个简单而经典的“Hello World”项目,我们将解锁安卓应用开发的基础概念和步骤。无论你是编程新手还是希望扩展技能的老手,这篇文章都将为你提供一次实操体验。从搭建开发环境到运行你的应用,每一步都清晰易懂,确保你能顺利地迈出安卓开发的第一步。让我们开始吧,探索如何将一行简单的代码转变为一个功能齐全的安卓应用!
|
15天前
|
开发框架 搜索推荐 开发工具
打造个性化安卓应用:从零开始的Flutter之旅
【8月更文挑战第51天】本文是一篇面向初学者的Flutter入门教程,旨在通过简单易懂的语言和实际代码示例,引导读者步入跨平台移动应用开发的世界。文章首先介绍了Flutter的基本概念和优势,然后逐步展示了如何搭建开发环境、创建第一个Flutter应用,并实现了一个简单的待办事项列表。最后,文章探讨了Flutter在实现高性能和美观界面方面的潜力,鼓励读者发挥创意,探索更多可能。
65 15
|
5天前
|
监控 安全 Java
Kotlin 在公司上网监控中的安卓开发应用
在数字化办公环境中,公司对员工上网行为的监控日益重要。Kotlin 作为一种基于 JVM 的编程语言,具备简洁、安全、高效的特性,已成为安卓开发的首选语言之一。通过网络请求拦截,Kotlin 可实现网址监控、访问时间记录等功能,满足公司上网监控需求。其简洁性有助于快速构建强大的监控应用,并便于后续维护与扩展。因此,Kotlin 在安卓上网监控应用开发中展现出广阔前景。
9 1
|
19天前
|
搜索推荐 Java Android开发
打造个性化安卓应用:从设计到发布的全程指南
【9月更文挑战第15天】本篇文章将带领读者踏上一段激动人心的旅程,从构思一个独特的安卓应用想法开始,直至将其变为现实并成功发布。我们将一起探索如何捕捉灵感、设计界面、编写代码以及最终将应用推向市场。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供宝贵的洞见和实用的技巧,让你的应用在竞争激烈的市场中脱颖而出。
56 17
|
15天前
|
Java Android开发 UED
🧠Android多线程与异步编程实战!告别卡顿,让应用响应如丝般顺滑!🧵
在Android开发中,为应对复杂应用场景和繁重计算任务,多线程与异步编程成为保证UI流畅性的关键。本文将介绍Android中的多线程基础,包括Thread、Handler、Looper、AsyncTask及ExecutorService等,并通过示例代码展示其实用性。AsyncTask适用于简单后台操作,而ExecutorService则能更好地管理复杂并发任务。合理运用这些技术,可显著提升应用性能和用户体验,避免内存泄漏和线程安全问题,确保UI更新顺畅。
38 5
|
16天前
|
前端开发 Java 数据库
💡Android开发者必看!掌握这5大框架,轻松打造爆款应用不是梦!🏆
在Android开发领域,框架犹如指路明灯,助力开发者加速应用开发并提升品质。本文将介绍五大必备框架:Retrofit简化网络请求,Room优化数据库访问,MVVM架构提高代码可维护性,Dagger 2管理依赖注入,Jetpack Compose革新UI开发。掌握这些框架,助你在竞争激烈的市场中脱颖而出,打造爆款应用。
86 3
|
16天前
|
存储 API Android开发
"解锁Android权限迷宫:一场惊心动魄的动态权限请求之旅,让你的应用从平凡跃升至用户心尖的宠儿!"
随着Android系统的更新,权限管理成为应用开发的关键。尤其在Android 6.0(API 级别 23)后,动态权限请求机制的引入提升了用户隐私保护,要求开发者进行更精细的权限管理。
43 2
|
24天前
|
开发框架 Android开发 iOS开发
探索安卓与iOS开发的差异:构建未来应用的指南
在移动应用开发的广阔天地中,安卓与iOS两大平台各占半壁江山。本文将深入浅出地对比这两大操作系统的开发环境、工具和用户体验设计,揭示它们在编程语言、开发工具以及市场定位上的根本差异。我们将从开发者的视角出发,逐步剖析如何根据项目需求和目标受众选择适合的平台,同时探讨跨平台开发框架的利与弊,为那些立志于打造下一个热门应用的开发者提供一份实用的指南。
51 5
|
22天前
|
Android开发 开发者 Kotlin
告别AsyncTask:一招教你用Kotlin协程重构Android应用,流畅度飙升的秘密武器
【9月更文挑战第13天】随着Android应用复杂度的增加,有效管理异步任务成为关键。Kotlin协程提供了一种优雅的并发操作处理方式,使异步编程更简单直观。本文通过具体示例介绍如何使用Kotlin协程优化Android应用性能,包括网络数据加载和UI更新。首先需在`build.gradle`中添加coroutines依赖。接着,通过定义挂起函数执行网络请求,并在`ViewModel`中使用`viewModelScope`启动协程,结合`Dispatchers.Main`更新UI,避免内存泄漏。使用协程不仅简化代码,还提升了程序健壮性。
45 1
下一篇
无影云桌面