深入浅出:Android屏幕刷新机制,美团点评APP在移动网络性能优化的实践

链接:https://juejin.im/post/6874483682699132935

基础知识

View绘制

这部分在之前的文章有过专门的说明Android的View绘制机制

在我们之前的代码中,对于15-17这部分并没有进行任何的详解,那么底层是如何产生Vsync的信号,然后又是如何通知到我们的应用进行屏幕刷新呢?这不分就是我们这篇文章的关注点。

入口

mChoreographer = Choreographer.getInstance();

//Choreographer.java frameworks\base\core\java\android\view
public static Choreographer getInstance() {
return sThreadInstance.get();
}

private static final ThreadLocal sThreadInstance = new ThreadLocal() {
@Override
protected Choreographer initialValue() {
//获取对应的looper
Looper looper = Looper.myLooper();
if (looper == null) {
throw new IllegalStateException(“The current thread must have a looper!”);
}
//注意这里使用的VSYNC_SOURCE_APP
Choreographer choreographer = new Choreographer(looper, VSYNC_SOURCE_APP);
if (looper == Looper.getMainLooper()) {
mMainInstance = choreographer;
}
return choreographer;
}
};

private Choreographer(Looper looper, int vsyncSource) {
//FrameDisplayEventReceiver创建的信号是VSYNC_SOURCE_APP,APP层请求的VSYNC
mDisplayEventReceiver = USE_VSYNC? new FrameDisplayEventReceiver(looper, vsyncSource): null;

}

这里初始化的FrameDisplayEventReceiver类继承自DisplayEventReceiver

public DisplayEventReceiver(Looper looper, int vsyncSource) {
if (looper == null) {
throw new IllegalArgumentException(“looper must not be null”);
}

mMessageQueue = looper.getQueue();
//调用底层初始化,并将本身以及对应的mMessageQueue传入进去
//对应frameworks\base\core\jni\android_view_DisplayEventReceiver.cpp
mReceiverPtr = nativeInit(new WeakReference(this), mMessageQueue,vsyncSource);

mCloseGuard.open(“dispose”);
}

这里会调用Native层的方法,并将当前的DisplayEventReceiver以及队列mMessageQueue和**vsyncSource(VSYNC_SOURCE_APP)**传递给底层

nativeInit

//frameworks\base\core\jni\android_view_DisplayEventReceiver.cpp
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
jobject messageQueueObj, jint vsyncSource) {
//申请对应的MessageQueue
sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);

//重点方法1 创建NativeDisplayEventReceiver
sp receiver = new NativeDisplayEventReceiver(env,
receiverWeak, messageQueue, vsyncSource);
//重点方法2 进行初始化NativeDisplayEventReceiver,并返回对应的初始化结果
status_t status = receiver->initialize();
if (status) {//初始化出现异常
String8 message;led to initialize display event receiver. status
message.appendFormat(“Fai=%d”, status);
jniThrowRuntimeException(env, message.string());
return 0;
}
receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); // retain a reference for the object
return reinterpret_cast(receiver.get());
}

我们这里先看一下NativeDisplayEventReceiver的创建过程。

[NativeDisplayEventReceiver的创建]

NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env,
jobject receiverWeak, const sp& messageQueue, jint vsyncSource) :
//继承了DisplayEventDispatcher,并传入了对应的messagequeue,将vsyncSource转化为了底层使用的变量
DisplayEventDispatcher(messageQueue->getLooper(),
static_castISurfaceComposer::VsyncSource(vsyncSource)),
mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
mMessageQueue(messageQueue) {
ALOGV(“receiver %p ~ Initializing display event receiver.”, this);
}

//DisplayEventDispatcher构造函数
DisplayEventDispatcher::DisplayEventDispatcher(const sp& looper,ISurfaceComposer::VsyncSource vsyncSource) :
//Vsync的来源传递给了mReceiver。这里相当于调用了mReceiver(Dis

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值