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

吐鲁番seo招聘惠州seo关键词

吐鲁番seo招聘,惠州seo关键词,南京网络建站模板,秦皇岛网站建设seo一、引言 在 Android 开发中,图片加载是一个常见且重要的功能。Glide 作为一款强大的图片加载库,因其高效、灵活和易于使用的特点,被广泛应用于各种 Android 应用中。Glide 的配置与初始化模块是整个库的基础,它允许开发者根据不…

一、引言

在 Android 开发中,图片加载是一个常见且重要的功能。Glide 作为一款强大的图片加载库,因其高效、灵活和易于使用的特点,被广泛应用于各种 Android 应用中。Glide 的配置与初始化模块是整个库的基础,它允许开发者根据不同的需求对 Glide 进行定制化设置,如缓存策略、图片解码格式、自定义组件等。本文将深入 Glide 源码,详细剖析其配置与初始化模块的实现原理和工作流程。

二、配置与初始化模块概述

2.1 模块的作用

Glide 的配置与初始化模块主要负责以下几个方面的工作:

  • 全局配置:允许开发者对 Glide 的各种行为进行全局配置,如设置缓存大小、自定义组件等。
  • 组件注册:开发者可以通过该模块注册自定义的组件,如 ModelLoaderResourceDecoder 等,以支持新的数据源和图片格式。
  • 生命周期管理:确保 Glide 与应用的生命周期进行正确的绑定,避免内存泄漏。

2.2 核心组件

该模块的核心组件包括:

  • GlideBuilder:用于构建 Glide 实例,提供了一系列方法来设置 Glide 的各种配置。
  • GlideModule(在 Glide 4.x 及以后版本为 AppGlideModuleLibraryGlideModule):提供了一种在应用启动时配置 Glide 的方式,开发者可以在 GlideModule 中注册自定义的组件、修改默认配置等。
  • Glide:Glide 库的核心类,负责管理图片加载请求、缓存、线程池等。

2.3 整体架构

Glide 配置与初始化模块的整体架构可以分为以下几个层次:

  1. 应用层:开发者在应用代码中调用 Glide 的初始化方法,并进行相关配置。
  2. 配置层GlideBuilderGlideModule 负责接收开发者的配置信息,并进行相应的设置。
  3. 核心层Glide 类根据配置信息进行初始化,创建各种组件和服务。

三、GlideBuilder 源码分析

3.1 类定义及属性

java

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Registry;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.Engine;
import com.bumptech.glide.load.engine.cache.DiskCache;
import com.bumptech.glide.load.engine.cache.DiskCacheFactory;
import com.bumptech.glide.load.engine.cache.MemoryCache;
import com.bumptech.glide.load.engine.cache.M.cache.MemorySizeCalculator;
import com.bumptech.glide.load.engine.executor.GlideExecutor;
import com.bumptech.glide.manager.ConnectivityMonitorFactory;
import com.bumptech.glide.manager.DefaultConnectivityMonitorFactory;
import com.bumptech.glide.manager.Lifecycle;
import com.bumptech.glide.manager.RequestManagerRetriever;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.ViewTarget;
import com.bumptech.glide.util.Preconditions;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;// GlideBuilder 类,用于构建 Glide 实例
public final class GlideBuilder {// 应用上下文private final Context context;// 内存缓存工厂private MemoryCache.Factory memoryCacheFactory;// 磁盘缓存工厂private DiskCache.Factory diskCacheFactory;// 引擎工厂private Engine.Factory engineFactory;// 解码格式private DecodeFormat decodeFormat = DecodeFormat.DEFAULT;// 默认的请求选项private RequestOptions defaultRequestOptions = new RequestOptions();// 连接监控工厂private ConnectivityMonitorFactory connectivityMonitorFactory;// 后台线程池private GlideExecutor sourceExecutor;// 磁盘缓存线程池private GlideExecutor diskCacheExecutor;// 动画帧线程池private GlideExecutor animationExecutor;// 生命周期private Lifecycle lifecycle;// 请求管理器检索器private RequestManagerRetriever.RequestManagerFactory requestManagerFactory;// 视图目标的默认布局参数private ViewTarget.LayoutParamsFactory defaultLayoutParamsFactory;// 注册表,用于注册各种组件private final Registry registry = new Registry();// 全局日志级别private int logLevel = android.util.Log.DEBUG;// 动画处理类private Handler mainHandler;// 内存大小计算器private MemorySizeCalculator memorySizeCalculator;// 组件清单解析器private final List<com.bumptech.glide.module.GlideModule> manifestModules = new ArrayList<>();// 自定义的 Glide 模块private com.bumptech.glide.module.GlideModule customModule;
}

GlideBuilder 类中,定义了一系列属性,用于存储 Glide 的各种配置信息。这些属性包括内存缓存工厂、磁盘缓存工厂、引擎工厂、解码格式、默认请求选项等。通过这些属性,开发者可以对 Glide 的各个方面进行定制化配置。

3.2 构造函数

java

/*** 构造函数,初始化 GlideBuilder 实例* * @param context 应用上下文*/
GlideBuilder(@NonNull Context context) {// 保存应用上下文this.context = context.getApplicationContext();
}

构造函数接收一个 Context 对象,并将其转换为应用上下文进行保存。这是为了避免因传入的 Context 生命周期过短而导致的内存泄漏问题。

3.3 配置方法

3.3.1 内存缓存配置

java

/*** 设置内存缓存工厂* * @param memoryCacheFactory 内存缓存工厂* @return GlideBuilder 实例,用于链式调用*/
@NonNull
public GlideBuilder setMemoryCache(@NonNull MemoryCache.Factory memoryCacheFactory) {// 检查传入的内存缓存工厂是否为空this.memoryCacheFactory = Preconditions.checkNotNull(memoryCacheFactory);return this;
}

setMemoryCache 方法用于设置内存缓存工厂。开发者可以通过该方法自定义内存缓存的实现,例如使用自定义的 LruResourceCache 或其他内存缓存策略。

3.3.2 磁盘缓存配置

java

/*** 设置磁盘缓存工厂* * @param diskCacheFactory 磁盘缓存工厂* @return GlideBuilder 实例,用于链式调用*/
@NonNull
public GlideBuilder setDiskCache(@NonNull DiskCache.Factory diskCacheFactory) {// 检查传入的磁盘缓存工厂是否为空this.diskCacheFactory = Preconditions.checkNotNull(diskCacheFactory);return this;
}

setDiskCache 方法用于设置磁盘缓存工厂。开发者可以通过该方法自定义磁盘缓存的实现,例如使用自定义的 DiskLruCacheWrapper 或其他磁盘缓存策略。

3.3.3 引擎配置

java

/*** 设置引擎工厂* * @param engineFactory 引擎工厂* @return GlideBuilder 实例,用于链式调用*/
@NonNull
public GlideBuilder setEngine(@NonNull Engine.Factory engineFactory) {// 检查传入的引擎工厂是否为空this.engineFactory = Preconditions.checkNotNull(engineFactory);return this;
}

setEngine 方法用于设置引擎工厂。引擎是 Glide 的核心组件之一,负责管理图片的加载、缓存和资源回收等操作。开发者可以通过该方法自定义引擎的实现。

3.3.4 解码格式配置

java

/*** 设置解码格式* * @param decodeFormat 解码格式* @return GlideBuilder 实例,用于链式调用*/
@NonNull
public GlideBuilder setDecodeFormat(@NonNull DecodeFormat decodeFormat) {// 检查传入的解码格式是否为空this.decodeFormat = Preconditions.checkNotNull(decodeFormat);return this;
}

setDecodeFormat 方法用于设置图片的解码格式。不同的解码格式会影响图片的质量和内存占用,开发者可以根据实际需求选择合适的解码格式。

3.3.5 默认请求选项配置

java

/*** 设置默认的请求选项* * @param defaultRequestOptions 默认请求选项* @return GlideBuilder 实例,用于链式调用*/
@NonNull
public GlideBuilder setDefaultRequestOptions(@NonNull RequestOptions defaultRequestOptions) {// 检查传入的默认请求选项是否为空this.defaultRequestOptions = Preconditions.checkNotNull(defaultRequestOptions);return this;
}

setDefaultRequestOptions 方法用于设置默认的请求选项。默认请求选项会应用到所有的图片加载请求中,开发者可以通过该方法设置一些通用的请求参数,如占位图、错误图等。

3.3.6 连接监控工厂配置

java

/*** 设置连接监控工厂* * @param factory 连接监控工厂* @return GlideBuilder 实例,用于链式调用*/
@NonNull
public GlideBuilder setConnectivityMonitorFactory(@NonNull ConnectivityMonitorFactory factory) {// 检查传入的连接监控工厂是否为空this.connectivityMonitorFactory = Preconditions.checkNotNull(factory);return this;
}

setConnectivityMonitorFactory 方法用于设置连接监控工厂。连接监控工厂用于创建连接监控器,监控网络连接状态的变化,以便在网络连接可用时自动恢复图片加载任务。

3.3.7 线程池配置

java

/*** 设置后台线程池* * @param sourceExecutor 后台线程池* @return GlideBuilder 实例,用于链式调用*/
@NonNull
public GlideBuilder setSourceExecutor(@NonNull GlideExecutor sourceExecutor) {// 检查传入的后台线程池是否为空this.sourceExecutor = Preconditions.checkNotNull(sourceExecutor);return this;
}/*** 设置磁盘缓存线程池* * @param diskCacheExecutor 磁盘缓存线程池* @return GlideBuilder 实例,用于链式调用*/
@NonNull
public GlideBuilder setDiskCacheExecutor(@NonNull GlideExecutor diskCacheExecutor) {// 检查传入的磁盘缓存线程池是否为空this.diskCacheExecutor = Preconditions.checkNotNull(diskCacheExecutor);return this;
}/*** 设置动画帧线程池* * @param animationExecutor 动画帧线程池* @return GlideBuilder 实例,用于链式调用*/
@NonNull
public GlideBuilder setAnimationExecutor(@NonNull GlideExecutor animationExecutor) {// 检查传入的动画帧线程池是否为空this.animationExecutor = Preconditions.checkNotNull(animationExecutor);return this;
}

这些方法分别用于设置后台线程池、磁盘缓存线程池和动画帧线程池。不同的线程池用于执行不同类型的任务,如后台线程池用于执行网络请求和图片解码任务,磁盘缓存线程池用于执行磁盘缓存的读写任务,动画帧线程池用于执行动画帧的加载和处理任务。

3.3.8 其他配置方法

java

/*** 设置生命周期* * @param lifecycle 生命周期* @return GlideBuilder 实例,用于链式调用*/
@NonNull
public GlideBuilder setLifecycle(@NonNull Lifecycle lifecycle) {// 检查传入的生命周期是否为空this.lifecycle = Preconditions.checkNotNull(lifecycle);return this;
}/*** 设置请求管理器工厂* * @param factory 请求管理器工厂* @return GlideBuilder 实例,用于链式调用*/
@NonNull
public GlideBuilder setRequestManagerFactory(@NonNull RequestManagerRetriever.RequestManagerFactory factory) {// 检查传入的请求管理器工厂是否为空this.requestManagerFactory = Preconditions.checkNotNull(factory);return this;
}/*** 设置视图目标的默认布局参数工厂* * @param factory 视图目标的默认布局参数工厂* @return GlideBuilder 实例,用于链式调用*/
@NonNull
public GlideBuilder setDefaultLayoutParamsFactory(@NonNull ViewTarget.LayoutParamsFactory factory) {// 检查传入的视图目标的默认布局参数工厂是否为空this.defaultLayoutParamsFactory = Preconditions.checkNotNull(factory);return this;
}/*** 设置全局日志级别* * @param logLevel 全局日志级别* @return GlideBuilder 实例,用于链式调用*/
@NonNull
public GlideBuilder setLogLevel(int logLevel) {this.logLevel = logLevel;return this;
}/*** 设置动画处理类* * @param mainHandler 动画处理类* @return GlideBuilder 实例,用于链式调用*/
@NonNull
public GlideBuilder setMainHandler(@NonNull Handler mainHandler) {// 检查传入的动画处理类是否为空this.mainHandler = Preconditions.checkNotNull(mainHandler);return this;
}

这些方法分别用于设置生命周期、请求管理器工厂、视图目标的默认布局参数工厂、全局日志级别和动画处理类。开发者可以通过这些方法对 Glide 的各个方面进行更细致的配置。

3.4 构建 Glide 实例

java

/*** 构建 Glide 实例* * @return Glide 实例*/
@NonNull
public Glide build(@NonNull Context context) {// 如果未设置后台线程池,使用默认的后台线程池if (sourceExecutor == null) {sourceExecutor = GlideExecutor.newSourceExecutor();}// 如果未设置磁盘缓存线程池,使用默认的磁盘缓存线程池if (diskCacheExecutor == null) {diskCacheExecutor = GlideExecutor.newDiskCacheExecutor();}// 如果未设置动画帧线程池,使用默认的动画帧线程池if (animationExecutor == null) {animationExecutor = GlideExecutor.newAnimationExecutor();}// 如果未设置内存大小计算器,创建一个默认的内存大小计算器if (memorySizeCalculator == null) {memorySizeCalculator = new MemorySizeCalculator.Builder(context).build();}// 如果未设置内存缓存工厂,使用默认的内存缓存工厂if (memoryCacheFactory == null) {memoryCacheFactory = new LruResourceCache.Factory(memorySizeCalculator.getMemoryCacheSize());}// 如果未设置磁盘缓存工厂,使用默认的磁盘缓存工厂if (diskCacheFactory == null) {diskCacheFactory = new InternalCacheDiskCacheFactory(context);}// 如果未设置引擎工厂,使用默认的引擎工厂if (engineFactory == null) {engineFactory = new Engine.Factory(diskCacheFactory, diskCacheExecutor, sourceExecutor);}// 如果未设置连接监控工厂,使用默认的连接监控工厂if (connectivityMonitorFactory == null) {connectivityMonitorFactory = new DefaultConnectivityMonitorFactory();}// 如果未设置动画处理类,创建一个默认的动画处理类if (mainHandler == null) {mainHandler = new Handler(Looper.getMainLooper());}// 创建引擎实例Engine engine = engineFactory.build(memoryCacheFactory.build(),diskCacheExecutor,sourceExecutor,animationExecutor,isActiveResourceRetentionAllowed);// 创建请求管理器检索器RequestManagerRetriever requestManagerRetriever = new RequestManagerRetriever(requestManagerFactory);// 创建 Glide 实例Glide glide = new Glide(context,engine,memoryCacheFactory.build(),diskCacheFactory,registry,animationExecutor,memorySizeCalculator,connectivityMonitorFactory,logLevel,defaultRequestOptions.lock(),defaultTransitionOptions,requestManagerRetriever,mainHandler,defaultLayoutParamsFactory);// 注册所有的 Glide 模块for (com.bumptech.glide.module.GlideModule module : manifestModules) {module.registerComponents(context, glide, registry);}if (customModule != null) {customModule.registerComponents(context, glide, registry);}return glide;
}

build 方法用于构建 Glide 实例。在该方法中,会检查各个配置项是否已经设置,如果未设置,则使用默认的配置。然后根据配置信息创建引擎、请求管理器检索器等组件,并最终创建 Glide 实例。最后,会注册所有的 GlideModule,以便对 Glide 进行进一步的配置和扩展。

四、GlideModule 源码分析

4.1 GlideModule 概述

在 Glide 4.x 及以后版本中,GlideModule 被拆分为 AppGlideModuleLibraryGlideModuleAppGlideModule 用于在应用级别进行配置,而 LibraryGlideModule 用于在库级别进行配置。

4.2 AppGlideModule 源码分析

4.2.1 类定义及属性

java

import android.content.Context;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Registry;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.AppGlideModule;// 标记该类为 AppGlideModule
@GlideModule
public class MyAppGlideModule extends AppGlideModule {// 可以在这里添加自定义的配置方法和属性
}

AppGlideModule 是一个抽象类,开发者需要创建一个继承自 AppGlideModule 的子类,并使用 @GlideModule 注解进行标记。

4.2.2 主要方法

java

@Override
public void applyOptions(@NonNull Context context, @NonNull GlideBuilder builder) {// 在这里可以对 GlideBuilder 进行配置builder.setMemoryCache(new LruResourceCache(10 * 1024 * 1024)); // 设置内存缓存大小为 10MBbuilder.setDiskCache(new ExternalCacheDiskCacheFactory(context, 50 * 1024 * 1024)); // 设置磁盘缓存大小为 50MB
}@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {// 在这里可以注册自定义的组件registry.append(MyModel.class, InputStream.class, new MyModelLoader.Factory());
}@Override
public boolean isManifestParsingEnabled() {// 是否启用组件清单解析return false;
}
  • applyOptions 方法:用于对 GlideBuilder 进行配置,开发者可以在该方法中设置内存缓存、磁盘缓存、解码格式等配置信息。
  • registerComponents 方法:用于注册自定义的组件,如 ModelLoaderResourceDecoder 等。通过该方法,开发者可以扩展 Glide 的功能,支持新的数据源和图片格式。
  • isManifestParsingEnabled 方法:用于控制是否启用组件清单解析。在 Glide 4.x 及以后版本中,建议将该方法返回 false,以避免组件清单解析带来的性能开销。

4.3 LibraryGlideModule 源码分析

4.3.1 类定义及属性

java

import android.content.Context;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Registry;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.module.LibraryGlideModule;// 标记该类为 LibraryGlideModule
@GlideModule
public class MyLibraryGlideModule extends LibraryGlideModule {// 可以在这里添加自定义的配置方法和属性
}

LibraryGlideModule 也是一个抽象类,开发者需要创建一个继承自 LibraryGlideModule 的子类,并使用 @GlideModule 注解进行标记。

4.3.2 主要方法

java

@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {// 在这里可以注册自定义的组件registry.append(MyModel.class, InputStream.class, new MyModelLoader.Factory());
}

LibraryGlideModule 主要用于在库级别注册自定义的组件。与 AppGlideModule 不同的是,LibraryGlideModule 没有 applyOptions 方法,因为库级别通常不进行全局配置,而是专注于组件的注册。

五、Glide 初始化流程分析

5.1 初始化入口

在应用代码中,通常通过以下方式初始化 Glide:

java

GlideBuilder builder = new GlideBuilder(context);
Glide glide = builder.build(context);

或者使用 Glide.get(context) 方法,该方法会在内部调用 GlideBuilder 进行初始化:

java

Glide glide = Glide.get(context);

5.2 初始化流程

  1. 创建 GlideBuilder 实例:在初始化过程中,首先会创建一个 GlideBuilder 实例,用于接收和保存配置信息。
  2. 配置 GlideBuilder:开发者可以通过 GlideBuilder 的各种配置方法,对 Glide 的内存缓存、磁盘缓存、引擎、解码格式等进行配置。
  3. 注册 GlideModule:在 build 方法中,会注册所有的 GlideModule,包括 AppGlideModuleLibraryGlideModule。在 GlideModule 中,开发者可以对 GlideBuilder 进行进一步的配置,或者注册自定义的组件。
  4. 创建核心组件:根据配置信息,build 方法会创建引擎、请求管理器检索器等核心组件。
  5. 创建 Glide 实例:最后,build 方法会创建 Glide 实例,并将配置信息和核心组件传递给 Glide 实例。

5.3 初始化流程的源码分析

java

// Glide 类中的 get 方法
public static Glide get(@NonNull Context context) {// 检查传入的上下文是否为空if (glide == null) {synchronized (Glide.class) {if (glide == null) {// 获取应用上下文Context applicationContext = context.getApplicationContext();// 获取组件清单解析器List<com.bumptech.glide.module.GlideModule> manifestModules = new ManifestParser(applicationContext).parse();// 创建 GlideBuilder 实例GlideBuilder builder = new GlideBuilder(applicationContext);// 创建 AppGlideModule 实例AppGlideModule appGlideModule = new GeneratedAppGlideModuleImpl();// 应用 AppGlideModule 中的配置appGlideModule.applyOptions(applicationContext, builder);// 注册 LibraryGlideModule 中的组件for (com.bumptech.glide.module.GlideModule module : manifestModules) {module.registerComponents(applicationContext, builder, builder.getRegistry());}// 注册 AppGlideModule 中的组件appGlideModule.registerComponents(applicationContext, builder, builder.getRegistry());// 构建 Glide 实例glide = builder.build(applicationContext);}}}return glide;
}

get 方法中,会首先检查 Glide 实例是否已经创建。如果未创建,则会进行以下操作:

  1. 获取应用上下文。
  2. 使用 ManifestParser 解析组件清单,获取所有的 LibraryGlideModule
  3. 创建 GlideBuilder 实例。
  4. 创建 AppGlideModule 实例,并调用其 applyOptions 方法对 GlideBuilder 进行配置。
  5. 注册所有 LibraryGlideModuleAppGlideModule 中的组件。
  6. 调用 GlideBuilderbuild 方法构建 Glide 实例。

六、自定义配置和组件注册

6.1 自定义内存缓存

开发者可以通过 GlideBuildersetMemoryCache 方法自定义内存缓存。以下是一个自定义内存缓存的示例:

java

// 自定义内存缓存工厂
class MyMemoryCacheFactory implements MemoryCache.Factory {@Overridepublic MemoryCache build() {return new LruResourceCache(20 * 1024 * 1024); // 设置内存缓存大小为 20MB}
}// 在应用代码中使用自定义内存缓存
GlideBuilder builder = new GlideBuilder(context);
builder.setMemoryCache(new MyMemoryCacheFactory());
Glide glide = builder.build(context);

在这个示例中,我们创建了一个自定义的内存缓存工厂 MyMemoryCacheFactory,并在 build 方法中返回一个 LruResourceCache 实例,设置其大小为 20MB。然后通过 GlideBuildersetMemoryCache 方法使用该自定义内存缓存工厂。

6.2 自定义磁盘缓存

开发者可以通过 GlideBuildersetDiskCache 方法自定义磁盘缓存。以下是一个自定义磁盘缓存的示例:

java

// 自定义磁盘缓存工厂
class MyDiskCacheFactory implements DiskCache.Factory {@Overridepublic DiskCache build() {return DiskLruCacheWrapper.create(new File(context.getExternalCacheDir(), "my_cache"),
http://www.dtcms.com/wzjs/365558.html

相关文章:

  • 东光有做网站的吗图片百度搜索
  • 网站开发多少钱一天是百度安装到桌面
  • 株洲市怎么seo快速排名
  • com网站建设中北京网络推广公司wyhseo
  • 网站网页的滚动字幕怎么做网站是怎么建立起来的
  • 我想花钱做网站企业建站平台
  • 俄罗斯乌克兰战争北京优化网站推广
  • app和网站的关系凡科网怎么建网站
  • 网站制作 青岛抖音关键词排名优化软件
  • 上海网站制作公司百度搜索引擎优化方案
  • 小企业网站建设包含哪些网站自然排名工具
  • 成都住建局官网租房sem优化
  • 政府网站建设规划署seo页面如何优化
  • 指点成金网发帖推广网站seo诊断分析报告
  • 做按摩网站优化怎么做好推广和营销
  • 长沙官网网站推广优化排名优化公司哪家好
  • 怎么做网站劳务中介进入百度首页
  • java做网站吗石家庄百度推广排名优化
  • 网站的全栈建设营销型网站建设优化建站
  • 萍乡网站建设公司最近新闻热点
  • 网站都需要备案吗长尾关键词挖掘爱站工具
  • 如何做点对点视频网站网络公司优化关键词
  • 高度国际装饰公司官网处理事件seo软件
  • 开封网站优化公司郴州网站建设网络推广渠道
  • 珠海响应式网站建设网站手机版排名seo
  • 网站建设与维护属于什么岗位知名网页设计公司
  • 做刷单哪个网站找小白搜索引擎营销方法有哪些
  • 政府网站制作平台山东百度推广代理商
  • dede5.7网站搬家seo岗位工作内容
  • php网页设计优化网站标题名词解释