Android中MainActivity方法执行顺序异常及程序停滞问题咨询
问题分析与解决方案
嘿,我来帮你拆解这两个疑问,顺便给你提些代码优化的建议,让你的蓝牙扫描功能能正常跑起来~
一、为什么执行顺序会是onCreate() → askCoarsePermission() → onResume() → askBluetoothPermission()?
这其实完全符合Android的运行规则,并不是异常情况,核心原因是权限请求的异步特性:
- 当你在
onCreate()里调用askCoarsePermission(),里面的requestPermissions()是个异步方法——它只是向系统发起权限请求,不会傻等用户点击“允许”或“拒绝”,而是立即返回,所以onCreate()方法会顺利执行完。 - 当
onCreate()执行结束后,Activity的生命周期会自然推进到onResume()阶段,这就解释了为什么askCoarsePermission()之后直接走到了onResume(),进而触发了里面的askBluetoothPermission()。
二、为什么程序在askBluetoothPermission()处停滞?
因为askBluetoothPermission()里调用了startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), ...),这个Intent会唤起系统自带的蓝牙启用请求对话框:
- 此时你的Activity会被暂停(触发
onPause()),系统会一直等待用户在这个对话框上做出操作——要么点击“允许”开启蓝牙,要么点击“拒绝”放弃。 - 如果用户一直不碰这个对话框,程序就会停在这个状态,看起来像是“停滞”,但本质是系统在等待用户交互,并不是程序卡死了。
三、代码里的其他潜在问题(附带修复建议)
除了上面两个疑问,你的代码还有几个小问题,不修复的话蓝牙扫描可能没法正常工作:
权限授予后没启动扫描
当前onRequestPermissionsResult()里只弹了个Toast,没触发扫描逻辑,应该补充:@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){ Toast.makeText(MainActivity.this, "onRequestPermissionResult here...", Toast.LENGTH_LONG).show(); super.onRequestPermissionsResult(requestCode,permissions,grantResults); if(requestCode == REQUEST_CODE_COARSE_PERMISSION){ if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){ Toast.makeText(this,"Coarse Permission Granted",Toast.LENGTH_LONG).show(); // 权限拿到后,检查蓝牙是否开启,再启动扫描 if(mBluetoothAdapter.isEnabled()){ scanBluetoothDevices(true); } else { askBluetoothPermission(); } } else { Toast.makeText(this,"Coarse Permission Denied, cannot scan BLE devices",Toast.LENGTH_LONG).show(); } } }onActivityResult()逻辑搞反了
你现在在蓝牙启用的结果回调里又调用了askCoarsePermission(),会重复发起权限请求,应该改成启动扫描:@Override protected void onActivityResult(int requestCode, int resultCode, Intent data){ Toast.makeText(MainActivity.this, "onActivityResult here...", Toast.LENGTH_LONG).show(); super.onActivityResult(requestCode,resultCode,data); if(requestCode == REQUEST_CODE_BLUETOOTH_PERMISSION){ if(resultCode == RESULT_OK){ // 用户允许开蓝牙了,检查定位权限是否到位,再启动扫描 if(checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED){ scanBluetoothDevices(true); } else { askCoarsePermission(); } } else { Toast.makeText(this,"Bluetooth not enabled, cannot scan",Toast.LENGTH_LONG).show(); } } }onResume()重复弹蓝牙请求框
每次Activity回到前台都会触发onResume(),现在的代码会重复弹出蓝牙启用对话框,改成仅在必要时检查:@Override protected void onResume(){ Toast.makeText(MainActivity.this, "onResume here...", Toast.LENGTH_LONG).show(); super.onResume(); setListAdapter(mLeDeviceListAdapter); // 只在未扫描且蓝牙未开启时检查 if(!mScanning && mBluetoothAdapter != null && !mBluetoothAdapter.isEnabled()){ askBluetoothPermission(); } }遗漏Toast的
show()方法
检查BLE支持的代码里,你创建了Toast但没调用show(),用户看不到提示,补上:if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){ Toast.makeText(this,"ble_not_supported",Toast.LENGTH_SHORT).show(); // 补充show() finish(); }
内容的提问来源于stack exchange,提问作者Crazy Fox
相关产品推荐
相关产品推荐

