首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android 權限申請:為何不應嘗試暫停主線程及正確做法

     編輯:程式設計疑難解答

錯誤思路分析

用戶希望在用戶未響應權限彈窗時「暫停主線程」,待用戶點擊後繼續執行。這在 Android 中不可行且極其危險:

  • 主線程(UI 線程)負責繪製界面、分發觸摸事件、運行組件生命周期。阻塞超過 5 秒會觸發 ANR(Application Not Responding),2 秒以上用戶即感覺卡頓。
  • Thread.sleep()、wait()、CountDownLatch.await() 等均會阻塞主線程,導致界面凍結,權限彈窗無法顯示或響應,形成死鎖。

正確做法:異步回調模式

Android 6.0+ 動態權限機制本身就是異步的,應遵循「請求 → 回調 → 處理」流程:

1. Activity/Fragment 中請求權限

private static final int REQ_PERM = 100;

public void requestCameraPermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQ_PERM);
    } else {
        // 已授權,直接執行業務
        doCameraWork();
    }
}

2. 重寫 onRequestPermissionsResult 處理結果

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == REQ_PERM) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            doCameraWork(); // 用戶同意
        } else {
            // 用戶拒絕:提示說明、引導去設置頁、或降級處理
            showPermissionDeniedDialog();
        }
    }
}

3. 使用封裝庫簡化代碼(推薦)

如 PermissionsDispatcher、RxPermissions,支持鏈式調用、Kotlin 協程,自動處理「不再提示」邏輯。

常見誤區澄清

誤區正確認知
用 while 循環輪詢權限狀態阻塞主線程,導致 ANR,彈窗無法顯示
在子線程請求權限requestPermissions 必須在主線程調用,否則崩潰
以為權限彈窗是同步的彈窗由系統進程管理,回調異步觸發

總結

永遠不要嘗試阻塞 Android 主線程。權限申請天然是異步流程,請在 onRequestPermissionsResult 或封裝庫的回調中編寫後續業務邏輯。這才是健壯、用戶體驗良好的應用架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved