Android系统截屏的实现分析
来源:互联网 发布:上海大承网络 空中网 编辑:程序博客网 时间:2024/06/06 03:22
先来看看别个总结的流程(自己本来想画个,发现找到个就不造车了)
(该图引自http://blog.csdn.net/hk_256/article/details/7306590)
源码部分
喔 对鸟,这个是5.1的代码,kk的没有研究过,想必也差不多
interceptKeyBeforeQueueing()拦截按键信息
interceptScreenshotChord():handler调用截屏
private void interceptScreenshotChord() { if (mScreenshotChordEnabled && mScreenshotChordVolumeDownKeyTriggered && mScreenshotChordPowerKeyTriggered && !mScreenshotChordVolumeUpKeyTriggered) { final long now = SystemClock.uptimeMillis(); if (now <= mScreenshotChordVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS && now <= mScreenshotChordPowerKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) { mScreenshotChordVolumeDownKeyConsumed = true; cancelPendingPowerKeyAction(); mHandler.postDelayed(mScreenshotRunnable, getScreenshotChordLongPressDelay()); } } } private final Runnable mScreenshotRunnable = new Runnable() { @Override public void run() { takeScreenshot(); } };
private void takeScreenshot() { synchronized (mScreenshotLock) { if (mScreenshotConnection != null) { return; } ComponentName cn = new ComponentName("com.android.systemui", "com.android.systemui.screenshot.TakeScreenshotService");//实际上是通过启动systemui的TakeScreenshotServiceservice来实现 Intent intent = new Intent(); intent.setComponent(cn); ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { synchronized (mScreenshotLock) { if (mScreenshotConnection != this) { return; } Messenger messenger = new Messenger(service); Message msg = Message.obtain(null, 1); final ServiceConnection myConn = this; Handler h = new Handler(mHandler.getLooper()) { @Override public void handleMessage(Message msg) { synchronized (mScreenshotLock) { if (mScreenshotConnection == myConn) { mContext.unbindService(mScreenshotConnection); mScreenshotConnection = null; mHandler.removeCallbacks(mScreenshotTimeout); } } } }; msg.replyTo = new Messenger(h); msg.arg1 = msg.arg2 = 0; if (mStatusBar != null && mStatusBar.isVisibleLw()) msg.arg1 = 1; if (mNavigationBar != null && mNavigationBar.isVisibleLw()) msg.arg2 = 1; try { messenger.send(msg); } catch (RemoteException e) { } } } @Override public void onServiceDisconnected(ComponentName name) {} }; if (mContext.bindServiceAsUser( intent, conn, Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) { mScreenshotConnection = conn; mHandler.postDelayed(mScreenshotTimeout, 10000); } } }
public class TakeScreenshotService extends Service { private static final String TAG = "TakeScreenshotService"; private static GlobalScreenshot mScreenshot; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 1: final Messenger callback = msg.replyTo; if (mScreenshot == null) { mScreenshot = new GlobalScreenshot(TakeScreenshotService.this); } mScreenshot.takeScreenshot(new Runnable() { @Override public void run() { Message reply = Message.obtain(null, 1); try { callback.send(reply); } catch (RemoteException e) { } } }, msg.arg1 > 0, msg.arg2 > 0);//这个方法执行截屏,以及window的ui效果等 } } }; @Override public IBinder onBind(Intent intent) { return new Messenger(mHandler).getBinder(); }}
在SurfaceControl类中,在这儿调用底层nativeScreenshot方法截屏
/** * Like {@link SurfaceControl#screenshot(int, int, int, int, boolean)} but * with builtInDisplayId in the screenshot. * * @param width The desired width of the returned bitmap; the raw * screen will be scaled down to this size. * @param height The desired height of the returned bitmap; the raw * screen will be scaled down to this size. * @param builtInDisplayId The Built-in physical display id. * @return Returns a Bitmap containing the screen contents, or null * if an error occurs. Make sure to call Bitmap.recycle() as soon as * possible, once its content is not needed anymore. * * @hide */ public static Bitmap screenshot(int width, int height, int builtInDisplayId) { IBinder displayToken = SurfaceControl.getBuiltInDisplay(builtInDisplayId); Log.d(TAG, "screenshot, builtInDisplayId = " + builtInDisplayId); return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true, false, Surface.ROTATION_0); }
static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj, jobject surfaceObj, jobject sourceCropObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) { sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); if (displayToken != NULL) { sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj); if (consumer != NULL) { int left = env->GetIntField(sourceCropObj, gRectClassInfo.left); int top = env->GetIntField(sourceCropObj, gRectClassInfo.top); int right = env->GetIntField(sourceCropObj, gRectClassInfo.right); int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom); Rect sourceCrop(left, top, right, bottom); if (allLayers) { minLayer = 0; maxLayer = -1; } ScreenshotClient::capture(displayToken, consumer->getIGraphicBufferProducer(), sourceCrop, width, height, uint32_t(minLayer), uint32_t(maxLayer), useIdentityTransform); } }}
再往下
status_t ScreenshotClient::capture( const sp<IBinder>& display, const sp<IGraphicBufferProducer>& producer, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ, uint32_t maxLayerZ, bool useIdentityTransform) { sp<ISurfaceComposer> s(ComposerService::getComposerService()); if (s == NULL) return NO_INIT; return s->captureScreen(display, producer, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);}
再找找
virtual status_t captureScreen(const sp<IBinder>& display, const sp<IGraphicBufferProducer>& producer, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ, uint32_t maxLayerZ, bool useIdentityTransform, ISurfaceComposer::Rotation rotation) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeStrongBinder(display); data.writeStrongBinder(producer->asBinder()); data.write(sourceCrop); data.writeInt32(reqWidth); data.writeInt32(reqHeight); data.writeInt32(minLayerZ); data.writeInt32(maxLayerZ); data.writeInt32(static_cast<int32_t>(useIdentityTransform)); data.writeInt32(static_cast<int32_t>(rotation)); remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); return reply.readInt32(); }
搬个源码做个笔记
再往下就是涉及底层buffer之类的处理了=。=
0 1
- Android系统截屏的实现分析
- Android 日志系统(Logcat)的实现分析
- Android系统logcat实现分析
- Android系统的智能指针实现原理分析
- Android系统的智能指针实现原理分析
- Android FrameWork深入分析DreamManagerService实现自己的系统屏保
- Android 系统log抓取,实现原理分析
- Android系统框架的分析
- 定制Android系统开发之四——系统服务实现的分析
- 定制Android系统开发之六——系统服务JNI的实现分析
- Android系统截屏的实现(附代码)
- Android系统 截屏监听 的 原理与实现
- Android系统 截屏监听 的 原理与实现
- Android系统 截屏监听 的 原理与实现
- Chromium on Android: Android系统上Chromium主消息循环的实现分析
- Android图形系统的分析与移植--七、双缓冲framebuffer的实现
- Android图形系统的分析与移植 -- 六、双缓冲framebuffer的实现
- Android调用系统相机以及拉取本地相册的功能实现以及代码分析
- Python--面向对象程序设计
- XPath 详解,总结
- 11.2.0.1在RHEL6.5
- css
- Hdu 1087 Super Jumping! Jumping! Jumping!【最大上升子序列和】
- Android系统截屏的实现分析
- Java学习推荐书目
- 文章标题
- iOS 开发中在导航栏添加多个按钮并改变它的位置
- MFC学习-第2,3课 MFC框架的运行机制
- 【Spring3】(1)初识Spring
- 生成二维码代码
- Oracle数据库order by排序之null值处理方法
- RequireJS Adding a Library