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

网站建设重庆百度推广在线客服

网站建设重庆,百度推广在线客服,妇联 网站建设情况,香河做网站Build lifecycle-aware components that can adjust behavior based on the current lifecycle state of an activity or fragment. 上面是源于官网的定义,简单翻译就是说Lifecycle的作用就是基于当前的Activity或者Fragment的生命周期当前状态构建可感知生命周期的…

Build lifecycle-aware components that can adjust behavior based on the current lifecycle state of an activity or fragment.

上面是源于官网的定义,简单翻译就是说Lifecycle的作用就是基于当前的Activity或者Fragment的生命周期当前状态构建可感知生命周期的组件。

Lifecycle组件涉及一个类和两个接口,一个类是Lifecycle,两个接口分别是LifecycleObserverLifecycleOwner

一、Lifecycle

在这里插入图片描述

1.1、源码

public abstract class Lifecycle {@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)@NonNullAtomicReference<Object> mInternalScopeRef = new AtomicReference<>();@MainThread//添加观察者public abstract void addObserver(@NonNull LifecycleObserver observer);@MainThread//移除观察者public abstract void removeObserver(@NonNull LifecycleObserver observer);@MainThread@NonNull//获取当前状态public abstract State getCurrentState();@SuppressWarnings("WeakerAccess")public enum Event {/*** Constant for onCreate event of the {@link LifecycleOwner}.*/ON_CREATE,/*** Constant for onStart event of the {@link LifecycleOwner}.*/ON_START,/*** Constant for onResume event of the {@link LifecycleOwner}.*/ON_RESUME,/*** Constant for onPause event of the {@link LifecycleOwner}.*/ON_PAUSE,/*** Constant for onStop event of the {@link LifecycleOwner}.*/ON_STOP,/*** Constant for onDestroy event of the {@link LifecycleOwner}.*/ON_DESTROY,/*** An {@link Event Event} constant that can be used to match all events.*/ON_ANY;/*** Returns the {@link Lifecycle.Event} that will be reported by a {@link Lifecycle}* leaving the specified {@link Lifecycle.State} to a lower state, or {@code null}* if there is no valid event that can move down from the given state.** @param state the higher state that the returned event will transition down from* @return the event moving down the lifecycle phases from state*/@Nullable//从当前状态降级的事件public static Event downFrom(@NonNull State state) {switch (state) {//从CREATED降级的是ON_DESTROY事件case CREATED:return ON_DESTROY;//从STARTED降级的是ON_STOP事件case STARTED:return ON_STOP;//从RESUMED降级的是ON_PAUSE事件case RESUMED:return ON_PAUSE;default:return null;}}/*** Returns the {@link Lifecycle.Event} that will be reported by a {@link Lifecycle}* entering the specified {@link Lifecycle.State} from a higher state, or {@code null}* if there is no valid event that can move down to the given state.** @param state the lower state that the returned event will transition down to* @return the event moving down the lifecycle phases to state*/@Nullable//降级到当前状态的事件public static Event downTo(@NonNull State state) {switch (state) {//降级到DESTROYED状态的是ON_DESTROY事件case DESTROYED:return ON_DESTROY;//降级到CREATED状态的是ON_STOP事件case CREATED:return ON_STOP;//降级到STARTED状态的是ON_PAUSE事件case STARTED:return ON_PAUSE;default:return null;}}/*** Returns the {@link Lifecycle.Event} that will be reported by a {@link Lifecycle}* leaving the specified {@link Lifecycle.State} to a higher state, or {@code null}* if there is no valid event that can move up from the given state.** @param state the lower state that the returned event will transition up from* @return the event moving up the lifecycle phases from state*/@Nullable//从该状态升级的事件public static Event upFrom(@NonNull State state) {switch (state) {//从INITIALIZED状态升级的事件为ON_CREATEcase INITIALIZED:return ON_CREATE;//从CREATED状态升级的事件为ON_STARTcase CREATED:return ON_START;//从STARTED状态升级的事件为ON_RESUMEcase STARTED:return ON_RESUME;default:return null;}}/*** Returns the {@link Lifecycle.Event} that will be reported by a {@link Lifecycle}* entering the specified {@link Lifecycle.State} from a lower state, or {@code null}* if there is no valid event that can move up to the given state.** @param state the higher state that the returned event will transition up to* @return the event moving up the lifecycle phases to state*/@Nullable//升级到该状态的事件public static Event upTo(@NonNull State state) {switch (state) {//升级到CREATED状态是ON_CREATE事件case CREATED:return ON_CREATE;//升级到STARTED状态是ON_START事件case STARTED:return ON_START;//升级到RESUMED状态是ON_RESUME事件case RESUMED:return ON_RESUME;default:return null;}}/*** Returns the new {@link Lifecycle.State} of a {@link Lifecycle} that just reported* this {@link Lifecycle.Event}.** Throws {@link IllegalArgumentException} if called on {@link #ON_ANY}, as it is a special* value used by {@link OnLifecycleEvent} and not a real lifecycle event.** @return the state that will result from this event*/@NonNullpublic State getTargetState() {switch (this) {case ON_CREATE:case ON_STOP:return State.CREATED;case ON_START:case ON_PAUSE:return State.STARTED;case ON_RESUME:return State.RESUMED;case ON_DESTROY:return State.DESTROYED;case ON_ANY:break;}throw new IllegalArgumentException(this + " has no target state");}}/*** Lifecycle states. You can consider the states as the nodes in a graph and* {@link Event}s as the edges between these nodes.*/@SuppressWarnings("WeakerAccess")public enum State {/*** Destroyed state for a LifecycleOwner. After this event, this Lifecycle will not dispatch* any more events. For instance, for an {@link android.app.Activity}, this state is reached* <b>right before</b> Activity's {@link android.app.Activity#onDestroy() onDestroy} call.*/DESTROYED,/*** Initialized state for a LifecycleOwner. For an {@link android.app.Activity}, this is* the state when it is constructed but has not received* {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} yet.*/INITIALIZED,/*** Created state for a LifecycleOwner. For an {@link android.app.Activity}, this state* is reached in two cases:* <ul>*     <li>after {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} call;*     <li><b>right before</b> {@link android.app.Activity#onStop() onStop} call.* </ul>*/CREATED,/*** Started state for a LifecycleOwner. For an {@link android.app.Activity}, this state* is reached in two cases:* <ul>*     <li>after {@link android.app.Activity#onStart() onStart} call;*     <li><b>right before</b> {@link android.app.Activity#onPause() onPause} call.* </ul>*/STARTED,/*** Resumed state for a LifecycleOwner. For an {@link android.app.Activity}, this state* is reached after {@link android.app.Activity#onResume() onResume} is called.*/RESUMED;/*** Compares if this State is greater or equal to the given {@code state}.** @param state State to compare with* @return true if this State is greater or equal to the given {@code state}*/public boolean isAtLeast(@NonNull State state) {return compareTo(state) >= 0;}}
}

从源码可以得知Lifecycle定义了三个方法和两个枚举:
三个方法:
1、addObserver 用于添加观察者
2、removeObserver 用于移除观察者
3、获取当前的状态
两个枚举:
1、Event 事件
2、State 状态

宿主的生命周期和状态转换的模型图如下:
在这里插入图片描述

1.2、直接子类LifecycleRegistry

1.2.1 源码

package androidx.lifecycle;import static androidx.lifecycle.Lifecycle.State.DESTROYED;
import static androidx.lifecycle.Lifecycle.State.INITIALIZED;import android.annotation.SuppressLint;import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.arch.core.executor.ArchTaskExecutor;
import androidx.arch.core.internal.FastSafeIterableMap;import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;public class LifecycleRegistry extends Lifecycle {private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =new FastSafeIterableMap<>();private State mState;//弱引用宿主对象private final WeakReference<LifecycleOwner> mLifecycleOwner;private int mAddingObserverCounter = 0;private boolean mHandlingEvent = false;private boolean mNewEventOccurred = false;private ArrayList<State> mParentStates = new ArrayList<>();private final boolean mEnforceMainThread;public LifecycleRegistry(@NonNull LifecycleOwner provider) {this(provider, true);}private LifecycleRegistry(@NonNull LifecycleOwner provider, boolean enforceMainThread) {mLifecycleOwner = new WeakReference<>(provider);mState = INITIALIZED;mEnforceMainThread = enforceMainThread;}@Deprecated@MainThreadpublic void markState(@NonNull State state) {enforceMainThreadIfNeeded("markState");setCurrentState(state);}//设置当前状态@MainThreadpublic void setCurrentState(@NonNull State state) {enforceMainThreadIfNeeded("setCurrentState");moveToState(state);}//处理生命周期事件public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {enforceMainThreadIfNeeded("handleLifecycleEvent");moveToState(event.getTargetState());}//状态转移private void moveToState(State next) {if (mState == next) {return;}if (mState == INITIALIZED && next == DESTROYED) {throw new IllegalStateException("no event down from " + mState);}mState = next;if (mHandlingEvent || mAddingObserverCounter != 0) {mNewEventOccurred = true;// we will figure out what to do on upper level.return;}mHandlingEvent = true;sync();mHandlingEvent = false;if (mState == DESTROYED) {mObserverMap = new FastSafeIterableMap<>();}}//是否同步private boolean isSynced() {if (mObserverMap.size() == 0) {return true;}State eldestObserverState = mObserverMap.eldest().getValue().mState;State newestObserverState = mObserverMap.newest().getValue().mState;return eldestObserverState == newestObserverState && mState == newestObserverState;}//计算目标状态private State calculateTargetState(LifecycleObserver observer) {Map.Entry<LifecycleObserver, ObserverWithState> previous = mObserverMap.ceil(observer);State siblingState = previous != null ? previous.getValue().mState : null;State parentState = !mParentStates.isEmpty() ? mParentStates.get(mParentStates.size() - 1): null;return min(min(mState, siblingState), parentState);}//增加观察者@Overridepublic void addObserver(@NonNull LifecycleObserver observer) {enforceMainThreadIfNeeded("addObserver");State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);if (previous != null) {return;}LifecycleOwner lifecycleOwner = mLifecycleOwner.get();if (lifecycleOwner == null) {// it is null we should be destroyed. Fallback quicklyreturn;}boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;State targetState = calculateTargetState(observer);mAddingObserverCounter++;while ((statefulObserver.mState.compareTo(targetState) < 0&& mObserverMap.contains(observer))) {pushParentState(statefulObserver.mState);final Event event = Event.upFrom(statefulObserver.mState);if (event == null) {throw new IllegalStateException("no event up from " + statefulObserver.mState);}statefulObserver.dispatchEvent(lifecycleOwner, event);popParentState();// mState / subling may have been changed recalculatetargetState = calculateTargetState(observer);}if (!isReentrance) {// we do sync only on the top level.sync();}mAddingObserverCounter--;}private void popParentState() {mParentStates.remove(mParentStates.size() - 1);}private void pushParentState(State state) {mParentStates.add(state);}//移除观察者@Overridepublic void removeObserver(@NonNull LifecycleObserver observer) {enforceMainThreadIfNeeded("removeObserver");mObserverMap.remove(observer);}//获取观察者数量@SuppressWarnings("WeakerAccess")public int getObserverCount() {enforceMainThreadIfNeeded("getObserverCount");return mObserverMap.size();}//获取当前状态@NonNull@Overridepublic State getCurrentState() {return mState;}//升级状态private void forwardPass(LifecycleOwner lifecycleOwner) {Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =mObserverMap.iteratorWithAdditions();while (ascendingIterator.hasNext() && !mNewEventOccurred) {Map.Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred&& mObserverMap.contains(entry.getKey()))) {pushParentState(observer.mState);final Event event = Event.upFrom(observer.mState);if (event == null) {throw new IllegalStateException("no event up from " + observer.mState);}observer.dispatchEvent(lifecycleOwner, event);popParentState();}}}//降级状态private void backwardPass(LifecycleOwner lifecycleOwner) {Iterator<Map.Entry<LifecycleObserver, ObserverWithState>> descendingIterator =mObserverMap.descendingIterator();while (descendingIterator.hasNext() && !mNewEventOccurred) {Map.Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();ObserverWithState observer = entry.getValue();while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred&& mObserverMap.contains(entry.getKey()))) {Event event = Event.downFrom(observer.mState);if (event == null) {throw new IllegalStateException("no event down from " + observer.mState);}pushParentState(event.getTargetState());observer.dispatchEvent(lifecycleOwner, event);popParentState();}}}//同步状态private void sync() {LifecycleOwner lifecycleOwner = mLifecycleOwner.get();if (lifecycleOwner == null) {throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"+ "garbage collected. It is too late to change lifecycle state.");}while (!isSynced()) {mNewEventOccurred = false;// no need to check eldest for nullability, because isSynced does it for us.if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {backwardPass(lifecycleOwner);}Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();if (!mNewEventOccurred && newest != null&& mState.compareTo(newest.getValue().mState) > 0) {forwardPass(lifecycleOwner);}}mNewEventOccurred = false;}@SuppressLint("RestrictedApi")private void enforceMainThreadIfNeeded(String methodName) {if (mEnforceMainThread) {if (!ArchTaskExecutor.getInstance().isMainThread()) {throw new IllegalStateException("Method " + methodName + " must be called on the "+ "main thread");}}}@VisibleForTesting@NonNullpublic static LifecycleRegistry createUnsafe(@NonNull LifecycleOwner owner) {return new LifecycleRegistry(owner, false);}static State min(@NonNull State state1, @Nullable State state2) {return state2 != null && state2.compareTo(state1) < 0 ? state2 : state1;}//带有状态信息的观察者static class ObserverWithState {State mState;LifecycleEventObserver mLifecycleObserver;ObserverWithState(LifecycleObserver observer, State initialState) {mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);mState = initialState;}void dispatchEvent(LifecycleOwner owner, Event event) {State newState = event.getTargetState();mState = min(mState, newState);mLifecycleObserver.onStateChanged(owner, event);mState = newState;}}
}

该类实现了对观察者的增加和删除、状态的同步以及状态改变后对观察者的状态变化通知。

二、LifecycleObserver(生命周期观察者)

在这里插入图片描述

2.1、LifecycleObserver

package androidx.lifecycle;/*** Marks a class as a LifecycleObserver. Don't use this interface directly. Instead implement either* {@link DefaultLifecycleObserver} or {@link LifecycleEventObserver} to be notified about* lifecycle events.** @see Lifecycle Lifecycle - for samples and usage patterns.*/
@SuppressWarnings("WeakerAccess")
public interface LifecycleObserver {}

2.2、FullLifecycleObserver

package androidx.lifecycle;interface FullLifecycleObserver extends LifecycleObserver {void onCreate(LifecycleOwner owner);void onStart(LifecycleOwner owner);void onResume(LifecycleOwner owner);void onPause(LifecycleOwner owner);void onStop(LifecycleOwner owner);void onDestroy(LifecycleOwner owner);
}

FullLifecycleObserver定义了所有生命周期的事件,如果我们实现了该接口,就要重写所有的事件方法

2.3、DefaultLifecycleObserver

package androidx.lifecycle;import androidx.annotation.NonNull;@SuppressWarnings("unused")
public interface DefaultLifecycleObserver extends FullLifecycleObserver {@Overridedefault void onCreate(@NonNull LifecycleOwner owner) {}@Overridedefault void onStart(@NonNull LifecycleOwner owner) {}@Overridedefault void onResume(@NonNull LifecycleOwner owner) {}@Overridedefault void onPause(@NonNull LifecycleOwner owner) {}@Overridedefault void onStop(@NonNull LifecycleOwner owner) {}@Overridedefault void onDestroy(@NonNull LifecycleOwner owner) {}
}

FullLifecycleObserver定义了生命周期的所有事件方法,为了不用重写所有的方法,就新增了DefaultLifecycleObserver接口,该接口继承了FullLifecycleObserver,并且重写了所有的事件函数,这样我们在自定义LifecycleObserver的时候可以直接实现DefaultLifecycleObserver重写需要用到的事件函数即可

2.4、LifecycleEventObserver

package androidx.lifecycle;import androidx.annotation.NonNull;public interface LifecycleEventObserver extends LifecycleObserver {void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);
}

如果一个自定义观察者既实现了LifecycleEventObserver接口,也实现了DefaultLifecycleObserver接口,当宿主的生命周期有变化的时候,会优先调用DefaultLifecycleObserver的方法,然后再调用LifecycleEventObserver的onStateChanged方法

2.4.1 示例

package com.anniljing.lifecyclecorestudy;import android.util.Log;import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;public class MyObserver implements DefaultLifecycleObserver, LifecycleEventObserver {private static final String TAG="MyObserver";@Overridepublic void onCreate(@NonNull LifecycleOwner owner) {Log.e(TAG,"DefaultLifecycleObserver onCreate");}@Overridepublic void onStart(@NonNull LifecycleOwner owner) {Log.e(TAG,"DefaultLifecycleObserver onStart");}@Overridepublic void onResume(@NonNull LifecycleOwner owner) {Log.e(TAG,"DefaultLifecycleObserver onResume");}@Overridepublic void onStop(@NonNull LifecycleOwner owner) {Log.e(TAG,"DefaultLifecycleObserver onStop");}@Overridepublic void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {Log.e(TAG,"LifecycleEventObserver onStateChanged:"+event.name());}
}

在这里插入图片描述

三、LifecycleOwner(生命周期宿主)

3.1、源码

@SuppressWarnings({"WeakerAccess", "unused"})
public interface LifecycleOwner {/*** Returns the Lifecycle of the provider.** @return The lifecycle of the provider.*/@NonNullLifecycle getLifecycle();
}

为宿主返回一个Lifecycle。

四、Fragment实现

在这里插入图片描述

  • 在Fragment的构造方法里面,创建了LifecycleRegistry
  • 在performCreate里面首先注册了一个LifecycleEventObserver观察者,重写了onStateChanged方法,用来接收Fragment的生命周期的状态,这样就完成了观察者的注册
  • 在performCreate里面调用onCreate方法
  • 后续就是Fragment生命周期变化时,通知LifecycleObserver的过程:Fragment的performXXX()、onXXX()方法;LifecycleRegistry的handleLifecycleEvent()方法;LifecycleObserver的onStateChanged()方法
  • LifecycleRegistry里面通过调用sync方法,通过比较大小的方式,来判断是状态升级,还是状态降级,来调整后面的状态
private void sync() {LifecycleOwner lifecycleOwner = mLifecycleOwner.get();if (lifecycleOwner == null) {throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"+ "garbage collected. It is too late to change lifecycle state.");}while (!isSynced()) {mNewEventOccurred = false;//如果下一个状态小于最早的,则说明要降级if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {backwardPass(lifecycleOwner);}Map.Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();//如果下一个状态的值大于最新的,则说明需要升级if (!mNewEventOccurred && newest != null&& mState.compareTo(newest.getValue().mState) > 0) {forwardPass(lifecycleOwner);}}mNewEventOccurred = false;}

五、Activity的实现

onCreate()

protected void onCreate(@Nullable Bundle savedInstanceState) {// Restore the Saved State first so that it is available to// OnContextAvailableListener instancesmSavedStateRegistryController.performRestore(savedInstanceState);mContextAwareHelper.dispatchOnContextAvailable(this);super.onCreate(savedInstanceState);ReportFragment.injectIfNeededIn(this);if (BuildCompat.isAtLeastT()) {mOnBackPressedDispatcher.setOnBackInvokedDispatcher(Api33Impl.getOnBackInvokedDispatcher(this));}if (mContentLayoutId != 0) {setContentView(mContentLayoutId);}}

ReportFragment.injectIfNeededIn()

public static void injectIfNeededIn(Activity activity) {if (Build.VERSION.SDK_INT >= 29) {// On API 29+, we can register for the correct Lifecycle callbacks directlyLifecycleCallbacks.registerIn(activity);}// Prior to API 29 and to maintain compatibility with older versions of// ProcessLifecycleOwner (which may not be updated when lifecycle-runtime is updated and// need to support activities that don't extend from FragmentActivity from support lib),// use a framework fragment to get the correct timing of Lifecycle eventsandroid.app.FragmentManager manager = activity.getFragmentManager();if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();// Hopefully, we are the first to make a transaction.manager.executePendingTransactions();}}

Activity源码中,把宿主的生命周期的感知放到了ReportFragment里面,Fragment是依附在activity的,能够同步到Activity的生命周期的事件。

六、示例

6.1、MyObserver

package com.anniljing.lifecyclecorestudy;import android.util.Log;import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;public class MyObserver implements DefaultLifecycleObserver, LifecycleEventObserver {private static final String TAG="MyObserver";@Overridepublic void onCreate(@NonNull LifecycleOwner owner) {Log.e(TAG,"DefaultLifecycleObserver onCreate");}@Overridepublic void onStart(@NonNull LifecycleOwner owner) {Log.e(TAG,"DefaultLifecycleObserver onStart");}@Overridepublic void onResume(@NonNull LifecycleOwner owner) {Log.e(TAG,"DefaultLifecycleObserver onResume");}@Overridepublic void onStop(@NonNull LifecycleOwner owner) {Log.e(TAG,"DefaultLifecycleObserver onStop");}@Overridepublic void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {Log.e(TAG,"LifecycleEventObserver onStateChanged:"+event.name());}
}

6.2、LifecycleMainActivity

package com.anniljing.lifecyclecorestudy;import android.os.Bundle;import androidx.appcompat.app.AppCompatActivity;public class LifecycleMainActivity extends AppCompatActivity {private MyObserver mObserver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mObserver = new MyObserver();getLifecycle().addObserver(mObserver);}
}

在这里插入图片描述
自定义的MyObserver 实现了DefaultLifecycleObserver,同时也实现了LifecycleEventObserver,从打印结果验证了如果既实现了DefaultLifecycleObserver,也实现了LifecycleEventObserver,会优先调用DefaultLifecycleObserver的事件回调,后面才调用LifecycleEventObserver的onStateChanged

http://www.rdtb.cn/news/17296.html

相关文章:

  • 电脑做科目一网站网站建站模板
  • 百雀羚网站建设模版许昌网络推广外包
  • 直接用源码做网站盗版吗seo咨询邵阳
  • 网站建设优化推广贵州国内最新新闻热点事件
  • 网站弹窗无法显示网络的推广方式有哪些
  • 阿里巴巴外贸网站登录佛山做优化的网络公司
  • 虚拟产品网站企业推广平台排行榜
  • 网站顶部轮播怎么做的茂名seo顾问服务
  • 全国住房和城乡建设部网站找关键词的三种方法
  • 青白江做网站的公司东莞百度seo推广公司
  • 网站维护成本武汉大学人民医院院长
  • 建筑公司经营范围参考优化外包哪里好
  • 房产类网站制作商营销推广软文案例
  • 临清网站制作百度一下官网首页登录
  • 广州网站建设公司哪家好google网站搜索
  • 武汉企业建站程序沧州网络推广公司
  • 历下区网站建设公司免费网站服务器
  • html5教育网站steam交易链接在哪
  • 云南红舰工贸有限公司的网站建设打开2345网址大全
  • 做微网站 主机 域名市场调研报告万能模板
  • 网站开发中可能遇到的技术问题怎样才能在百度上发布信息
  • 有帮忙做网站的吗品牌广告和效果广告
  • 万网网站电话建立免费个人网站
  • 织梦摄影网站模板自己做网站建设
  • 网站建设分享文章晚上免费b站软件
  • 新余服装网站建设东莞建设企业网站
  • 网站开发 语音交换链接的其它叫法是
  • wordpress 评论群发seo和sem分别是什么
  • 上海金融网站制作公河南省疫情最新情况
  • 定制网站公司哪家好谷歌自然排名优化