当前位置: 首页 > news >正文

网站的结构与布局优化优化电池充电什么意思

网站的结构与布局优化,优化电池充电什么意思,网站建站案,拍网制作方法图片教程目录 简介 Insets管理架构 Insets相关类图 app侧的类 WMS侧的类 inset show的流程 接口 流程 WMS侧确定InsetsSourceControl的流程 两个问题 窗口显示时不改变现有的inset状态 全屏窗口上的dialog 不显示statusbar问题 View 和 DecorView 设置insets信息 输入法显…目录 简介 Insets管理架构 Insets相关类图 app侧的类 WMS侧的类 inset show的流程 接口 流程 WMS侧确定InsetsSourceControl的流程 两个问题 窗口显示时不改变现有的inset状态 全屏窗口上的dialog 不显示statusbar问题 View 和 DecorView 设置insets信息 输入法显示流程 1. 在某个app侧点击编辑框 2.输入法app接收到显示输入法消息 3.InputMethodManagerService接收到输入法app的显示状态信息 4.输入法窗口接收到showInsetsIWindow  监听inset 变化 设置Insetscontroller变化监听 应用WindowInsets变化 简介 android 11上新增一套inset管理方法。 Insets 是指系统边衬区的窗口 包括statusbar, navigation bar, 输入法等 都在insets管理中。下面说的这些insets即为这些窗口。  通过insets相关的接口 app可以控制insets窗口的显示 隐藏 沉浸式等。 inset 最基本的控制是show 和hide。 在inset 不同的状态下 应用区的位置也会发生变化 这部分的计算也是inset控制的重要内容之一。   insets完整的实现逻辑 包含app端和服务端服务端主要是WMS(window manager service)。 本文梳理insets的管理架构和主要逻辑 如show insets 等。 下面为dump 出来的insets信息, 使用命令adb shell dumpsys window。 InsetsState 是系统当前所有inset状态的集合InsetsSource 对应每一个inset, 包括type, frame, visible项  InsetsState       InsetsSource typeITYPE_STATUS_BAR frame[0,0][2776,130] visiblefalse       InsetsSource typeITYPE_NAVIGATION_BAR frame[0,0][744,1022] visiblefalse       InsetsSource typeITYPE_TOP_GESTURES frame[0,0][2776,130] visibletrue       InsetsSource typeITYPE_BOTTOM_GESTURES frame[0,1017][744,1022] visibletrue       InsetsSource typeITYPE_LEFT_GESTURES frame[0,0][0,1022] visibletrue       InsetsSource typeITYPE_RIGHT_GESTURES frame[2776,0][2776,1022] visibletrue       InsetsSource typeITYPE_TOP_TAPPABLE_ELEMENT frame[0,0][2776,130] visibletrue       InsetsSource typeITYPE_BOTTOM_TAPPABLE_ELEMENT frame[0,1017][744,1022] visibletrue       InsetsSource typeITYPE_IME frame[0,0][0,0] visiblefalse Insets管理架构 Insets相关类图 分为app侧和系统服务侧wms侧。  app侧的类 InsetsState  为Parceble 在wms和app中互相传递。其中记录了所有系统Insets的InsetsSource。每个InsetsSource描述了Insets的状态。 可以参看简介中dump信息InsetsSource 为Parceble 记录一个inset是否显示及frame。可以参看简介中dump信息。 InsetsSourceControl 为Parceble。  InsetsSourceControl 与某一个insets窗口对应 可以通过其控制inset show 和hide。app持有相应inset的InsetsSourceControl 就可以控制该inset的显示和隐藏如果不持有某个类型的InsetsSourceControl 就不能控制该类型的inset的显示和隐藏。  其中mLeash 为surfaceControl, 可由InsetsAnimationControlImpl获取并交给SyncRtSurfaceTransactionApplier 控制动画进度如surface位置 隐藏显示等。app持有哪些inset的InsetsSourceControl有wms确定并在ddWindow和 relayoutWindow()时传回给app。  app侧持有的InsetsSourceControl来自于添加窗口时 addWindow和 relayoutWindow()时传回的 mTempControls。 实测 addWindow时mTempControls传回值为null. 在relayoutWindow 时传回mTempControls为实际值。WMS在在relayout 过程中 会寻找inset 的target 窗口 通过addToControlMaps InsetsStateController.java为该类型的窗口添加target 然后在 relayoutWindow()中通过调用win.getDisplayContent().getInsetsStateController().getControlsForDispatch(win); 获取该win的InsetsSourceControl 传回给app端的mTempControls。 ViewRootImp.setView()--addWindow...mTempControls //获得mTempControlsmInsetsController.onControlsChanged(mTempControls)--consumer.setControl(control, showTypes, hideTypes); InsetsController 每个窗口对应一个InsetController。 为app端控制inset显示隐藏 更新状态动画的总调度 包含 InsetsSourceConsumer map 和 ViewRootInsetsControllerHost。每种insets类型对应一个InsetsSourceConsumer。InsetsController在ViewRootImpl初始化时创建。 创建InsetsController stack 从下向上at android.view.InsetsController.init(InsetsController.java:525)at android.view.ViewRootImpl.init(ViewRootImpl.java:768)at android.view.ViewRootImpl.init(ViewRootImpl.java:720)at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:401)at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:109) InsetsSourceConsumer 中记录了InsetState(从wms传入)及InsetsSourceControl。 InsetsSourceControl来自wms中传入 具体参看InsetsSourceControl说明。 PendingInsetsController为窗口被加入到wms之前记录APP要求的状态 在ViewRootImpl.setview时调用mWindowSession.addToDisplayAsUser之后被同步到InsetsController中。  WMS侧的类 InsetsStateController 控制全局整体inset状态。 mProviders为insets的provider的集合。 mTypeControlTargetMap为可以控制每种Insets如显示或隐藏的窗口的集合。 mState为InsetsState 当前系统所有inset 的状态。 (注 每个WindowState通过InsetsStateController.getInsetsForDispatch获取该窗口的state 通过relayoutWindow或者addWindow 中的outInsetsState.set(win.getInsetsState(), win.isClientLocal())将当前窗口insetState 转给app。app端通过mInsetsController.onStateChanged ViewRootImpl将状态设置给InsetsController。  app 根据这个insetstate计算内容区域。 app 计算inset区域mInsetsController.calculateInsets。 DisplayContent和InsetsPolicy均持有InsetsStateController为同一实例。 InsetsPolicy 为insets在wms端的总体策略。InsetsControlTarget即为WindowState如果某个窗口可以控制某种类型inset 在该窗口addToWindow()和relayoutWindow()函数中, 返回对应inset的InsetsSourceControl。例如 当前top窗口仅允许控制statusbar, 则statusbar的InsetsControlTarget为当前top窗口 传回给当前top窗口InsetsSourceControl 仅有statusbar, 没有导航栏的InsetsSourceControl。 InsetsSourceProvider win inset 窗口 例如输入法窗口 导航栏窗口。 其中mSource为某个 inset的frame及显示状态。 mFrameProvider计算inset的frame大小的函数用于设置mSource中的frame。 在updateSourceFrame中调用。 inset show的流程 inset 基本的控制是show 和hide, inset show和hide流程基本一样以show流程说明流程。  接口 app 控制insets显示或者隐藏调用的接口如下, 关于InsetsController参见InsetsController类说明。 getWindow().getInsetsController().show(insetTypeList) //实际对应InsetsController.show() getWindow().getInsetsController().hide(insetTypeList) //实际对应InsetsController.hide() 流程 调用InsetsController.show/hide的调用stack如下 从下到上这个stack只到InsetsController.notifyVisibilityChanged()该stack只是记录和参考不作详细说明。 具体需要注意的是InsetsController.notifyVisibilityChanged()之后流程。 //此函数先调用ViewRootInsetsControllerHost.notifyInsetsChanged 后调用updateRequestedStateat android.view.InsetsController.notifyVisibilityChanged(InsetsController.java:1208) at android.view.InsetsSourceConsumer.setRequestedVisible(InsetsSourceConsumer.java:344)at android.view.InsetsSourceConsumer.show(InsetsSourceConsumer.java:196)at android.view.InsetsController.showDirectly(InsetsController.java:1325)at android.view.InsetsController.controlAnimationUnchecked(InsetsController.java:1013)at android.view.InsetsController.applyAnimation(InsetsController.java:1305)at android.view.InsetsController.show(InsetsController.java:870)at android.view.InsetsController.show(InsetsController.java:826) InsetsController.notifyVisibilityChanged()流程 InsetsController.notifyVisibilityChanged()函数如下 先调用ViewRootInsetsControllerHost.notifyInsetsChanged  后调用updateRequestedState。 public void notifyVisibilityChanged() {mHost.notifyInsetsChanged();  //实际在viewRootImpl中requestLayout, 也就是在下一个vsync中与wms交互去Relayout()。updateRequestedState();  //调用了ViewRootInsetsControllerHost.onInsetsModified。 交互流程见下面的流程图。} ViewRootInsetsControllerHost.notifyInsetsChanged 实际在viewRootImpl中调用requestLayout, 也就是在下一个vsync中与wms交互去Relayout()。从而获取新的InsetsSourceControl和InsetsState,并刷新界面layout。 这里的notify应该指的是通知本app重新刷新layout。在重新layout后 会调用mInsetsController.calculateInsets根据inset的显示和占位情况 计算应用区的大小。  at android.view.ViewRootImpl.notifyInsetsChanged(ViewRootImpl.java:1603) //下一个vsync relayout at android.view.ViewRootInsetsControllerHost.notifyInsetsChanged(ViewRootInsetsControllerHost.java:54) // at android.view.InsetsController.notifyVisibilityChanged(InsetsController.java:1208) updateRequestedState用于通知wms端app请求inset变化wms处理相应的inset显示和隐藏 并通知其他app系统inset变化。 调用了ViewRootInsetsControllerHost.onInsetsModified交互流程见下面的流程图。app端调用IWindowSession.insetsModified(IWindow window, in InsetsState state)通知wms inset变化 其中InsetsState为修改后的inset状态。 wms通过InsetSourceProvider.setClientVisible设置inset窗口显示状态。 然后发送消息给所有的活动窗口 通知insetsChanged。 每个活动窗口调用mInsetsController.onStateChanged设置自己的inset窗口状态onStateChanged也会调用notifyInsetsChanged重新relayout 窗口。而发起show流程的窗口因为state已经修改为当前的状态 所以onStateChanged不再执行该操作。 at android.view.ViewRootInsetsControllerHost.onInsetsModified(ViewRootInsetsControllerHost.java:147) //调用WindowSession.insetsModified()通知wms 修改inset visibilityat android.view.InsetsController.updateRequestedState(InsetsController.java:1287)at android.view.InsetsController.notifyVisibilityChanged(InsetsController.java:1209) ​​ 注 app 调用notifyInsetsChanged的几个地方仅做参考  1. 在onStateChangedInsetsController中调用 比如在ViewRootImpl.setView中调用onStateChanged, 从下到上  ViewRootInsetsControllerHost.notifyInsetsChanged()  android.view.ViewRootInsetsControllerHost.notifyInsetsChanged(ViewRootInsetsControllerHost.java:54)       at android.view.InsetsController.onStateChanged(InsetsController.java:630)  //在ViewRootImpl.setView中调用mWindowSession.addToDisplayAsUser后wms 返回了当前窗口对应的InsetsSourceControl和InsetsState 调用本函数      at android.view.ViewRootImpl.setView(ViewRootImpl.java:1059)        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:411)       at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:109)        2. 在setFrameViewRootImpl中调用 如在ViewRootImpl.setView中调用setFrame(), 从小到上 ViewRootInsetsControllerHost.notifyInsetsChanged()  android.view.ViewRootInsetsControllerHost.notifyInsetsChanged(ViewRootInsetsControllerHost.java:54)       at android.view.InsetsController.onFrameChanged(InsetsController.java:594)       at android.view.ViewRootImpl.setFrame(ViewRootImpl.java:7493)       at android.view.ViewRootImpl.setView(ViewRootImpl.java:1036)       at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:411)       at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:109)        WMS侧确定InsetsSourceControl的流程 WMS侧如何确定某个app 可以持有哪些InsetsSourceControl。 在该窗口relayout中 根据当前window 的focus情况 只有focus的窗口可以获取InsetsSourceControl也就是控制inset的显示和隐藏 没有focus的窗口不能获取InsetsSourceControl也就是不能控制inset的显示和隐藏。当一个窗口设置了FLAG_NOT_FOCUSABLE 就不在能控制inset的显示和隐藏。流程从下到上 // addToControlMaps 设置了mControlTargetTypeMapInsetsStateController.java   设置了mControlTargetTypeMap后 通过在relayout 中调用getInsetsSourceControls传回给app进程的mTempControls。        at com.android.server.wm.InsetsStateController.addToControlMaps(InsetsStateController.java:523)       at com.android.server.wm.InsetsStateController.onControlChanged(InsetsStateController.java:469)       at com.android.server.wm.InsetsStateController.onBarControlTargetChanged(InsetsStateController.java:424)       at com.android.server.wm.InsetsPolicy.updateBarControlTarget(InsetsPolicy.java:150)       at com.android.server.wm.DisplayPolicy.updateSystemUiVisibilityLw(DisplayPolicy.java:3940)       at com.android.server.wm.DisplayPolicy.focusChangedLw(DisplayPolicy.java:3736)       at com.android.server.wm.DisplayContent.updateFocusedWindowLocked(DisplayContent.java:3286)       at com.android.server.wm.RootWindowContainer.updateFocusedWindowLocked(RootWindowContainer.java:461)       at com.android.server.wm.WindowManagerService.updateFocusedWindowLocked(WindowManagerService.java:5552)       at com.android.server.wm.WindowManagerService.relayoutWindow(WindowManagerService.java:2348) 两个问题 窗口显示时不改变现有的inset状态 两种方法 一种就是控制inset 和上一个窗口相同获取当前insets状态方法 getWindowManager().getCurrentWindowMetrics().getWindowInsets。示例 在onCreate 或 onResume中调用以下代码也就是mWm.addView(mDecorView, l);之前调用。 WindowInsets windowInsets getWindowManager().getCurrentWindowMetrics().getWindowInsets(); hideTypeList getHideTypeList(windowInsets)//获取hide 的type list。 showTypeList getShowTypeList(windowInsets)//获取show 的type list。 WindowInsetsController controller decorView.getWindowInsetsController(); controller.hide(hideTypeList); controller.show(hideTypeList);另一种就是设置窗口为FLAG_NOT_FOCUSABLE。FLAG_NOT_FOCUSABLE, 导致没有focus window 变化 从而不能设置获取InsetsSourceControl也就无法控制所有insets窗口的show和hide。 代码 l.flags | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE  // 本句需要注释掉才能获取InsetsSourceControl。 | WindowManager.LayoutParams.FLAG_FULLSCREEN; wms中判断应用是否focus的代码 mFindFocusedWindow           at com.android.server.wm.WindowState.canReceiveKeys(WindowState.java:2877) // 如果设置FLAG_NOT_FOCUSABLE canReceiveKeys 返回false, 认为改窗口非焦点窗口 不改变inset设置。 全屏窗口上的dialog 不显示statusbar问题 受全屏窗口设置影响。 系统单独对status bar做了设置 ​​ View 和 DecorView 设置insets信息 流程如下 DecorView的onApplyWindowInsets 会调用mInsetsController.calculateInsets,计算应用区的大小。 at com.android.internal.policy.DecorView.onApplyWindowInsets(DecorView.java:1046)//demorview 将inset区域减去其他的区域作为内容区at android.view.View.dispatchApplyWindowInsets(View.java:11311)at android.view.ViewGroup.dispatchApplyWindowInsets(ViewGroup.java:7320)at android.view.ViewRootImpl.dispatchApplyInsets(ViewRootImpl.java:2311) //会通过calculateInsets 计算当前inset, 将当前inset应用到view。 at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2439)at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1948)at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8179)at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)at android.view.Choreographer.doCallbacks(Choreographer.java:796)at android.view.Choreographer.doFrame(Choreographer.java:731)at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957) 输入法显示流程 输入法也是一种inset 其显示和隐藏的流程也与inset 显示隐藏一致。 下面介绍的是在点击编辑框时输入法显示流程。 1. 在某个app侧点击编辑框 最后调用showSoftInputInputMethodManager  showSoftInput:1587, InputMethodManager (android.view.inputmethod) onTouchEvent:11082, TextView (android.widget) dispatchTouchEvent:14309, View (android.view) dispatchTransformedTouchEvent:3118, ViewGroup (android.view) dispatchTouchEvent:2799, ViewGroup (android.view) dispatchTransformedTouchEvent:3118, ViewGroup (android.view) dispatchTouchEvent:2799, ViewGroup (android.view) dispatchTransformedTouchEvent:3118, ViewGroup (android.view) dispatchTouchEvent:2799, ViewGroup (android.view) dispatchTransformedTouchEvent:3118, ViewGroup (android.view) dispatchTouchEvent:2799, ViewGroup (android.view) superDispatchTouchEvent:515, DecorView (com.android.internal.policy) superDispatchTouchEvent:1879, PhoneWindow (com.android.internal.policy) dispatchTouchEvent:4135, Activity (android.app) dispatchTouchEvent:473, DecorView (com.android.internal.policy) dispatchPointerEvent:14568, View (android.view) processPointerEvent:6024, ViewRootImpl$ViewPostImeInputStage (android.view) onProcess:5827, ViewRootImpl$ViewPostImeInputStage (android.view) deliver:5318, ViewRootImpl$InputStage (android.view) onDeliverToNext:5375, ViewRootImpl$InputStage (android.view) forward:5341, ViewRootImpl$InputStage (android.view) forward:5493, ViewRootImpl$AsyncInputStage (android.view) apply:5349, ViewRootImpl$InputStage (android.view) apply:5550, ViewRootImpl$AsyncInputStage (android.view) deliver:5322, ViewRootImpl$InputStage (android.view) onDeliverToNext:5375, ViewRootImpl$InputStage (android.view) forward:5341, ViewRootImpl$InputStage (android.view) apply:5349, ViewRootImpl$InputStage (android.view) deliver:5322, ViewRootImpl$InputStage (android.view) deliverInputEvent:8088, ViewRootImpl (android.view) doProcessInputEvents:8039, ViewRootImpl (android.view) enqueueInputEvent:8000, ViewRootImpl (android.view) onInputEvent:8211, ViewRootImpl$WindowInputEventReceiver (android.view) dispatchInputEvent:220, InputEventReceiver (android.view) nativePollOnce:-1, MessageQueue (android.os) next:335, MessageQueue (android.os) loop:183, Looper (android.os) main:7664, ActivityThread (android.app) invoke:-1, Method (java.lang.reflect) run:592, RuntimeInit$MethodAndArgsCaller (com.android.internal.os) main:947, ZygoteInit (com.android.internal.os) 2.输入法app接收到显示输入法消息 输入法app, 即实现inputmethodservice的app。 其与InputMethodManagerService的接口为IInputMethodWrapper。 InputMethodManagerService 调用 IInputMethodWrapper.showSoftInput 其发送消息DO_SHOW_SOFT_INPUT。 处理DO_SHOW_SOFT_INPUT 调用到InputMethodService.showSoftInput () 最终调用到IInputMethodPrivilegedOperations.applyImeVisibility().IInputMethodPrivilegedOperations 为inputMethodService与InputMethodManagerService的通信接口。  applyVisibilityInInsetsConsumerIfNecessary:2219, InputMethodService (android.inputmethodservice) access$400:263, InputMethodService (android.inputmethodservice) showSoftInput:748, InputMethodService$InputMethodImpl (android.inputmethodservice) showSoftInputWithToken:718, InputMethodService$InputMethodImpl (android.inputmethodservice) executeMessage:226, IInputMethodWrapper (android.inputmethodservice) handleMessage:44, HandlerCaller$MyHandler (com.android.internal.os) dispatchMessage:106, Handler (android.os) loop:223, Looper (android.os) main:7664, ActivityThread (android.app) invoke:-1, Method (java.lang.reflect) run:592, RuntimeInit$MethodAndArgsCaller (com.android.internal.os) main:947, ZygoteInit (com.android.internal.os) 3.InputMethodManagerService接收到输入法app的显示状态信息 输入法app调用InputMethodManagerService.applyImeVisibility() 通知InputMethodManagerServiceIMMS显示状态变化IMMS然后调用到scheduleShowImePostLayoutImeInsetsSourceProvider该函数在下一个vsync调用输入法窗口的windowState.showInsets通知输入法窗口: ims: show.   scheduleShowImePostLayout:52, ImeInsetsSourceProvider (com.android.server.wm) showImePostLayout:7615, WindowManagerService$LocalService (com.android.server.wm) applyImeVisibility:4088, InputMethodManagerService (com.android.server.inputmethod) access$4700:188, InputMethodManagerService (com.android.server.inputmethod) applyImeVisibility:5935, InputMethodManagerService$InputMethodPrivilegedOperationsImpl (com.android.server.inputmethod) onTransact:336, IInputMethodPrivilegedOperations$Stub (com.android.internal.inputmethod) execTransactInternal:1154, Binder (android.os) execTransact:1123, Binder (android.os) 4.输入法窗口接收到showInsetsIWindow  输入法在接收到ims显示状态变化后 如下面流程调用InsetsController.show, 后面的流程和前面介绍的inset show的流程一致 通知wms ims inset状态变化,  并通知给所有活动中的窗口。 在下一个vsync 调用relayoutWindow()重新布局。下面为输入法窗口的showInsets流程。 main15899 prio5 tid0x2 nidNA runnablejava.lang.Thread.State: RUNNABLEat android.view.InsetsController.updateRequestedState(InsetsController.java:1262)at android.view.InsetsController.notifyVisibilityChanged(InsetsController.java:1209)at android.view.InsetsSourceConsumer.setRequestedVisible(InsetsSourceConsumer.java:344)at android.view.InsetsSourceConsumer.show(InsetsSourceConsumer.java:196)at android.view.InsetsController.showDirectly(InsetsController.java:1325)at android.view.InsetsController.controlAnimationUnchecked(InsetsController.java:1013)at android.view.InsetsController.applyAnimation(InsetsController.java:1305)at android.view.InsetsController.show(InsetsController.java:870)at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:5031) //处理 MSG_SHOW_INSETS MSG_SHOW_INSETS 为wms 调用iWindow.showInsets触发。at android.os.Handler.dispatchMessage(Handler.java:106)at android.os.Looper.loop(Looper.java:223)at android.app.ActivityThread.main(ActivityThread.java:7664)at java.lang.reflect.Method.invoke(Method.java:-1)at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)监听inset 变化 窗口中的view可以在insets变化时 改变默认的inset 占位行为。 监听inset变化 然后自行设置insets如何占位。 如 设置Insetscontroller变化监听 InsetsController.addOnControllableInsetsChangedListener(OnControllableInsetsChangedListener ...); 应用WindowInsets变化 getWindow().getDecorView().setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener ...);Overridepublic WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {mImeVisible insets.isVisible(ime());return v.onApplyWindowInsets(insets);}
http://www.pierceye.com/news/434232/

相关文章:

  • 软件开发与网站开发硬件开发语言
  • 开封做网站睿艺美官方网站建设的必要
  • 自适应网站制作简创网络南联网站建设
  • 帮别人做钓鱼网站犯法吗贵州网站建设工作室
  • 企业网站域名空间优化公司治理结构
  • 网站建设 前沿文章php做网站脑图
  • 刷单网站开发装修企业网站源码
  • 莱州人社局网站网站开发项目资金运用明细
  • 水墨网站模板软通动力外包怎么样
  • 直播间网站建设小清新wordpress主题
  • 淘金网站建设推广汽车 营销 网站建设
  • 网站站内链接seo外链发布工具
  • 如何设计大型电商网站建设利用php做网站
  • 大朗网站仿做google广告
  • 跳转网站代码wordpress文章只能会员才能看
  • 大鹏网络网站建设报价vps的网站打不开
  • 西部数码网站管理助手卸载修改网站空间服务器密码
  • asp网站开发技术总结与收获建设银行网站怎么登录密码忘了怎么办
  • 营销型企业网站 网络服务flashfxp 网站
  • 青岛网站建设服务平台邢台专业网站建设费用
  • wordpress做网站好吗戴南做网站
  • 中山精品网站建设价位网站开发后台一般用什么
  • 万网 手机网站物联网平台介绍
  • 墨星写作网站网站建设使用的什么语言
  • wdcp网站搬家wordpress 改成宽屏
  • 汽车网站建设规划书洛阳恢复客运最新通知
  • 商洛建设网站有了网站源码可以做网站吗
  • 网站运营学习电子商务网站建设与管理的实验报告
  • 上海设计网站与太原免费网络推广哪里朿
  • 网站前端建设需要学会什么珠海网站优化公司