Android 組件化】路由組件 ( 組件間共享的服務(wù) )

      網(wǎng)友投稿 868 2025-03-31

      文章目錄

      一、組件間共享的服務(wù)

      二、注解處理器添加對上述 " 組件間共享的服務(wù) " 的支持

      三、注解處理器 生成代碼規(guī)則

      四、完整注解處理器代碼 及 生成的 Java 代碼

      1、注解處理器代碼

      2、app 模塊中的注解類生成的 Java 源碼

      3、library2 模塊中的注解類生成的 Java 源碼

      五、博客資源

      組件化系列博客 :

      【Android 組件化】從模塊化到組件化

      【Android 組件化】使用 Gradle 實現(xiàn)組件化 ( Gradle 變量定義與使用 )

      【Android 組件化】使用 Gradle 實現(xiàn)組件化 ( 組件模式與集成模式切換 )

      【Android 組件化】使用 Gradle 實現(xiàn)組件化 ( 組件 / 集成模式下的 Library Module 開發(fā) )

      【Android 組件化】路由組件 ( 路由組件結(jié)構(gòu) )

      【Android 組件化】路由組件 ( 注解處理器獲取被注解的節(jié)點 )

      【Android 組件化】路由組件 ( 注解處理器中使用 JavaPoet 生成代碼 )

      【Android 組件化】路由組件 ( 注解處理器參數(shù)選項設(shè)置 )

      【Android 組件化】路由組件 ( 構(gòu)造路由表中的路由信息 )

      【Android 組件化】路由組件 ( 使用 JavaPoet 生成路由表類 )

      一、組件間共享的服務(wù)

      路由除了支持 Activity 之外 , 還要支持 組件間共享的服務(wù) 如 工具類 , 邏輯功能 等 ;

      注意 : 這里的 " 組件間共享的服務(wù) "

      不是 4 4 4 大組件中的 Service 組件

      , 是

      任意的 , 實現(xiàn)了 IService 接口的 Java 類

      , 可以是工具類 , 業(yè)務(wù)邏輯 , 等等 ;

      定義空的接口 IService , 令 需要共享的服務(wù)類 實現(xiàn)接口 , 該接口沒有實際的意義 , 僅用于標記該接口需要納入路由組件管理 , 起標記作用 ;

      package kim.hsl.route_core.template; /** * 需要跨組件通信的服務(wù)需要實現(xiàn)該接口 * 用于標記服務(wù) */ public interface IService { }

      1

      2

      3

      4

      5

      6

      7

      8

      接口定義位置 :

      跨組件調(diào)用時 , 需要暴露出一個接口 , 接口必須實現(xiàn)上述 IService 接口 , 用于作為標識 , 注解處理器中 , 通過判斷該注解節(jié)點的類型是不是該接口的子類 , 如果是則生成 路由信息 , 加入到 路由表 中 ;

      IService 接口僅用與 標識 服務(wù)是否在 組件間共享 ;

      針對每個具體的服務(wù) , 還要在 底層依賴庫 中定義一系列的接口 , 這里的底層依賴庫是所有的 Module 組件都要依賴的 Android Library Module 依賴庫 ;

      在其中定義一個接口 ComponentService , 繼承 IService 接口 , 在該接口中定義一系列需要暴露的方法 ;

      package kim.hsl.base; import kim.hsl.route_core.template.IService; /** * 暴露一個接口 */ public interface ComponentService extends IService { void doSomething(); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      該接口定義位置 : 所有的組件都依賴 base 依賴庫 ;

      在具體的組件中 , 實現(xiàn)上述 ComponentService 接口 , 并添加 @Route 注解 ;

      package kim.hsl.library2; import android.util.Log; import kim.hsl.base.ComponentService; import kim.hsl.router_annotation.Route; @Route(path = "/library2/StringService") public class StringService implements ComponentService { @Override public void doSomething() { Log.i("StringService", "library2 組件中的 StringService 服務(wù) "); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      該類定義位置 : 在任意模塊都可以調(diào)用該類 ;

      二、注解處理器添加對上述 " 組件間共享的服務(wù) " 的支持

      之前在注解處理器中 , 只支持 android.app.Activity 的路由節(jié)點添加 ;

      // 獲取 android.app.Activity 類型的注解節(jié)點 TypeElement activityElement = mElementUtils.getTypeElement("android.app.Activity"); // 判斷 typeMirror 注解節(jié)點是否是 Activity 類型 if (mTypeUtils.isSubtype(element.asType(), activityElement.asType())) { // 該節(jié)點是 android.app.Activity 類型的 routeBean = new RouteBean( RouteBean.Type.ACTIVITY, // 路由對象類型 element, // 路由節(jié)點 null, // 類對象 route.path(), // 路由地址 route.group()); // 路由組 }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      當(dāng)前注解處理器中 , 支持 kim.hsl.route_core.template.IService 類型的 路由節(jié)點 添加 ;

      // 獲取 android.app.Activity 類型的注解節(jié)點 TypeElement activityElement = mElementUtils.getTypeElement("android.app.Activity"); // 獲取 組件間共享服務(wù) 的接口, 該接口僅用于表示組件類型 TypeElement iServiceElement = mElementUtils.getTypeElement("kim.hsl.route_core.template.IService"); // 判斷 typeMirror 注解節(jié)點是否是 Activity 類型 if (mTypeUtils.isSubtype(element.asType(), activityElement.asType())) { // 該節(jié)點是 android.app.Activity 類型的 routeBean = new RouteBean( RouteBean.Type.ACTIVITY, // 路由對象類型 element, // 路由節(jié)點 null, // 類對象 route.path(), // 路由地址 route.group()); // 路由組 }else if (mTypeUtils.isSubtype(element.asType(), iServiceElement.asType())) { // 該節(jié)點是 kim.hsl.route_core.template.IService 類型的 routeBean = new RouteBean( RouteBean.Type.ISERVICE, // 路由對象類型 element, // 路由節(jié)點 null, // 類對象 route.path(), // 路由地址 route.group()); // 路由組 }else{ // 該節(jié)點不是 android.app.Activity 類型的 throw new RuntimeException("@Route 注解節(jié)點類型錯誤"); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      三、注解處理器 生成代碼規(guī)則

      注解處理器的 process 方法調(diào)用 , 是按照 Module 模塊進行的 ;

      如果 Module 模塊中有相關(guān)注解 , 傳入的 Set set 參數(shù)不為空 , 就會進行相關(guān)處理 ;

      如果 Module 模塊中沒有相關(guān)注解 , 傳入的 Set set 參數(shù)為空 , 此時就不進行后續(xù)操作 ;

      下圖紅色的 library1 模塊中沒有注解 ;

      藍色的 library2 模塊中添加了 @Route(path = “/library2/StringService”) 注解 ;

      綠色的 app 模塊中添加了 @Route(path = “/app/MainActivity”) 注解 ;

      Module 模塊中 , 使用注解生成的源碼 , 都在對應(yīng)模塊的 " build\generated\ap_generated_sources\debug\out\ " 目錄中 ;

      四、完整注解處理器代碼 及 生成的 Java 代碼

      1、注解處理器代碼

      package kim.hsl.router_compiler; import com.google.auto.service.AutoService; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeSpec; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.TreeMap; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedOptions; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.tools.Diagnostic; import kim.hsl.router_annotation.Route; import kim.hsl.router_annotation.model.RouteBean; import static javax.lang.model.element.Modifier.PUBLIC; // 注解處理器接收的參數(shù) @SupportedOptions("moduleName") // 自動注冊注解處理器 @AutoService(Processor.class) // 支持的注解類型 @SupportedAnnotationTypes({"kim.hsl.router_annotation.Route"}) // 支持的 Java 版本 @SupportedSourceVersion(SourceVersion.RELEASE_8) public class RouterProcessor extends AbstractProcessor { /** * 注解處理器中使用 Messager 對象打印日志 */ private Messager mMessager; /** * 用于寫出生成的 Java 代碼 */ private Filer mFiler; /** * 注解節(jié)點工具 */ private Elements mElementUtils; /** * 類工具 */ private Types mTypeUtils; /** * 獲取的 moduleName 參數(shù) */ private String mModuleName; /** * 管理路由信息 * 鍵 ( Key ) : 路由分組名稱 * 值 ( Value ) : 路由信息集合 */ private HashMap> mGroupMap = new HashMap<>(); /** * 管理 路由表信息 * 鍵 ( Key ) : 組名 * 值 ( Value ) : 類名 */ private Map mRootMap = new TreeMap<>(); /** * 該函數(shù)在初始化時調(diào)用 , 相當(dāng)于構(gòu)造函數(shù) * @param processingEnvironment */ @Override public synchronized void init(ProcessingEnvironment processingEnvironment) { super.init(processingEnvironment); // 獲取打印日志接口 this.mMessager = processingEnvironment.getMessager(); // 測試日志打印 mMessager.printMessage(Diagnostic.Kind.NOTE, "Messager Print Log"); this.mFiler = processingEnvironment.getFiler(); this.mElementUtils = processingEnvironment.getElementUtils(); this.mTypeUtils = processingEnvironment.getTypeUtils(); // 獲取 moduleName 參數(shù) // 先獲取 注解處理器 選項 Map options = processingEnvironment.getOptions(); if (options != null){ mModuleName = options.get("moduleName"); mMessager.printMessage(Diagnostic.Kind.NOTE, "打印 moduleName 參數(shù) : " + mModuleName); } } /** * 該函數(shù)在注解處理器注冊時自動執(zhí)行, 是處理注解的核心函數(shù) * * Set set 參數(shù) : 該集合表示使用了相關(guān)注解的節(jié)點的集合 * * @param set * @param roundEnvironment * @return */ @Override public boolean process(Set set, RoundEnvironment roundEnvironment) { if (set == null || set.isEmpty()){ // 如果沒有檢測到注解 , 直接退出 return false; } // 獲取被 @Route 注解的節(jié)點 // 這些 注解節(jié)點 都是類節(jié)點 , TypeElement 類型的 Set routeElements = roundEnvironment.getElementsAnnotatedWith(Route.class); generateRouteClass(routeElements); // 生成 路由組件 分組表 對應(yīng)的 Java 類 generateGroupTable(); // 生成 路由組件 路由表 對應(yīng)的 Java 類 return true; } /** * 生成 路由組件 分組表 對應(yīng)的 Java 類 */ private void generateGroupTable() { // 獲取要生成的類 需要實現(xiàn)的接口節(jié)點 TypeElement iRouteGroup = mElementUtils.getTypeElement( "kim.hsl.route_core.template.IRouteGroup"); // 打印類節(jié)點全類名 mMessager.printMessage(Diagnostic.Kind.NOTE, "打印 路由表 需要實現(xiàn)的接口節(jié)點 iRouteGroup : " + iRouteGroup.getQualifiedName()); // 生成參數(shù)類型 Map atlas ParameterizedTypeName atlasType = ParameterizedTypeName.get( ClassName.get(Map.class), ClassName.get(String.class), ClassName.get(RouteBean.class) ); // 生成參數(shù) Map atlas ParameterSpec atlasValue = ParameterSpec.builder(atlasType, "atlas").build(); // 遍歷 HashMap> mGroupMap = new HashMap<>() 路由分組 // 為每個 路由分組 創(chuàng)建一個類 for (Map.Entry> entry : mGroupMap.entrySet()){ // 創(chuàng)建函數(shù) loadInto MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("loadInto") .addModifiers(Modifier.PUBLIC) .addAnnotation(Override.class) .addParameter(atlasValue); // 函數(shù)體中的代碼生成 // 獲取 ArrayList 數(shù)據(jù) ArrayList groupRoutes = entry.getValue(); // 組名 String groupName = ""; // 生成函數(shù)體代碼 for (RouteBean routeBean : groupRoutes){ // 獲取組名 groupName = routeBean.getRouteGroup(); // $S 表示字符串 // $T 表示類 // $L 表示字面量 , 原封不動的字符串替換 methodBuilder.addStatement("atlas.put($S, new $T($T.$L, $T.class, $S, $S))", // $S 字符串 : "main" routeBean.getRouteGroup(), // $T 類名 : RouteBean ClassName.get(RouteBean.class), // $T 類名 : Type ClassName.get(RouteBean.Type.class), // $L 字面量 : ACTIVITY routeBean.getType(), // $T 類名 : kim.hsl.component.MainActivity 類 ClassName.get((TypeElement) routeBean.getElement()), // $S 字符串 : "/app/MainActivity" routeBean.getRouteAddress(), // $S 字符串 : "app" routeBean.getRouteGroup()); } // 創(chuàng)建類 // 構(gòu)造類名 Router_Group_main String groupClassName = "Router_Group_" + groupName; // 創(chuàng)建類 TypeSpec typeSpec = TypeSpec.classBuilder(groupClassName) .addSuperinterface(ClassName.get(iRouteGroup)) .addModifiers(PUBLIC) .addMethod(methodBuilder.build()) .build(); // 生成 Java 源碼文件 JavaFile javaFile = JavaFile.builder("kim.hsl.router", typeSpec).build(); // 將 Java 源文件寫出到相應(yīng)目錄中 try { mMessager.printMessage(Diagnostic.Kind.NOTE, "輸出文件 : " + groupClassName); javaFile.writeTo(mFiler); } catch (IOException e) { e.printStackTrace(); mMessager.printMessage(Diagnostic.Kind.NOTE, "輸出文件出現(xiàn)異常"); }finally { mMessager.printMessage(Diagnostic.Kind.NOTE, "輸出文件完畢"); } // 統(tǒng)計路由表信息 mRootMap.put(groupName, groupClassName); } } private void generateRouteClass(Set routeElements) { // 獲取 android.app.Activity 類型的注解節(jié)點 TypeElement activityElement = mElementUtils.getTypeElement("android.app.Activity"); // 獲取 組件間共享服務(wù) 的接口, 該接口僅用于表示組件類型 TypeElement iServiceElement = mElementUtils.getTypeElement("kim.hsl.route_core.template.IService"); // 處理 @Route(path = "app/MainActivity") 節(jié)點 for (Element element : routeElements) { // 獲取 Route 注解 Route route = element.getAnnotation(Route.class); // 路由表中的單個路由對象 RouteBean routeBean = null; // 判斷 typeMirror 注解節(jié)點是否是 Activity 類型 if (mTypeUtils.isSubtype(element.asType(), activityElement.asType())) { // 該節(jié)點是 android.app.Activity 類型的 routeBean = new RouteBean( RouteBean.Type.ACTIVITY, // 路由對象類型 element, // 路由節(jié)點 null, // 類對象 route.path(), // 路由地址 route.group()); // 路由組 }else if (mTypeUtils.isSubtype(element.asType(), iServiceElement.asType())) { // 該節(jié)點是 kim.hsl.route_core.template.IService 類型的 routeBean = new RouteBean( RouteBean.Type.ISERVICE, // 路由對象類型 element, // 路由節(jié)點 null, // 類對象 route.path(), // 路由地址 route.group()); // 路由組 }else{ // 該節(jié)點不是 android.app.Activity 類型的 throw new RuntimeException("@Route 注解節(jié)點類型錯誤"); } // 檢查路由地址 checkRouteAddress(routeBean); // 打印路由信息 mMessager.printMessage(Diagnostic.Kind.NOTE, "打印路由信息 : " + routeBean.toString()); // 處理路由信息分組 routeGroup(routeBean); } } /** * 處理路由信息分組 * @param routeBean */ private void routeGroup(RouteBean routeBean) { // 首先從 groupMap 集合中獲取該分組的所有 路由信息 ArrayList routeBeans = mGroupMap.get(routeBean.getRouteGroup()); if (routeBeans == null){ // 如果從 mGroupMap 獲取的該分組的路由信息集合為空 // 則創(chuàng)建新集合, 放置路由信息, 并加入到 mGroupMap 中 routeBeans = new ArrayList<>(); routeBeans.add(routeBean); mGroupMap.put(routeBean.getRouteGroup(), routeBeans); }else{ // 從 mGroupMap 獲取的路由分組對應(yīng)的路由信息集合不為空 // 直接添加 路由信息 即可 routeBeans.add(routeBean); } } /** * 驗證路由地址 * @Route(path = "/app/MainActivity") * @param routeBean */ private void checkRouteAddress(RouteBean routeBean){ // 獲取路由地址 String routeAddress = routeBean.getRouteAddress(); // 獲取路由分組 String routeGroup = routeBean.getRouteGroup(); // 驗證路由地址是否以 "/" 開頭 if (!routeAddress.startsWith("/")) { throw new RuntimeException("路由地址 " + routeAddress + " 格式錯誤"); } // 如果路由地址的分組為空 , // 則截取第 0 和 第 1 個 "/" 之間的字符串作為分組名稱 if (routeGroup == null || "".equals(routeGroup)){ String group = routeAddress.substring( routeAddress.indexOf("/", 0) + 1, routeAddress.indexOf("/", 1) ); if (group == null || "".equals(group)){ throw new RuntimeException("路由地址 " + routeAddress + " 獲取分組錯誤"); } // 打印組名 mMessager.printMessage(Diagnostic.Kind.NOTE, "打印路由地址 " + routeAddress + " 的組名為 " + group); // 正式設(shè)置路由地址分組 routeBean.setRouteGroup(group); } } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      59

      60

      61

      62

      63

      64

      65

      66

      67

      68

      69

      70

      71

      72

      73

      74

      75

      76

      77

      78

      79

      80

      81

      82

      83

      84

      85

      86

      87

      88

      89

      90

      91

      92

      93

      94

      95

      96

      97

      98

      99

      100

      101

      102

      103

      104

      105

      106

      107

      108

      109

      110

      111

      112

      113

      114

      115

      116

      117

      118

      119

      120

      121

      122

      123

      124

      125

      126

      127

      128

      129

      130

      131

      132

      133

      134

      135

      136

      137

      138

      139

      140

      141

      142

      143

      144

      145

      146

      147

      148

      149

      150

      151

      152

      153

      154

      155

      156

      157

      158

      159

      160

      161

      162

      163

      164

      165

      166

      167

      168

      169

      170

      171

      172

      173

      174

      175

      176

      177

      178

      179

      180

      181

      182

      183

      184

      185

      186

      187

      188

      189

      190

      191

      192

      193

      194

      195

      196

      197

      198

      199

      200

      201

      202

      203

      204

      205

      206

      207

      208

      209

      210

      211

      212

      213

      214

      215

      216

      217

      218

      219

      220

      221

      222

      223

      224

      225

      226

      227

      228

      229

      230

      231

      232

      233

      234

      235

      236

      237

      238

      239

      240

      241

      242

      243

      244

      245

      246

      247

      248

      249

      250

      251

      252

      253

      254

      255

      256

      257

      258

      259

      260

      261

      262

      263

      264

      265

      266

      267

      268

      269

      270

      271

      272

      273

      274

      275

      276

      277

      278

      279

      280

      281

      282

      283

      284

      285

      286

      287

      288

      289

      290

      291

      292

      293

      294

      295

      296

      297

      298

      299

      300

      301

      302

      303

      304

      305

      306

      307

      308

      309

      310

      311

      312

      313

      314

      315

      316

      317

      318

      319

      320

      321

      322

      323

      324

      325

      326

      327

      328

      329

      330

      331

      332

      333

      334

      335

      336

      337

      338

      339

      340

      341

      342

      343

      344

      345

      2、app 模塊中的注解類生成的 Java 源碼

      Module 模塊中 , 使用注解生成的源碼 , 都在對應(yīng)模塊的 " build\generated\ap_generated_sources\debug\out\ " 目錄中 ;

      app 中的注解類 :

      @Route(path = "/app/MainActivity") public class MainActivity extends Activity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }

      1

      2

      3

      4

      5

      6

      7

      8

      生成的源碼 : 生成源碼路徑 D:

      生成的源碼 : 生成源碼路徑 D:\002_Project\002_Android_Learn\Component\app\build\generated\ap_generated_sources\debug\out\kim\hsl\router\Router_Group_app.java ;

      2_Project

      生成的源碼 : 生成源碼路徑 D:\002_Project\002_Android_Learn\Component\app\build\generated\ap_generated_sources\debug\out\kim\hsl\router\Router_Group_app.java ;

      2_Android_Learn\Component\app\build\generated\ap_generated_sources\debug\out\kim\hsl\router\Router_Group_app.java ;

      package kim.hsl.router; import java.lang.Override; import java.lang.String; import java.util.Map; import kim.hsl.component.MainActivity; import kim.hsl.route_core.template.IRouteGroup; import kim.hsl.router_annotation.model.RouteBean; public class Router_Group_app implements IRouteGroup { @Override public void loadInto(Map atlas) { atlas.put("app", new RouteBean(RouteBean.Type.ACTIVITY, MainActivity.class, "/app/MainActivity", "app")); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      3、library2 模塊中的注解類生成的 Java 源碼

      Module 模塊中 , 使用注解生成的源碼 , 都在對應(yīng)模塊的 " build\generated\ap_generated_sources\debug\out\ " 目錄中 ;

      library2 中的注解類 :

      package kim.hsl.library2; import android.util.Log; import kim.hsl.base.ComponentService; import kim.hsl.router_annotation.Route; @Route(path = "/library2/StringService") public class StringService implements ComponentService { @Override public void doSomething() { Log.i("StringService", "library2 組件中的 StringService 服務(wù) "); } }

      1

      2

      3

      4

      【Android 組件化】路由組件 ( 組件間共享的服務(wù) )

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      生成的源碼 : 生成源碼路徑 D:\002_Project\002_Android_Learn\Component\library2\build\generated\ap_generated_sources\debug\out\kim\hsl\router\Router_Group_library2.java ;

      package kim.hsl.router; import java.lang.Override; import java.lang.String; import java.util.Map; import kim.hsl.library2.StringService; import kim.hsl.route_core.template.IRouteGroup; import kim.hsl.router_annotation.model.RouteBean; public class Router_Group_library2 implements IRouteGroup { @Override public void loadInto(Map atlas) { atlas.put("library2", new RouteBean(RouteBean.Type.ISERVICE, StringService.class, "/library2/StringService", "library2")); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      五、博客資源

      博客源碼 :

      GitHub : https://github.com/han1202012/Component

      CSDN 下載 :

      Android NAT

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:excel公式不計算顯示的是公式實現(xiàn)教程
      下一篇:制造業(yè)生產(chǎn)計劃管理制度(生產(chǎn)制造企業(yè)管理制度)
      相關(guān)文章
      亚洲av乱码一区二区三区| 亚洲一级黄色视频| 久久亚洲国产精品一区二区| 亚洲av无码日韩av无码网站冲| 亚洲国产品综合人成综合网站| 亚洲精品亚洲人成在线观看麻豆 | 久久精品国产亚洲沈樵| 成人午夜亚洲精品无码网站| 国产亚洲精品AA片在线观看不加载 | 久久久久亚洲AV片无码下载蜜桃| 亚洲高清专区日韩精品| 亚洲av无码一区二区乱子伦as| 亚洲AV无码专区电影在线观看 | 亚洲网红精品大秀在线观看| 91久久亚洲国产成人精品性色| 亚洲视频在线观看不卡| 亚洲电影在线播放| 亚洲人成电影院在线观看| 老色鬼久久亚洲AV综合| 亚洲精品无码你懂的网站| 亚洲中文字幕视频国产| 亚洲午夜福利精品无码| 亚洲乳大丰满中文字幕| 无码乱人伦一区二区亚洲| 亚洲精品高清国产麻豆专区| 亚洲人成激情在线播放| 日韩亚洲产在线观看| 亚洲av成人无码网站…| 亚洲欧洲一区二区三区| 九月丁香婷婷亚洲综合色| 亚洲综合国产精品| 亚洲冬月枫中文字幕在线看| 久久乐国产综合亚洲精品| 色窝窝亚洲av网| 中文字幕一精品亚洲无线一区| 亚洲国产第一站精品蜜芽| 久久国产亚洲精品无码| 亚洲久悠悠色悠在线播放| 在线观看亚洲免费| 亚洲人成在线播放网站| 午夜亚洲国产理论秋霞|