Android Display 管理服务 DisplayManager 详解
1、DisplayManager 概述
DisplayManager 是 Android 系统服务,负责管理显示设备,包括主屏幕、外接显示器、虚拟显示器等。它提供了获取显示信息、监听显示变化、管理多屏显示等功能。
核心特性:
- 管理所有显示设备
- 提供显示信息查询接口
- 支持显示变化监听
- 支持多屏显示和屏幕镜像
- 支持虚拟显示器(如投屏、录屏)
应用场景:
- 多屏互动应用
- 投屏和屏幕镜像
- 显示适配和布局优化
- 屏幕旋转和分辨率适配
- 虚拟显示器创建
2、核心 API
2.1、获取 DisplayManager
DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);2.2、Display 类
Display 类表示一个显示设备,提供以下关键信息:
- displayId:显示设备唯一标识
- name:显示设备名称
- width / height:显示尺寸(像素)
- realWidth / realHeight:实际尺寸(包含装饰区域)
- densityDpi:屏幕密度
- refreshRate:刷新率
- rotation:旋转角度(0、90、180、270度)
- state:显示状态(ON、OFF、DOZE、UNKNOWN)
2.3、Display.Mode
Display.Mode 表示显示模式,包含:
- modeId:模式标识
- width / height:分辨率
- refreshRate:刷新率
2.4、DisplayManager 常用方法
- getDisplay(int displayId):根据 ID 获取 Display
- getDisplays():获取所有显示设备
- getDisplays(String category):获取指定类别的显示设备
- registerDisplayListener():注册显示变化监听器
- unregisterDisplayListener():注销监听器
3、获取显示信息
3.1、获取默认显示
DisplayManager displayManager = (DisplayManager) getSystemService(DISPLAY_SERVICE);
Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
// 获取显示尺寸
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
// 获取实际尺寸(包含状态栏、导航栏)
Point realSize = new Point();
display.getRealSize(realSize);
// 获取显示模式
Display.Mode mode = display.getMode();
int modeWidth = mode.getWidth();
int modeHeight = mode.getHeight();
float refreshRate = mode.getRefreshRate();
// 获取屏幕密度
int densityDpi = display.getDensityDpi();
float density = display.getDensity();
// 获取旋转角度
int rotation = display.getRotation();
// Surface.ROTATION_0、ROTATION_90、ROTATION_180、ROTATION_270
// 获取显示状态
int state = display.getState();
// Display.STATE_ON、STATE_OFF、STATE_DOZE、STATE_UNKNOWN3.2、获取所有显示设备
Display[] displays = displayManager.getDisplays();
for (Display d : displays) {
Log.d("Display", "ID: " + d.getDisplayId() + ", Name: " + d.getName());
}
// 获取指定类别的显示设备
Display[] presentationDisplays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);3.3、获取支持的显示模式
Display.Mode[] modes = display.getSupportedModes();
for (Display.Mode m : modes) {
Log.d("Mode", "Width: " + m.getWidth() + ", Height: " + m.getHeight() +
", RefreshRate: " + m.getRefreshRate());
}4、监听显示变化
4.1、注册显示监听器
DisplayManager.DisplayListener listener = new DisplayManager.DisplayListener() {
@Override
public void onDisplayAdded(int displayId) {
Log.d("Display", "Display added: " + displayId);
Display display = displayManager.getDisplay(displayId);
}
@Override
public void onDisplayRemoved(int displayId) {
Log.d("Display", "Display removed: " + displayId);
}
@Override
public void onDisplayChanged(int displayId) {
Log.d("Display", "Display changed: " + displayId);
Display display = displayManager.getDisplay(displayId);
handleDisplayChange(display);
}
};
displayManager.registerDisplayListener(listener, null);4.2、注销监听器
displayManager.unregisterDisplayListener(listener);4.3、处理显示变化
private void handleDisplayChange(Display display) {
int rotation = display.getRotation();
int state = display.getState();
switch (rotation) {
case Surface.ROTATION_0:
// 竖屏
break;
case Surface.ROTATION_90:
// 横屏(左旋转)
break;
case Surface.ROTATION_180:
// 倒置竖屏
break;
case Surface.ROTATION_270:
// 横屏(右旋转)
break;
}
switch (state) {
case Display.STATE_ON:
// 显示开启
break;
case Display.STATE_OFF:
// 显示关闭
break;
case Display.STATE_DOZE:
// 低功耗模式
break;
}
}5、多屏显示与虚拟显示器
5.1、Presentation 多屏显示
Presentation 是用于在辅助显示器上显示内容的特殊 Dialog:
DisplayManager displayManager = (DisplayManager) getSystemService(DISPLAY_SERVICE);
Display[] displays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
if (displays.length > 0) {
Display display = displays[0];
MyPresentation presentation = new MyPresentation(this, display);
presentation.show();
}
// 自定义 Presentation
class MyPresentation extends Presentation {
public MyPresentation(Context context, Display display) {
super(context, display);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.presentation_layout);
}
}5.2、创建虚拟显示器
VirtualDisplay 用于创建虚拟显示设备,常用于录屏、投屏:
MediaProjectionManager projectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
MediaProjection projection = projectionManager.getMediaProjection(resultCode, data);
VirtualDisplay virtualDisplay = projection.createVirtualDisplay(
"MyVirtualDisplay",
width, height, densityDpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
surface, null, null);5.3、屏幕镜像
通过 VirtualDisplay 实现屏幕镜像:
DisplayManager displayManager = (DisplayManager) getSystemService(DISPLAY_SERVICE);
Display defaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
VirtualDisplay mirrorDisplay = displayManager.createVirtualDisplay(
"MirrorDisplay",
defaultDisplay.getMode().getWidth(),
defaultDisplay.getMode().getHeight(),
defaultDisplay.getDensityDpi(),
DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC,
surface, null, null);6、最佳实践与注意事项
6.1、性能优化
- 避免频繁查询显示信息,缓存必要的数据
- 在 onDisplayChanged 中避免耗时操作
- 合理使用监听器,及时注销
- 对于多屏显示,注意资源释放
6.2、兼容性处理
- 处理不同 Android 版本的 API 差异
- 适配不同屏幕尺寸和密度
- 处理屏幕旋转和配置变化
- 测试多屏显示场景
6.3、常见问题
问题1:获取的显示尺寸不正确
解决:区分 getSize() 和 getRealSize(),前者不包含装饰区域,后者包含
问题2:监听器回调频繁
解决:添加防抖逻辑,避免重复处理
问题3:Presentation 显示异常
解决:检查 Display 状态,确保显示器可用
6.4、总结
DisplayManager 是 Android 管理显示设备的核心服务,提供了获取显示信息、监听显示变化、管理多屏显示等功能。通过合理使用 DisplayManager,可以开发出适配不同显示设备的应用,提升用户体验。
关键要点:
- 使用 DisplayManager 获取显示设备信息
- 注册监听器响应显示变化
- 使用 Presentation 实现多屏显示
- 使用 VirtualDisplay 创建虚拟显示器
- 注意性能优化和兼容性处理
掌握 DisplayManager 的使用,对于开发多屏互动、投屏、录屏等功能至关重要,是 Android 开发者必备的技能之一。

