张波

提交代码

Showing 74 changed files with 4887 additions and 0 deletions
  1 +*.iml
  2 +.gradle
  3 +/local.properties
  4 +/.idea
  5 +.DS_Store
  6 +/build
  7 +/captures
  8 +.externalNativeBuild
  9 +.cxx
  10 +local.properties
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="EclipseCodeFormatterProjectSettings">
  4 + <option name="projectSpecificProfile">
  5 + <ProjectSpecificProfile>
  6 + <option name="formatter" value="ECLIPSE" />
  7 + <option name="importOrder" value="java;javax;org;android;androidx;com;" />
  8 + <option name="pathToConfigFileJava" value="$PROJECT_DIR$/config/CodeQuality/WonderTek_CodeFormatter_Convention_v1.0.xml" />
  9 + <option name="selectedJavaProfile" value="WonderTek_CodeFormatter_Convention_v1.0" />
  10 + </ProjectSpecificProfile>
  11 + </option>
  12 + </component>
  13 +</project>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project version="4">
  3 + <component name="VcsDirectoryMappings">
  4 + <mapping directory="$PROJECT_DIR$" vcs="Git" />
  5 + </component>
  6 +</project>
  1 +/build
  1 +plugins {
  2 + id 'com.android.application'
  3 + id 'kotlin-android'
  4 + id 'kotlin-android-extensions'
  5 +}
  6 +
  7 +android {
  8 + compileSdkVersion var.compileSdkVersion
  9 + buildToolsVersion var.buildToolsVersion
  10 +
  11 + defaultConfig {
  12 + applicationId "com.example.myapplication"
  13 + minSdkVersion var.minSdkVersion
  14 + targetSdkVersion var.targetSdkVersion
  15 + versionCode 1
  16 + versionName "1.0"
  17 +
  18 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
  19 + multiDexEnabled true
  20 + ndk {
  21 + // noinspection ChromeOsAbiSupport
  22 + abiFilters "armeabi-v7a", "arm64-v8a", "x86"
  23 + }
  24 +
  25 + javaCompileOptions {
  26 + annotationProcessorOptions {
  27 + arguments = [AROUTER_MODULE_NAME: project.getName()]
  28 + }
  29 + }
  30 + }
  31 +
  32 + buildTypes {
  33 + release {
  34 + minifyEnabled false
  35 + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
  36 + }
  37 + }
  38 +
  39 + lintOptions {
  40 + abortOnError false
  41 + }
  42 +
  43 + compileOptions {
  44 + // Java兼容性设置为Java 8
  45 + sourceCompatibility JavaVersion.VERSION_1_8
  46 + targetCompatibility JavaVersion.VERSION_1_8
  47 + }
  48 +}
  49 +
  50 +repositories {
  51 + flatDir {
  52 + dirs 'libs'
  53 + }
  54 +}
  55 +
  56 +dependencies {
  57 +// implementation 'androidx.appcompat:appcompat:1.6.1'
  58 + implementation "com.google.android.material:material:1.4.0"
  59 +// implementation project(path: ':wdstartup')
  60 + implementation 'com.wd:startup:1.0.0'
  61 +}
  1 +# Add project specific ProGuard rules here.
  2 +# You can control the set of applied configuration files using the
  3 +# proguardFiles setting in build.gradle.
  4 +#
  5 +# For more details, see
  6 +# http://developer.android.com/guide/developing/tools/proguard.html
  7 +
  8 +# If your project uses WebView with JS, uncomment the following
  9 +# and specify the fully qualified class name to the JavaScript interface
  10 +# class:
  11 +#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
  12 +# public *;
  13 +#}
  14 +
  15 +# Uncomment this to preserve the line number information for
  16 +# debugging stack traces.
  17 +#-keepattributes SourceFile,LineNumberTable
  18 +
  19 +# If you keep the line number information, uncomment this to
  20 +# hide the original source file name.
  21 +#-renamesourcefileattribute SourceFile
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3 + xmlns:tools="http://schemas.android.com/tools"
  4 + package="com.example.myapplication">
  5 + <!-- 请求网络 -->
  6 + <uses-permission android:name="android.permission.INTERNET" />
  7 + <uses-feature
  8 + android:name="android.software.leanback"
  9 + android:required="false" />
  10 + <application
  11 + android:name=".MyApplication"
  12 + android:allowBackup="true"
  13 + android:fullBackupContent="@xml/backup_rules"
  14 + android:icon="@mipmap/ic_launcher"
  15 + android:label="@string/app_name"
  16 + android:roundIcon="@mipmap/ic_launcher_round"
  17 + android:supportsRtl="true"
  18 + android:theme="@style/Theme.MyApplication"
  19 + tools:targetApi="31">
  20 +
  21 + <activity
  22 + android:name="com.example.myapplication.MainActivity"
  23 + android:exported="true"
  24 + android:launchMode="singleTask">
  25 + <intent-filter>
  26 + <action android:name="android.intent.action.MAIN" />
  27 + <category android:name="android.intent.category.LAUNCHER" />
  28 + </intent-filter>
  29 + </activity>
  30 + </application>
  31 +</manifest>
  1 +
  2 +package com.example.myapplication;
  3 +
  4 +import android.app.Activity;
  5 +import android.os.Bundle;
  6 +
  7 +import androidx.annotation.Nullable;
  8 +
  9 +/**
  10 + * @ProjectName: PeopleDailyVideo
  11 + * @Package: com.people.displayui.main
  12 + * @ClassName: WelcomeActivity
  13 + * @Description: 启动APP过渡页面
  14 + * @Author: wd
  15 + * @CreateDate: 2022/10/28 17:36
  16 + * @UpdateUser: wd
  17 + * @UpdateDate: 2022/10/28 17:36
  18 + * @UpdateRemark: 更新说明:
  19 + * @Version: 1.0
  20 + */
  21 +public class MainActivity extends Activity {
  22 +
  23 + @Override
  24 + protected void onCreate(@Nullable Bundle savedInstanceState) {
  25 + super.onCreate(savedInstanceState);
  26 + // 直接进入首页
  27 + }
  28 +}
  1 +
  2 +package com.example.myapplication;
  3 +
  4 +import android.app.Application;
  5 +import android.util.Log;
  6 +
  7 +import com.example.myapplication.starttask.StartTaskConfig;
  8 +import com.example.myapplication.starttask.StartTaskTool;
  9 +
  10 +/**
  11 + * @author devel
  12 + * @time 2024/8/28 星期三 16:23
  13 + */
  14 +public class MyApplication extends Application {
  15 + @Override
  16 + public void onCreate() {
  17 + super.onCreate();
  18 + Log.e("zzzz","MyApplication onCreate");
  19 + // test
  20 + StartTaskConfig taskConfig = new StartTaskConfig(this);
  21 + taskConfig.start();
  22 + StartTaskTool.startTaskInMain(this);
  23 + StartTaskTool.startPrivate(this);
  24 + StartTaskTool.startTaskInSplash(this);
  25 + }
  26 +}
  1 +/*
  2 + * Copyright (c) People Technologies Co., Ltd. 2019-2022. All rights reserved.
  3 + */
  4 +
  5 +package com.example.myapplication.starttask;
  6 +
  7 +import android.content.Context;
  8 +import android.util.Log;
  9 +
  10 +import com.example.myapplication.starttask.task.MyTaskCreator;
  11 +import com.wd.base.starttask.AlphaManager;
  12 +import com.wd.base.starttask.Project;
  13 +
  14 +/**
  15 + * 描述:启动初始化任务
  16 + * 默认放在子线程执行,如果子线程执行有问题,构造函数中使用super(name,isInUiThread)
  17 + *
  18 + * @author : lvjinhui
  19 + * @since: 2022/7/2
  20 + */
  21 +
  22 +public class StartTaskConfig {
  23 +
  24 + private Context mContext;
  25 +
  26 + public StartTaskConfig(Context mContext) {
  27 + this.mContext = mContext;
  28 + }
  29 +
  30 + /**
  31 + * 开始全部的初始化,在application
  32 + */
  33 + public void start() {
  34 + if (mContext == null) {
  35 + return;
  36 + }
  37 + Project.Builder builder = new Project.Builder().withTaskCreator(new MyTaskCreator(mContext));
  38 + // 日志
  39 + builder.add(MyTaskCreator.TASK_LOG);
  40 + // AppContext.init、CompComponent 组件服务注册,MyFileUtil.init,直播消息弹幕和打赏
  41 + builder.add(MyTaskCreator.TASK_LOCAL);
  42 + AlphaManager.getInstance(mContext).addProject(builder.create());
  43 + AlphaManager.getInstance(mContext).start();
  44 +
  45 + Log.e("zzzz","start");
  46 + }
  47 +
  48 + /**
  49 + * 适当的放一部分延时初始化
  50 + */
  51 + public void startTaskDelay() {
  52 + if (mContext == null) {
  53 + return;
  54 + }
  55 + Project.Builder builder = new Project.Builder().withTaskCreator(new MyTaskCreator(mContext));
  56 + // 延时初始化,短视频SDK,辅助通道
  57 + builder.add(MyTaskCreator.TASK_DELAY);
  58 + builder.setProjectName("delayGroup");
  59 + AlphaManager.getInstance(mContext).addProject(builder.create());
  60 + AlphaManager.getInstance(mContext).start();
  61 + Log.e("zzzz","startTaskDelay");
  62 + }
  63 +
  64 + /**
  65 + * 需要用户同意隐私政策才能初始化的SDK,放在PrivatePolicyTask
  66 + */
  67 + public void startPrivate() {
  68 + if (mContext == null) {
  69 + return;
  70 + }
  71 + Project.Builder builder = new Project.Builder().withTaskCreator(new MyTaskCreator(mContext));
  72 + // umeng 正式init
  73 + builder.add(MyTaskCreator.TASK_PRIVATE);
  74 + builder.setProjectName("privateGroup");
  75 + AlphaManager.getInstance(mContext).addProject(builder.create());
  76 + AlphaManager.getInstance(mContext).start();
  77 + Log.e("zzzz","startPrivate");
  78 + }
  79 +
  80 + /**
  81 + * 优先级最高(未同意隐私政策,等同意隐私政策完成后初始化;
  82 + * 已同意隐私政策,直接初始化)
  83 + * 进入主页在初始的,但是在隐私弹窗之前,不可以放涉及隐私的SDK
  84 + */
  85 + public void startTaskInMain() {
  86 + if (mContext == null) {
  87 + return;
  88 + }
  89 +
  90 + Project.Builder builder = new Project.Builder().withTaskCreator(new MyTaskCreator(mContext));
  91 + // 子线程 内容组件、comp组件、语音识别
  92 + builder.add(MyTaskCreator.TASK_WD);
  93 + builder.setProjectName("inMainGroup");
  94 + AlphaManager.getInstance(mContext).addProject(builder.create());
  95 + AlphaManager.getInstance(mContext).start();
  96 + Log.e("zzzz","startTaskInMain");
  97 + }
  98 +
  99 +}
  1 +/*
  2 + * Copyright (c) People Technologies Co., Ltd. 2019-2022. All rights reserved.
  3 + */
  4 +
  5 +package com.example.myapplication.starttask;
  6 +
  7 +import android.content.Context;
  8 +
  9 +/**
  10 + * 描述:
  11 + *
  12 + * @author : lvjinhui
  13 + * @since: 2022/7/7
  14 + */
  15 +public class StartTaskTool {
  16 + public static void startTaskInMain(Context context) {
  17 + StartTaskConfig taskConfig = new StartTaskConfig(context);
  18 + taskConfig.startTaskInMain();
  19 + }
  20 +
  21 + public static void startPrivate(Context context) {
  22 + StartTaskConfig taskConfig = new StartTaskConfig(context);
  23 + taskConfig.startPrivate();
  24 + }
  25 +
  26 + public static void startTaskInSplash(Context context) {
  27 + StartTaskConfig taskConfig = new StartTaskConfig(context);
  28 + taskConfig.startTaskDelay();
  29 + }
  30 +}
  1 +/*
  2 + * Copyright (c) People Technologies Co., Ltd. 2019-2022. All rights reserved.
  3 + */
  4 +
  5 +package com.example.myapplication.starttask.task;
  6 +
  7 +import android.content.Context;
  8 +
  9 +import com.wd.base.starttask.Task;
  10 +
  11 +//import com.orhanobut.logger.Logger;
  12 +//import com.people.kittools.constant.CommonConstant;
  13 +//import com.people.kittools.sp.SpUtils;
  14 +//import com.people.umeng.UmSdkHelper;
  15 +
  16 +/**
  17 + * 描述:在主页初始化,不着急使用,进入主页用户必然已经同意隐私政策
  18 + *
  19 + * @author : lvjinhui
  20 + * @since: 2022/7/2
  21 + */
  22 +public class DelayTask extends Task {
  23 +
  24 + public DelayTask(Context mContext) {
  25 + super("DelayTask");
  26 + setExecutePriority(9);
  27 +// if (SpUtils.isFirstAgreementFlag()){
  28 +// return;
  29 +// }
  30 + try {
  31 + //友盟分享
  32 +// UmSdkHelper.initUmThirdSDk(mContext, CommonConstant.FILE_PROVIDER);
  33 +// Logger.e("DelayTask 执行");
  34 +
  35 + } catch (Exception e) {
  36 + e.printStackTrace();
  37 + }
  38 +
  39 + }
  40 +
  41 + @Override
  42 + public void run() {
  43 +
  44 + }
  45 +}
  1 +/*
  2 + * Copyright (c) People Technologies Co., Ltd. 2019-2022. All rights reserved.
  3 + */
  4 +
  5 +package com.example.myapplication.starttask.task;
  6 +
  7 +import java.lang.ref.WeakReference;
  8 +
  9 +import android.content.Context;
  10 +
  11 +import com.wd.base.starttask.Task;
  12 +
  13 +//import com.people.kittools.file.MyFileUtils;
  14 +//import com.people.uiframework.CompComponent;
  15 +
  16 +/**
  17 + * 描述:本地代码初始化context,都在子线程执行
  18 + * 无关用户信息,收集用户信息的SDK初始化不要放进这里
  19 + * @author : lvjinhui
  20 + * @since: 2022/7/2
  21 + */
  22 +public class LocalThreadTask extends Task {
  23 +
  24 + private WeakReference<Context> weakReference;
  25 + public LocalThreadTask(Context context) {
  26 + super("LocalThreadTask");
  27 + weakReference = new WeakReference<>(context);
  28 + setExecutePriority(1);
  29 + }
  30 +
  31 + @Override
  32 + public void run() {
  33 + Context mContext = weakReference.get();
  34 + // 注册创建对象
  35 +// new CompComponent().registerServices();
  36 +// // 赋值context
  37 +// MyFileUtils.init(mContext);
  38 + }
  39 +
  40 +}
  1 +/*
  2 + * Copyright (c) People Technologies Co., Ltd. 2019-2022. All rights reserved.
  3 + */
  4 +
  5 +package com.example.myapplication.starttask.task;
  6 +
  7 +import com.wd.base.starttask.Task;
  8 +//import com.people.logutil.LoggerInit;
  9 +
  10 +/**
  11 + * 描述:com.orhanobut.logger 初始化,子线程初始化
  12 + *
  13 + * @author : lvjinhui
  14 + * @since: 2022/7/2
  15 + */
  16 +public class LoggerTask extends Task {
  17 +
  18 + public LoggerTask() {
  19 + super("LoggerTask");
  20 + }
  21 +
  22 + @Override
  23 + public void run() {
  24 + // log 初始化
  25 +// LoggerInit.getInstance().init(true);// BuildConfig.DEBUG
  26 + }
  27 +}
  1 +/*
  2 + * Copyright (c) People Technologies Co., Ltd. 2019-2022. All rights reserved.
  3 + */
  4 +
  5 +package com.example.myapplication.starttask.task;
  6 +
  7 +import android.content.Context;
  8 +import android.util.Log;
  9 +
  10 +import com.wd.base.starttask.ITaskCreator;
  11 +import com.wd.base.starttask.Task;
  12 +
  13 +/**
  14 + * 描述:create task
  15 + *
  16 + * @author : lvjinhui
  17 + * @since: 2022/7/2
  18 + */
  19 +public class MyTaskCreator implements ITaskCreator {
  20 + /**
  21 + * 定义的task 名字, 比如 LoggerTask 在 task 构造函数传入
  22 + */
  23 + public static final String TASK_LOG = "LoggerTask";
  24 +
  25 + public static final String TASK_LOCAL = "LocalThreadTask";
  26 +
  27 + public static final String TASK_DELAY = "DelayTask";
  28 +
  29 + public static final String TASK_PRIVATE = "PrivatePolicyTask";
  30 +
  31 + public static final String TASK_WD = "WCompTask";
  32 +
  33 + private final Context mContext;
  34 +
  35 + public MyTaskCreator(Context context) {
  36 + this.mContext = context;
  37 + }
  38 +
  39 + @Override
  40 + public Task createTask(String taskName) {
  41 + Log.d("==ALPHA==", taskName);
  42 + switch (taskName) {
  43 + case TASK_LOG:
  44 + return new LoggerTask();
  45 + case TASK_LOCAL:
  46 + return new LocalThreadTask(mContext);
  47 + case TASK_DELAY:
  48 + return new DelayTask(mContext);
  49 + case TASK_PRIVATE:
  50 + return new PrivatePolicyTask(mContext);
  51 + case TASK_WD:
  52 + return new WCompTask();
  53 + default:
  54 + break;
  55 + }
  56 +
  57 + return null;
  58 + }
  59 +}
  1 +/*
  2 + * Copyright (c) People Technologies Co., Ltd. 2019-2022. All rights reserved.
  3 + */
  4 +
  5 +package com.example.myapplication.starttask.task;
  6 +
  7 +import android.content.Context;
  8 +
  9 +import com.wd.base.starttask.Task;
  10 +
  11 +
  12 +//import com.orhanobut.logger.Logger;
  13 +//import com.people.kittools.sp.SpUtils;
  14 +//import com.people.umeng.UmSdkHelper;
  15 +
  16 +
  17 +/**
  18 + * 描述:需要用户同意隐私政策的SDK初始化
  19 + *
  20 + * @author : lvjinhui
  21 + * @since: 2022/7/2
  22 + */
  23 +public class PrivatePolicyTask extends Task {
  24 +
  25 + private Context instance;
  26 +
  27 + public PrivatePolicyTask(Context context) {
  28 + super("PrivatePolicyTask");
  29 + this.instance = context;
  30 +// if (SpUtils.isFirstAgreementFlag()) {
  31 +// return;
  32 +// }
  33 + /**
  34 + * 友盟SDK正式初始化
  35 + */
  36 +// UmSdkHelper.initUmSdk(instance);
  37 +// Logger.e("隐私SDK初始化");
  38 + }
  39 +
  40 + @Override
  41 + public void run() {
  42 +
  43 + }
  44 +}
  1 +/*
  2 + * Copyright (c) People Technologies Co., Ltd. 2019-2022. All rights reserved.
  3 + */
  4 +
  5 +package com.example.myapplication.starttask.task;
  6 +
  7 +//import com.wondertek.wheat.ability.scheduler.WComponent;
  8 +//import com.wondertek.wheat.ability.scheduler.listener.IComponentRegister;
  9 +//import com.wondertek.wheat.ability.scheduler.listener.InitListener;
  10 +
  11 +import com.wd.base.starttask.Task;
  12 +
  13 +/**
  14 + * 描述:组件注册,反射多了影响性能
  15 + *
  16 + * @author : lvjinhui
  17 + * @since: 2022/7/2
  18 + */
  19 +public class WCompTask extends Task {
  20 +
  21 + public WCompTask() {
  22 + super("WCompTask");
  23 + }
  24 +
  25 + @Override
  26 + public void run() {
  27 + // 代码组件
  28 + initWComponent();
  29 + }
  30 +
  31 + private void initWComponent() {
  32 +// WComponent.init(new InitListener() {
  33 +// @Override
  34 +// public void beforeInit() {
  35 +//
  36 +// }
  37 +//
  38 +// @Override
  39 +// public void registerComponent(IComponentRegister iComponentRegister) {
  40 +// // 内容获取组件
  41 +// iComponentRegister.registerComponent("ContentComponent",
  42 +// "com.people.component.content.ContentComponent");
  43 +// // comp组件
  44 +// iComponentRegister.registerComponent("CompComponent", "com.people.component.comp.CompComponent");
  45 +// // 语音识别
  46 +// iComponentRegister.registerComponent("SpeechComponent", "com.people.speech.SpeechComponent");
  47 +// }
  48 +//
  49 +// @Override
  50 +// public void initFinish() {
  51 +//
  52 +// }
  53 +// });
  54 + }
  55 +
  56 +}
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<vector xmlns:android="http://schemas.android.com/apk/res/android"
  3 + android:width="108dp"
  4 + android:height="108dp"
  5 + android:viewportWidth="108"
  6 + android:viewportHeight="108">
  7 + <path
  8 + android:fillColor="#3DDC84"
  9 + android:pathData="M0,0h108v108h-108z" />
  10 + <path
  11 + android:fillColor="#00000000"
  12 + android:pathData="M9,0L9,108"
  13 + android:strokeWidth="0.8"
  14 + android:strokeColor="#33FFFFFF" />
  15 + <path
  16 + android:fillColor="#00000000"
  17 + android:pathData="M19,0L19,108"
  18 + android:strokeWidth="0.8"
  19 + android:strokeColor="#33FFFFFF" />
  20 + <path
  21 + android:fillColor="#00000000"
  22 + android:pathData="M29,0L29,108"
  23 + android:strokeWidth="0.8"
  24 + android:strokeColor="#33FFFFFF" />
  25 + <path
  26 + android:fillColor="#00000000"
  27 + android:pathData="M39,0L39,108"
  28 + android:strokeWidth="0.8"
  29 + android:strokeColor="#33FFFFFF" />
  30 + <path
  31 + android:fillColor="#00000000"
  32 + android:pathData="M49,0L49,108"
  33 + android:strokeWidth="0.8"
  34 + android:strokeColor="#33FFFFFF" />
  35 + <path
  36 + android:fillColor="#00000000"
  37 + android:pathData="M59,0L59,108"
  38 + android:strokeWidth="0.8"
  39 + android:strokeColor="#33FFFFFF" />
  40 + <path
  41 + android:fillColor="#00000000"
  42 + android:pathData="M69,0L69,108"
  43 + android:strokeWidth="0.8"
  44 + android:strokeColor="#33FFFFFF" />
  45 + <path
  46 + android:fillColor="#00000000"
  47 + android:pathData="M79,0L79,108"
  48 + android:strokeWidth="0.8"
  49 + android:strokeColor="#33FFFFFF" />
  50 + <path
  51 + android:fillColor="#00000000"
  52 + android:pathData="M89,0L89,108"
  53 + android:strokeWidth="0.8"
  54 + android:strokeColor="#33FFFFFF" />
  55 + <path
  56 + android:fillColor="#00000000"
  57 + android:pathData="M99,0L99,108"
  58 + android:strokeWidth="0.8"
  59 + android:strokeColor="#33FFFFFF" />
  60 + <path
  61 + android:fillColor="#00000000"
  62 + android:pathData="M0,9L108,9"
  63 + android:strokeWidth="0.8"
  64 + android:strokeColor="#33FFFFFF" />
  65 + <path
  66 + android:fillColor="#00000000"
  67 + android:pathData="M0,19L108,19"
  68 + android:strokeWidth="0.8"
  69 + android:strokeColor="#33FFFFFF" />
  70 + <path
  71 + android:fillColor="#00000000"
  72 + android:pathData="M0,29L108,29"
  73 + android:strokeWidth="0.8"
  74 + android:strokeColor="#33FFFFFF" />
  75 + <path
  76 + android:fillColor="#00000000"
  77 + android:pathData="M0,39L108,39"
  78 + android:strokeWidth="0.8"
  79 + android:strokeColor="#33FFFFFF" />
  80 + <path
  81 + android:fillColor="#00000000"
  82 + android:pathData="M0,49L108,49"
  83 + android:strokeWidth="0.8"
  84 + android:strokeColor="#33FFFFFF" />
  85 + <path
  86 + android:fillColor="#00000000"
  87 + android:pathData="M0,59L108,59"
  88 + android:strokeWidth="0.8"
  89 + android:strokeColor="#33FFFFFF" />
  90 + <path
  91 + android:fillColor="#00000000"
  92 + android:pathData="M0,69L108,69"
  93 + android:strokeWidth="0.8"
  94 + android:strokeColor="#33FFFFFF" />
  95 + <path
  96 + android:fillColor="#00000000"
  97 + android:pathData="M0,79L108,79"
  98 + android:strokeWidth="0.8"
  99 + android:strokeColor="#33FFFFFF" />
  100 + <path
  101 + android:fillColor="#00000000"
  102 + android:pathData="M0,89L108,89"
  103 + android:strokeWidth="0.8"
  104 + android:strokeColor="#33FFFFFF" />
  105 + <path
  106 + android:fillColor="#00000000"
  107 + android:pathData="M0,99L108,99"
  108 + android:strokeWidth="0.8"
  109 + android:strokeColor="#33FFFFFF" />
  110 + <path
  111 + android:fillColor="#00000000"
  112 + android:pathData="M19,29L89,29"
  113 + android:strokeWidth="0.8"
  114 + android:strokeColor="#33FFFFFF" />
  115 + <path
  116 + android:fillColor="#00000000"
  117 + android:pathData="M19,39L89,39"
  118 + android:strokeWidth="0.8"
  119 + android:strokeColor="#33FFFFFF" />
  120 + <path
  121 + android:fillColor="#00000000"
  122 + android:pathData="M19,49L89,49"
  123 + android:strokeWidth="0.8"
  124 + android:strokeColor="#33FFFFFF" />
  125 + <path
  126 + android:fillColor="#00000000"
  127 + android:pathData="M19,59L89,59"
  128 + android:strokeWidth="0.8"
  129 + android:strokeColor="#33FFFFFF" />
  130 + <path
  131 + android:fillColor="#00000000"
  132 + android:pathData="M19,69L89,69"
  133 + android:strokeWidth="0.8"
  134 + android:strokeColor="#33FFFFFF" />
  135 + <path
  136 + android:fillColor="#00000000"
  137 + android:pathData="M19,79L89,79"
  138 + android:strokeWidth="0.8"
  139 + android:strokeColor="#33FFFFFF" />
  140 + <path
  141 + android:fillColor="#00000000"
  142 + android:pathData="M29,19L29,89"
  143 + android:strokeWidth="0.8"
  144 + android:strokeColor="#33FFFFFF" />
  145 + <path
  146 + android:fillColor="#00000000"
  147 + android:pathData="M39,19L39,89"
  148 + android:strokeWidth="0.8"
  149 + android:strokeColor="#33FFFFFF" />
  150 + <path
  151 + android:fillColor="#00000000"
  152 + android:pathData="M49,19L49,89"
  153 + android:strokeWidth="0.8"
  154 + android:strokeColor="#33FFFFFF" />
  155 + <path
  156 + android:fillColor="#00000000"
  157 + android:pathData="M59,19L59,89"
  158 + android:strokeWidth="0.8"
  159 + android:strokeColor="#33FFFFFF" />
  160 + <path
  161 + android:fillColor="#00000000"
  162 + android:pathData="M69,19L69,89"
  163 + android:strokeWidth="0.8"
  164 + android:strokeColor="#33FFFFFF" />
  165 + <path
  166 + android:fillColor="#00000000"
  167 + android:pathData="M79,19L79,89"
  168 + android:strokeWidth="0.8"
  169 + android:strokeColor="#33FFFFFF" />
  170 +</vector>
  1 +<vector xmlns:android="http://schemas.android.com/apk/res/android"
  2 + xmlns:aapt="http://schemas.android.com/aapt"
  3 + android:width="108dp"
  4 + android:height="108dp"
  5 + android:viewportWidth="108"
  6 + android:viewportHeight="108">
  7 + <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
  8 + <aapt:attr name="android:fillColor">
  9 + <gradient
  10 + android:endX="85.84757"
  11 + android:endY="92.4963"
  12 + android:startX="42.9492"
  13 + android:startY="49.59793"
  14 + android:type="linear">
  15 + <item
  16 + android:color="#44000000"
  17 + android:offset="0.0" />
  18 + <item
  19 + android:color="#00000000"
  20 + android:offset="1.0" />
  21 + </gradient>
  22 + </aapt:attr>
  23 + </path>
  24 + <path
  25 + android:fillColor="#FFFFFF"
  26 + android:fillType="nonZero"
  27 + android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
  28 + android:strokeWidth="1"
  29 + android:strokeColor="#00000000" />
  30 +</vector>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3 + android:id="@+id/rl_parent"
  4 + android:layout_width="match_parent"
  5 + android:layout_height="match_parent"
  6 + android:background="@color/white" />
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <background android:drawable="@drawable/ic_launcher_background" />
  4 + <foreground android:drawable="@drawable/ic_launcher_foreground" />
  5 + <monochrome android:drawable="@drawable/ic_launcher_foreground" />
  6 +</adaptive-icon>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <background android:drawable="@drawable/ic_launcher_background" />
  4 + <foreground android:drawable="@drawable/ic_launcher_foreground" />
  5 + <monochrome android:drawable="@drawable/ic_launcher_foreground" />
  6 +</adaptive-icon>
No preview for this file type
No preview for this file type
No preview for this file type
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <color name="purple_200">#FFBB86FC</color>
  4 + <color name="purple_500">#FF6200EE</color>
  5 + <color name="purple_700">#FF3700B3</color>
  6 + <color name="teal_200">#FF03DAC5</color>
  7 + <color name="teal_700">#FF018786</color>
  8 + <color name="black">#FF000000</color>
  9 + <color name="white">#FFFFFFFF</color>
  10 +</resources>
  1 +<resources>
  2 + <string name="app_name">My Application</string>
  3 +</resources>
  1 +<resources xmlns:tools="http://schemas.android.com/tools">
  2 + <!-- Base application theme. -->
  3 + <style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
  4 + <!-- Primary brand color. -->
  5 + <item name="colorPrimary">@color/purple_500</item>
  6 + <item name="colorPrimaryVariant">@color/purple_700</item>
  7 + <item name="colorOnPrimary">@color/white</item>
  8 + <!-- Secondary brand color. -->
  9 + <item name="colorSecondary">@color/teal_200</item>
  10 + <item name="colorSecondaryVariant">@color/teal_700</item>
  11 + <item name="colorOnSecondary">@color/black</item>
  12 + <!-- Status bar color. -->
  13 + <item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
  14 + <!-- Customize your theme here. -->
  15 + </style>
  16 +</resources>
  1 +<?xml version="1.0" encoding="utf-8"?><!--
  2 + Sample backup rules file; uncomment and customize as necessary.
  3 + See https://developer.android.com/guide/topics/data/autobackup
  4 + for details.
  5 + Note: This file is ignored for devices older that API 31
  6 + See https://developer.android.com/about/versions/12/backup-restore
  7 +-->
  8 +<full-backup-content>
  9 + <!--
  10 + <include domain="sharedpref" path="."/>
  11 + <exclude domain="sharedpref" path="device.xml"/>
  12 +-->
  13 +</full-backup-content>
  1 +apply plugin: 'maven'
  2 +
  3 +buildscript {
  4 + ext.kotlin_version = "1.4.32"
  5 + repositories {
  6 + mavenLocal()
  7 + mavenCentral()
  8 + // 以下四行代码为阿里gradle源,需要的人自己放開使用
  9 + maven { url 'https://maven.aliyun.com/repository/google' }
  10 + maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
  11 + maven { url 'https://maven.aliyun.com/repository/public' }
  12 + maven { url 'https://maven.aliyun.com/repository/jcenter' }
  13 + maven { url 'https://maven.aliyun.com/nexus/content/repositories/releases' }
  14 + //阿里云 maven
  15 + maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
  16 + maven { url 'https://maven.aliyun.com/repository/releases' }
  17 +
  18 + google()
  19 +
  20 + maven { url "https://jitpack.io" }
  21 + //华为
  22 + maven { url 'https://developer.huawei.com/repo/' }
  23 + //阿里云QuickTracking
  24 + maven { url 'https://repo1.maven.org/maven2/' }
  25 +
  26 + maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
  27 + maven {
  28 + url 'https://maven.aliyun.com/nexus/content/repositories/google/'
  29 + name 'aliyun-google'
  30 + }
  31 +
  32 + // TingYun
  33 + maven { url "https://nexus2.tingyun.com/nexus/content/repositories/snapshots/" }
  34 + }
  35 +
  36 + dependencies {
  37 + classpath "com.android.tools.build:gradle:4.0.2"
  38 + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  39 + classpath 'com.billy.android:autoregister:1.4.2'
  40 + // NOTE: Do not place your application dependencies here; they belong
  41 + // in the individual module build.gradle files
  42 + }
  43 +}
  44 +
  45 +allprojects {
  46 + repositories {
  47 + mavenLocal()
  48 + mavenCentral()
  49 + // 以下四行代码为阿里gradle源,需要的人自己放開使用
  50 + maven { url 'https://maven.aliyun.com/repository/google' }
  51 + maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
  52 + maven { url 'https://maven.aliyun.com/repository/public' }
  53 + maven { url 'https://maven.aliyun.com/repository/jcenter' }
  54 + maven { url 'https://maven.aliyun.com/nexus/content/repositories/releases' }
  55 + //阿里云 maven
  56 + maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
  57 + maven { url 'https://maven.aliyun.com/repository/releases' }
  58 + google()
  59 +
  60 + maven { url "https://jitpack.io" }
  61 + //华为
  62 + maven { url 'https://developer.huawei.com/repo/' }
  63 + //阿里云QuickTracking
  64 + maven { url 'https://repo1.maven.org/maven2/' }
  65 + maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
  66 + maven {
  67 + url 'https://maven.aliyun.com/nexus/content/repositories/google/'
  68 + name 'aliyun-google'
  69 + }
  70 +
  71 + flatDir { dirs 'src/main/libs' }
  72 +
  73 + // 快马私库
  74 + maven {
  75 + credentials {
  76 + username '6708d1cf6f4c940bd257c88d'
  77 + password 'Wm51gc4rARyr'
  78 + }
  79 + url 'https://packages.aliyun.com/6708d221eef79c23d7b02189/maven/repo-higom'
  80 + }
  81 + }
  82 +
  83 + project.configurations.configureEach {
  84 + resolutionStrategy.eachDependency { details ->
  85 + if (details.requested.group == 'com.android.android.support' && !details.requested.name.contains('multidex')) {
  86 + details.useVersion "28.0.0"
  87 + }
  88 +
  89 + }
  90 + }
  91 +
  92 + // 强制依赖
  93 + configurations.configureEach {
  94 + exclude group: 'com.alipay.android.phone.thirdparty', module: 'securityguard-build'
  95 + resolutionStrategy {
  96 + force 'androidx.activity:activity:1.2.1'
  97 + force 'androidx.annotation:annotation:1.1.0'
  98 + force 'androidx.appcompat:appcompat:1.2.0'
  99 + force 'androidx.arch.core:core-common:2.1.0'
  100 + force 'androidx.arch.core:core-runtime:2.1.0'
  101 + force 'androidx.core:core-ktx:1.6.0'
  102 + force 'androidx.core:core:1.5.0'
  103 + force 'androidx.collection:collection:1.1.0'
  104 + force 'androidx.constraintlayout:constraintlayout:2.0.4'
  105 + force 'androidx.constraintlayout:constraintlayout-solver:2.0.4'
  106 + force 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
  107 + force 'androidx.fragment:fragment:1.3.1'
  108 + force 'androidx.lifecycle:lifecycle-common:2.3.0'
  109 + force 'androidx.multidex:multidex:2.0.1'
  110 + force 'androidx.recyclerview:recyclerview:1.2.0'
  111 + force 'androidx.vectordrawable:vectordrawable:1.1.0'
  112 + force 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
  113 + force 'com.squareup.okhttp3:okhttp:4.9.1'
  114 + force 'com.squareup.okio:okio:2.7.0'
  115 + force 'org.jetbrains.kotlin:kotlin-stdlib:1.4.32'
  116 + force 'org.jetbrains.kotlin:kotilin-stdlib-jdk8:1.4.32'
  117 + force 'org.jetbrains:annotations:15.0'
  118 + force 'net.sf.proguard:proguard-base:6.1.0'
  119 + }
  120 + }
  121 +}
  122 +
  123 +ext {
  124 + var = [
  125 + // SDK And Tools
  126 + applicationId : "com.wondertek.dss",
  127 + minSdkVersion : 25,
  128 + targetSdkVersion : 30,
  129 + compileSdkVersion: 30,
  130 + buildToolsVersion: "30.0.3",
  131 + // 版本号,正式版本 1.0.0 1000080 后两位,80即标识为发布版本
  132 + // 测试版本 1.0.0_TF1 1000001 后两位,01即为测试版本号,01-79
  133 + // 升级版本 1.0.0_RC1 1000081 后两位,81即为升级版本号,81-99
  134 + versionName : "1.0.0", // release正式
  135 + debugVnName : "", // debug开发模式 用于区分debug模式下上报的日志
  136 + versionCode : 100,
  137 + //此版本号是SDK版本,不能随便改
  138 + aar_version : "1.0.0",
  139 + ]
  140 +
  141 +}
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<profiles version="12">
  3 + <profile kind="CodeFormatterProfile" name="WonderTek_CodeFormatter_Convention_v1.0"
  4 + version="12">
  5 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert" />
  6 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations"
  7 + value="insert" />
  8 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration"
  9 + value="insert" />
  10 + <setting
  11 + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression"
  12 + value="do not insert" />
  13 + <setting
  14 + id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration"
  15 + value="insert" />
  16 + <setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment"
  17 + value="common_lines" />
  18 + <setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries"
  19 + value="true" />
  20 + <setting
  21 + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters"
  22 + value="insert" />
  23 + <setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter"
  24 + value="do not insert" />
  25 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package"
  26 + value="insert" />
  27 + <setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation"
  28 + value="common_lines" />
  29 + <setting
  30 + id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant"
  31 + value="do not insert" />
  32 + <setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1" />
  33 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while"
  34 + value="do not insert" />
  35 + <setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags"
  36 + value="insert" />
  37 + <setting
  38 + id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration"
  39 + value="do not insert" />
  40 + <setting
  41 + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws"
  42 + value="do not insert" />
  43 + <setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement"
  44 + value="common_lines" />
  45 + <setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true" />
  46 + <setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4" />
  47 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator"
  48 + value="do not insert" />
  49 + <setting
  50 + id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration"
  51 + value="common_lines" />
  52 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments"
  53 + value="insert" />
  54 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments"
  55 + value="insert" />
  56 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits"
  57 + value="do not insert" />
  58 + <setting
  59 + id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration"
  60 + value="do not insert" />
  61 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for"
  62 + value="insert" />
  63 + <setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off" />
  64 + <setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="1" />
  65 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="49" />
  66 + <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1" />
  67 + <setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1" />
  68 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator"
  69 + value="insert" />
  70 + <setting
  71 + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations"
  72 + value="insert" />
  73 + <setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement"
  74 + value="common_lines" />
  75 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant"
  76 + value="16" />
  77 + <setting
  78 + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference"
  79 + value="do not insert" />
  80 + <setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true" />
  81 + <setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch"
  82 + value="true" />
  83 + <setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on" />
  84 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block"
  85 + value="insert" />
  86 + <setting
  87 + id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return"
  88 + value="insert" />
  89 + <setting
  90 + id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration"
  91 + value="20" />
  92 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter"
  93 + value="do not insert" />
  94 + <setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line"
  95 + value="false" />
  96 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field"
  97 + value="insert" />
  98 + <setting
  99 + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments"
  100 + value="insert" />
  101 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block"
  102 + value="insert" />
  103 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator"
  104 + value="do not insert" />
  105 + <setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations"
  106 + value="1" />
  107 + <setting
  108 + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer"
  109 + value="do not insert" />
  110 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for"
  111 + value="do not insert" />
  112 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch"
  113 + value="do not insert" />
  114 + <setting
  115 + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments"
  116 + value="do not insert" />
  117 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method"
  118 + value="insert" />
  119 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch"
  120 + value="do not insert" />
  121 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references"
  122 + value="16" />
  123 + <setting
  124 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration"
  125 + value="insert" />
  126 + <setting
  127 + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression"
  128 + value="do not insert" />
  129 + <setting
  130 + id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant"
  131 + value="insert" />
  132 + <setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column"
  133 + value="false" />
  134 + <setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error" />
  135 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter"
  136 + value="insert" />
  137 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits"
  138 + value="insert" />
  139 + <setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block"
  140 + value="true" />
  141 + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration"
  142 + value="end_of_line" />
  143 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard"
  144 + value="do not insert" />
  145 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation"
  146 + value="do not insert" />
  147 + <setting
  148 + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments"
  149 + value="do not insert" />
  150 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch"
  151 + value="insert" />
  152 + <setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120" />
  153 + <setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false" />
  154 + <setting
  155 + id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression"
  156 + value="do not insert" />
  157 + <setting
  158 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant"
  159 + value="insert" />
  160 + <setting
  161 + id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation"
  162 + value="do not insert" />
  163 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator"
  164 + value="insert" />
  165 + <setting
  166 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration"
  167 + value="insert" />
  168 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for"
  169 + value="do not insert" />
  170 + <setting
  171 + id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments"
  172 + value="true" />
  173 + <setting
  174 + id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable"
  175 + value="insert" />
  176 + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration"
  177 + value="end_of_line" />
  178 + <setting
  179 + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation"
  180 + value="do not insert" />
  181 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch"
  182 + value="16" />
  183 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for"
  184 + value="insert" />
  185 + <setting
  186 + id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body"
  187 + value="0" />
  188 + <setting
  189 + id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments"
  190 + value="insert" />
  191 + <setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line"
  192 + value="false" />
  193 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16" />
  194 + <setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause"
  195 + value="common_lines" />
  196 + <setting
  197 + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference"
  198 + value="insert" />
  199 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer"
  200 + value="do not insert" />
  201 + <setting
  202 + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations"
  203 + value="insert" />
  204 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation"
  205 + value="do not insert" />
  206 + <setting
  207 + id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call"
  208 + value="16" />
  209 + <setting
  210 + id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header"
  211 + value="true" />
  212 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces"
  213 + value="insert" />
  214 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default"
  215 + value="do not insert" />
  216 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional"
  217 + value="insert" />
  218 + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line" />
  219 + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration"
  220 + value="end_of_line" />
  221 + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body"
  222 + value="end_of_line" />
  223 + <setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true" />
  224 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters"
  225 + value="do not insert" />
  226 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch"
  227 + value="insert" />
  228 + <setting
  229 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation"
  230 + value="do not insert" />
  231 + <setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true" />
  232 + <setting
  233 + id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration"
  234 + value="20" />
  235 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="16" />
  236 + <setting
  237 + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments"
  238 + value="insert" />
  239 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation"
  240 + value="16" />
  241 + <setting
  242 + id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration"
  243 + value="20" />
  244 + <setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error" />
  245 + <setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment"
  246 + value="true" />
  247 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement"
  248 + value="do not insert" />
  249 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try"
  250 + value="insert" />
  251 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing"
  252 + value="do not insert" />
  253 + <setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment"
  254 + value="true" />
  255 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer"
  256 + value="insert" />
  257 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator"
  258 + value="insert" />
  259 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator"
  260 + value="do not insert" />
  261 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer"
  262 + value="20" />
  263 + <setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column"
  264 + value="true" />
  265 + <setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1" />
  266 + <setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation"
  267 + value="common_lines" />
  268 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case"
  269 + value="insert" />
  270 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis"
  271 + value="do not insert" />
  272 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources"
  273 + value="do not insert" />
  274 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert"
  275 + value="insert" />
  276 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if"
  277 + value="do not insert" />
  278 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments"
  279 + value="do not insert" />
  280 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter"
  281 + value="insert" />
  282 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration"
  283 + value="insert" />
  284 + <setting
  285 + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression"
  286 + value="do not insert" />
  287 + <setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true" />
  288 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement"
  289 + value="insert" />
  290 + <setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false" />
  291 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="20" />
  292 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body"
  293 + value="insert" />
  294 + <setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header"
  295 + value="true" />
  296 + <setting
  297 + id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration"
  298 + value="do not insert" />
  299 + <setting
  300 + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant"
  301 + value="do not insert" />
  302 + <setting
  303 + id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration"
  304 + value="16" />
  305 + <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration"
  306 + value="0" />
  307 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression"
  308 + value="16" />
  309 + <setting
  310 + id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer"
  311 + value="do not insert" />
  312 + <setting
  313 + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters"
  314 + value="do not insert" />
  315 + <setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line"
  316 + value="false" />
  317 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if"
  318 + value="insert" />
  319 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type"
  320 + value="insert" />
  321 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block"
  322 + value="insert" />
  323 + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration"
  324 + value="end_of_line" />
  325 + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case"
  326 + value="end_of_line" />
  327 + <setting
  328 + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration"
  329 + value="do not insert" />
  330 + <setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false" />
  331 + <setting
  332 + id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression"
  333 + value="16" />
  334 + <setting
  335 + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation"
  336 + value="do not insert" />
  337 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while"
  338 + value="insert" />
  339 + <setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled" />
  340 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch"
  341 + value="do not insert" />
  342 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="16" />
  343 + <setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true" />
  344 + <setting
  345 + id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration"
  346 + value="do not insert" />
  347 + <setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator"
  348 + value="true" />
  349 + <setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases"
  350 + value="true" />
  351 + <setting
  352 + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression"
  353 + value="do not insert" />
  354 + <setting
  355 + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized"
  356 + value="do not insert" />
  357 + <setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines"
  358 + value="2147483647" />
  359 + <setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries"
  360 + value="true" />
  361 + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration"
  362 + value="end_of_line" />
  363 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for"
  364 + value="insert" />
  365 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="16" />
  366 + <setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations"
  367 + value="false" />
  368 + <setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause"
  369 + value="common_lines" />
  370 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation"
  371 + value="80" />
  372 + <setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column"
  373 + value="false" />
  374 + <setting id="org.eclipse.jdt.core.compiler.source" value="1.8" />
  375 + <setting
  376 + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized"
  377 + value="do not insert" />
  378 + <setting
  379 + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws"
  380 + value="insert" />
  381 + <setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4" />
  382 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant"
  383 + value="insert" />
  384 + <setting
  385 + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression"
  386 + value="insert" />
  387 + <setting
  388 + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference"
  389 + value="do not insert" />
  390 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional"
  391 + value="insert" />
  392 + <setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true" />
  393 + <setting
  394 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer"
  395 + value="insert" />
  396 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try"
  397 + value="do not insert" />
  398 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources"
  399 + value="insert" />
  400 + <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="1" />
  401 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation"
  402 + value="do not insert" />
  403 + <setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer"
  404 + value="1" />
  405 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard"
  406 + value="do not insert" />
  407 + <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1" />
  408 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration"
  409 + value="16" />
  410 + <setting
  411 + id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration"
  412 + value="16" />
  413 + <setting
  414 + id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw"
  415 + value="insert" />
  416 + <setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator"
  417 + value="false" />
  418 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement"
  419 + value="do not insert" />
  420 + <setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8" />
  421 + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch"
  422 + value="end_of_line" />
  423 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces"
  424 + value="do not insert" />
  425 + <setting
  426 + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters"
  427 + value="insert" />
  428 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation"
  429 + value="do not insert" />
  430 + <setting
  431 + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer"
  432 + value="do not insert" />
  433 + <setting
  434 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression"
  435 + value="do not insert" />
  436 + <setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true" />
  437 + <setting
  438 + id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration"
  439 + value="do not insert" />
  440 + <setting
  441 + id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters"
  442 + value="insert" />
  443 + <setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration"
  444 + value="common_lines" />
  445 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16" />
  446 + <setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false" />
  447 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="16" />
  448 + <setting
  449 + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference"
  450 + value="do not insert" />
  451 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator"
  452 + value="do not insert" />
  453 + <setting
  454 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant"
  455 + value="do not insert" />
  456 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation"
  457 + value="16" />
  458 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations"
  459 + value="do not insert" />
  460 + <setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line"
  461 + value="true" />
  462 + <setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch"
  463 + value="true" />
  464 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement"
  465 + value="do not insert" />
  466 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator"
  467 + value="insert" />
  468 + <setting
  469 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration"
  470 + value="do not insert" />
  471 + <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1" />
  472 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label"
  473 + value="do not insert" />
  474 + <setting
  475 + id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header"
  476 + value="true" />
  477 + <setting
  478 + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression"
  479 + value="do not insert" />
  480 + <setting
  481 + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration"
  482 + value="do not insert" />
  483 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional"
  484 + value="insert" />
  485 + <setting
  486 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference"
  487 + value="do not insert" />
  488 + <setting
  489 + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters"
  490 + value="do not insert" />
  491 + <setting
  492 + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments"
  493 + value="do not insert" />
  494 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast"
  495 + value="do not insert" />
  496 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert"
  497 + value="insert" />
  498 + <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1" />
  499 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement"
  500 + value="do not insert" />
  501 + <setting
  502 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference"
  503 + value="do not insert" />
  504 + <setting
  505 + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference"
  506 + value="do not insert" />
  507 + <setting
  508 + id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression"
  509 + value="16" />
  510 + <setting
  511 + id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer"
  512 + value="do not insert" />
  513 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration"
  514 + value="insert" />
  515 + <setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true" />
  516 + <setting
  517 + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration"
  518 + value="do not insert" />
  519 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if"
  520 + value="do not insert" />
  521 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon"
  522 + value="do not insert" />
  523 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator"
  524 + value="do not insert" />
  525 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try"
  526 + value="do not insert" />
  527 + <setting
  528 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments"
  529 + value="do not insert" />
  530 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast"
  531 + value="do not insert" />
  532 + <setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true" />
  533 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow"
  534 + value="insert" />
  535 + <setting
  536 + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration"
  537 + value="do not insert" />
  538 + <setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false" />
  539 + <setting
  540 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration"
  541 + value="insert" />
  542 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration"
  543 + value="16" />
  544 + <setting
  545 + id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference"
  546 + value="do not insert" />
  547 + <setting
  548 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters"
  549 + value="do not insert" />
  550 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for"
  551 + value="do not insert" />
  552 + <setting
  553 + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws"
  554 + value="insert" />
  555 + <setting
  556 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression"
  557 + value="do not insert" />
  558 + <setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body"
  559 + value="true" />
  560 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16" />
  561 + <setting
  562 + id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments"
  563 + value="insert" />
  564 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator"
  565 + value="do not insert" />
  566 + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer"
  567 + value="end_of_line" />
  568 + <setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true" />
  569 + <setting
  570 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration"
  571 + value="insert" />
  572 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters"
  573 + value="insert" />
  574 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch"
  575 + value="do not insert" />
  576 + <setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8" />
  577 + <setting
  578 + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference"
  579 + value="do not insert" />
  580 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation"
  581 + value="insert" />
  582 + <setting
  583 + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments"
  584 + value="do not insert" />
  585 + <setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration"
  586 + value="common_lines" />
  587 + <setting
  588 + id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer"
  589 + value="do not insert" />
  590 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case"
  591 + value="do not insert" />
  592 + <setting
  593 + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations"
  594 + value="do not insert" />
  595 + <setting
  596 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration"
  597 + value="insert" />
  598 + <setting
  599 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference"
  600 + value="do not insert" />
  601 + <setting
  602 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration"
  603 + value="do not insert" />
  604 + <setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested"
  605 + value="true" />
  606 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast"
  607 + value="insert" />
  608 + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant"
  609 + value="end_of_line" />
  610 + <setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration"
  611 + value="end_of_line" />
  612 + <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="1" />
  613 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for"
  614 + value="insert" />
  615 + <setting
  616 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized"
  617 + value="insert" />
  618 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments"
  619 + value="do not insert" />
  620 + <setting
  621 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration"
  622 + value="do not insert" />
  623 + <setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header"
  624 + value="16" />
  625 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while"
  626 + value="do not insert" />
  627 + <setting
  628 + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant"
  629 + value="do not insert" />
  630 + <setting
  631 + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments"
  632 + value="do not insert" />
  633 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation"
  634 + value="do not insert" />
  635 + <setting
  636 + id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters"
  637 + value="do not insert" />
  638 + <setting
  639 + id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header"
  640 + value="true" />
  641 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow"
  642 + value="insert" />
  643 + <setting
  644 + id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration"
  645 + value="insert" />
  646 + <setting
  647 + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws"
  648 + value="do not insert" />
  649 + <setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="false" />
  650 + <setting
  651 + id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters"
  652 + value="do not insert" />
  653 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional"
  654 + value="insert" />
  655 + <setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description"
  656 + value="false" />
  657 + <setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement"
  658 + value="do not insert" />
  659 + <setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space" />
  660 + <setting
  661 + id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations"
  662 + value="do not insert" />
  663 + <setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1" />
  664 + <setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120" />
  665 + <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation"
  666 + value="do not insert" />
  667 + <setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch"
  668 + value="insert" />
  669 + </profile>
  670 +</profiles>
  1 +# Project-wide Gradle settings.
  2 +# IDE (e.g. Android Studio) users:
  3 +# Gradle settings configured through the IDE *will override*
  4 +# any settings specified in this file.
  5 +# For more details on how to configure your build environment visit
  6 +# http://www.gradle.org/docs/current/userguide/build_environment.html
  7 +# Specifies the JVM arguments used for the daemon process.
  8 +# The setting is particularly useful for tweaking memory settings.
  9 +#org.gradle.jvmargs=-Xmx2048m
  10 +# When configured, Gradle will run in incubating parallel mode.
  11 +# This option should only be used with decoupled projects. More details, visit
  12 +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
  13 +# org.gradle.parallel=true
  14 +# AndroidX package structure to make it clearer which packages are bundled with the
  15 +# Android operating system, and which are packaged with your app's APK
  16 +# https://developer.android.com/topic/libraries/support-library/androidx-rn
  17 +android.useAndroidX=true
  18 +# Automatically convert third-party libraries to use AndroidX
  19 +android.enableJetifier=true
  20 +android.enableResourceOptimizations=false
  21 +#建议您关闭 R8 后再进行混淆
  22 +android.enableR8=false
  23 +android.enableR8.libraries=false
  24 +# 如果使用最新稳定版本 Android Studio 3.5 或以上,那么您需要在 gradle.properties 里面新增
  25 +android.buildOnlyTargetAbi=false
  26 +#网络请求接口版本 202204151851
  27 +requestVersion=107
  28 +#设置组件是否作为app还是lib,true是lib ,false 是app
  29 +#分享
  30 +isShareModule=true
  31 +#播放器
  32 +isPlayerModule=true
  33 +#是否直播模块运行 false可以单独运行
  34 +isLiveModule=true
  35 +org.gradle.daemon=true
  36 +org.gradle.parallel=true
  37 +org.gradle.configureondemand=true
  38 +org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
  39 +# Kotlin code style for this project: "official" or "obsolete":
  40 +kotlin.code.style=official
  41 +# Enables namespacing of each library's R class so that its R class includes only the
  42 +# resources declared in the library itself and none from the library's dependencies,
  43 +# thereby reducing the size of the R class for that library
  44 +#android.nonTransitiveRClass=true
  45 +
  46 +
No preview for this file type
  1 +#Fri Oct 23 14:37:25 CST 2020
  2 +distributionBase=GRADLE_USER_HOME
  3 +distributionPath=wrapper/dists
  4 +zipStoreBase=GRADLE_USER_HOME
  5 +zipStorePath=wrapper/dists
  6 +distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-6.8-all.zip
  1 +#!/usr/bin/env sh
  2 +
  3 +##############################################################################
  4 +##
  5 +## Gradle start up script for UN*X
  6 +##
  7 +##############################################################################
  8 +
  9 +# Attempt to set APP_HOME
  10 +# Resolve links: $0 may be a link
  11 +PRG="$0"
  12 +# Need this for relative symlinks.
  13 +while [ -h "$PRG" ] ; do
  14 + ls=`ls -ld "$PRG"`
  15 + link=`expr "$ls" : '.*-> \(.*\)$'`
  16 + if expr "$link" : '/.*' > /dev/null; then
  17 + PRG="$link"
  18 + else
  19 + PRG=`dirname "$PRG"`"/$link"
  20 + fi
  21 +done
  22 +SAVED="`pwd`"
  23 +cd "`dirname \"$PRG\"`/" >/dev/null
  24 +APP_HOME="`pwd -P`"
  25 +cd "$SAVED" >/dev/null
  26 +
  27 +APP_NAME="Gradle"
  28 +APP_BASE_NAME=`basename "$0"`
  29 +
  30 +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
  31 +DEFAULT_JVM_OPTS=""
  32 +
  33 +# Use the maximum available, or set MAX_FD != -1 to use that value.
  34 +MAX_FD="maximum"
  35 +
  36 +warn () {
  37 + echo "$*"
  38 +}
  39 +
  40 +die () {
  41 + echo
  42 + echo "$*"
  43 + echo
  44 + exit 1
  45 +}
  46 +
  47 +# OS specific support (must be 'true' or 'false').
  48 +cygwin=false
  49 +msys=false
  50 +darwin=false
  51 +nonstop=false
  52 +case "`uname`" in
  53 + CYGWIN* )
  54 + cygwin=true
  55 + ;;
  56 + Darwin* )
  57 + darwin=true
  58 + ;;
  59 + MINGW* )
  60 + msys=true
  61 + ;;
  62 + NONSTOP* )
  63 + nonstop=true
  64 + ;;
  65 +esac
  66 +
  67 +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
  68 +
  69 +# Determine the Java command to use to start the JVM.
  70 +if [ -n "$JAVA_HOME" ] ; then
  71 + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
  72 + # IBM's JDK on AIX uses strange locations for the executables
  73 + JAVACMD="$JAVA_HOME/jre/sh/java"
  74 + else
  75 + JAVACMD="$JAVA_HOME/bin/java"
  76 + fi
  77 + if [ ! -x "$JAVACMD" ] ; then
  78 + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
  79 +
  80 +Please set the JAVA_HOME variable in your environment to match the
  81 +location of your Java installation."
  82 + fi
  83 +else
  84 + JAVACMD="java"
  85 + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
  86 +
  87 +Please set the JAVA_HOME variable in your environment to match the
  88 +location of your Java installation."
  89 +fi
  90 +
  91 +# Increase the maximum file descriptors if we can.
  92 +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
  93 + MAX_FD_LIMIT=`ulimit -H -n`
  94 + if [ $? -eq 0 ] ; then
  95 + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
  96 + MAX_FD="$MAX_FD_LIMIT"
  97 + fi
  98 + ulimit -n $MAX_FD
  99 + if [ $? -ne 0 ] ; then
  100 + warn "Could not set maximum file descriptor limit: $MAX_FD"
  101 + fi
  102 + else
  103 + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
  104 + fi
  105 +fi
  106 +
  107 +# For Darwin, add options to specify how the application appears in the dock
  108 +if $darwin; then
  109 + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
  110 +fi
  111 +
  112 +# For Cygwin, switch paths to Windows format before running java
  113 +if $cygwin ; then
  114 + APP_HOME=`cygpath --path --mixed "$APP_HOME"`
  115 + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
  116 + JAVACMD=`cygpath --unix "$JAVACMD"`
  117 +
  118 + # We build the pattern for arguments to be converted via cygpath
  119 + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
  120 + SEP=""
  121 + for dir in $ROOTDIRSRAW ; do
  122 + ROOTDIRS="$ROOTDIRS$SEP$dir"
  123 + SEP="|"
  124 + done
  125 + OURCYGPATTERN="(^($ROOTDIRS))"
  126 + # Add a user-defined pattern to the cygpath arguments
  127 + if [ "$GRADLE_CYGPATTERN" != "" ] ; then
  128 + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
  129 + fi
  130 + # Now convert the arguments - kludge to limit ourselves to /bin/sh
  131 + i=0
  132 + for arg in "$@" ; do
  133 + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
  134 + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
  135 +
  136 + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
  137 + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
  138 + else
  139 + eval `echo args$i`="\"$arg\""
  140 + fi
  141 + i=$((i+1))
  142 + done
  143 + case $i in
  144 + (0) set -- ;;
  145 + (1) set -- "$args0" ;;
  146 + (2) set -- "$args0" "$args1" ;;
  147 + (3) set -- "$args0" "$args1" "$args2" ;;
  148 + (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
  149 + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
  150 + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
  151 + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
  152 + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
  153 + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
  154 + esac
  155 +fi
  156 +
  157 +# Escape application args
  158 +save () {
  159 + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
  160 + echo " "
  161 +}
  162 +APP_ARGS=$(save "$@")
  163 +
  164 +# Collect all arguments for the java command, following the shell quoting and substitution rules
  165 +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
  166 +
  167 +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
  168 +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
  169 + cd "$(dirname "$0")"
  170 +fi
  171 +
  172 +exec "$JAVACMD" "$@"
  1 +@if "%DEBUG%" == "" @echo off
  2 +@rem ##########################################################################
  3 +@rem
  4 +@rem Gradle startup script for Windows
  5 +@rem
  6 +@rem ##########################################################################
  7 +
  8 +@rem Set local scope for the variables with windows NT shell
  9 +if "%OS%"=="Windows_NT" setlocal
  10 +
  11 +set DIRNAME=%~dp0
  12 +if "%DIRNAME%" == "" set DIRNAME=.
  13 +set APP_BASE_NAME=%~n0
  14 +set APP_HOME=%DIRNAME%
  15 +
  16 +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
  17 +set DEFAULT_JVM_OPTS=
  18 +
  19 +@rem Find java.exe
  20 +if defined JAVA_HOME goto findJavaFromJavaHome
  21 +
  22 +set JAVA_EXE=java.exe
  23 +%JAVA_EXE% -version >NUL 2>&1
  24 +if "%ERRORLEVEL%" == "0" goto init
  25 +
  26 +echo.
  27 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
  28 +echo.
  29 +echo Please set the JAVA_HOME variable in your environment to match the
  30 +echo location of your Java installation.
  31 +
  32 +goto fail
  33 +
  34 +:findJavaFromJavaHome
  35 +set JAVA_HOME=%JAVA_HOME:"=%
  36 +set JAVA_EXE=%JAVA_HOME%/bin/java.exe
  37 +
  38 +if exist "%JAVA_EXE%" goto init
  39 +
  40 +echo.
  41 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
  42 +echo.
  43 +echo Please set the JAVA_HOME variable in your environment to match the
  44 +echo location of your Java installation.
  45 +
  46 +goto fail
  47 +
  48 +:init
  49 +@rem Get command-line arguments, handling Windows variants
  50 +
  51 +if not "%OS%" == "Windows_NT" goto win9xME_args
  52 +
  53 +:win9xME_args
  54 +@rem Slurp the command line arguments.
  55 +set CMD_LINE_ARGS=
  56 +set _SKIP=2
  57 +
  58 +:win9xME_args_slurp
  59 +if "x%~1" == "x" goto execute
  60 +
  61 +set CMD_LINE_ARGS=%*
  62 +
  63 +:execute
  64 +@rem Setup the command line
  65 +
  66 +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
  67 +
  68 +@rem Execute Gradle
  69 +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
  70 +
  71 +:end
  72 +@rem End local scope for the variables with windows NT shell
  73 +if "%ERRORLEVEL%"=="0" goto mainEnd
  74 +
  75 +:fail
  76 +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
  77 +rem the _cmd.exe /c_ return code!
  78 +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
  79 +exit /b 1
  80 +
  81 +:mainEnd
  82 +if "%OS%"=="Windows_NT" endlocal
  83 +
  84 +:omega
  1 +rootProject.name = "wdkitcore"
  2 +include ':app'
  3 +include ':wdkitcore'
  1 +plugins {
  2 + id 'com.android.library'
  3 + id 'kotlin-android'
  4 + id 'maven'
  5 +}
  6 +
  7 +android {
  8 + compileSdkVersion var.compileSdkVersion
  9 +
  10 + defaultConfig {
  11 + minSdkVersion var.minSdkVersion
  12 + targetSdkVersion var.targetSdkVersion
  13 + versionCode var.versionCode
  14 + versionName var.versionName
  15 +
  16 + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  17 + consumerProguardFiles "consumer-rules.pro"
  18 +
  19 + buildConfigField "String", "API_VERSION", "\"${requestVersion}\""
  20 + }
  21 +
  22 + buildTypes {
  23 + release {
  24 + minifyEnabled false
  25 + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
  26 + }
  27 + }
  28 + compileOptions {
  29 + sourceCompatibility JavaVersion.VERSION_1_8
  30 + targetCompatibility JavaVersion.VERSION_1_8
  31 + }
  32 +
  33 + // 自定义AAR包名
  34 + android.libraryVariants.all { variant ->
  35 + variant.outputs.all {
  36 + if (outputFileName != null && outputFileName.endsWith(".aar")) {
  37 + def fileName = "${project.name}-${buildType.name}-v${var.aar_version}.aar"
  38 + outputFileName = fileName
  39 + }
  40 + }
  41 + }
  42 +}
  43 +
  44 +dependencies {
  45 + implementation 'androidx.appcompat:appcompat:1.2.0'
  46 + implementation 'com.wd:log:1.0.0'
  47 +}
  48 +
  49 +uploadArchives {
  50 + repositories {
  51 + mavenDeployer {
  52 + repository(url: "https://packages.aliyun.com/6708d221eef79c23d7b02189/maven/repo-higom/") {
  53 + authentication(userName: '6708d1cf6f4c940bd257c88d', password: 'Wm51gc4rARyr')
  54 + }
  55 + pom.project {
  56 + artifactId 'wdkit'
  57 + version '1.0.0'
  58 + groupId 'com.wd'
  59 + packaging 'aar'
  60 + }
  61 + }
  62 + }
  63 +}
  1 +# Add project specific ProGuard rules here.
  2 +# You can control the set of applied configuration files using the
  3 +# proguardFiles setting in build.gradle.
  4 +#
  5 +# For more details, see
  6 +# http://developer.android.com/guide/developing/tools/proguard.html
  7 +
  8 +# If your project uses WebView with JS, uncomment the following
  9 +# and specify the fully qualified class name to the JavaScript interface
  10 +# class:
  11 +#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
  12 +# public *;
  13 +#}
  14 +
  15 +# Uncomment this to preserve the line number information for
  16 +# debugging stack traces.
  17 +#-keepattributes SourceFile,LineNumberTable
  18 +
  19 +# If you keep the line number information, uncomment this to
  20 +# hide the original source file name.
  21 +#-renamesourcefileattribute SourceFile
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3 + package="com.wd.foundation.wdkitcore">
  4 +
  5 +</manifest>
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.scheduler;
  6 +
  7 +import com.wd.base.log.Logger;
  8 +
  9 +/**
  10 + * <组件基类>
  11 + *
  12 + * @author wangnaiwen
  13 + * @version [V1.0.0.0, 2020/5/23]
  14 + * @since V1.0.0.0
  15 + */
  16 +public abstract class BaseComponent {
  17 +
  18 + /**
  19 + * 注册服务:子类实现
  20 + */
  21 + public abstract void registerServices();
  22 +
  23 + protected void registerService(Class<? extends IService> serviceApiClazz,
  24 + Class<? extends IService> serviceImplClass) {
  25 + if (serviceImplClass != null && serviceApiClazz != null) {
  26 + WComponent.registerService(serviceApiClazz, serviceImplClass);
  27 + } else {
  28 + Logger.t("XC:BaseComponent").w("register service failed, api or impl class is null");
  29 + }
  30 + }
  31 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.scheduler;
  6 +
  7 +import java.util.Collection;
  8 +import java.util.HashMap;
  9 +import java.util.Map;
  10 +
  11 +import android.text.TextUtils;
  12 +
  13 +import com.wd.base.log.Logger;
  14 +import com.wd.foundation.wdkit.tools.CastUtils;
  15 +import com.wd.foundation.wdkit.tools.ReflectionUtils;
  16 +
  17 +/**
  18 + * <组件持有者>
  19 + *
  20 + * @author wangnaiwen
  21 + * @version [V1.0.0.0, 2020/5/23]
  22 + * @since V1.0.0.0
  23 + */
  24 +public class ComponentHolder {
  25 +
  26 + private static final String TAG = "ComponentHolder";
  27 +
  28 + /**
  29 + * 组件持有者
  30 + */
  31 + private Map<String, BaseComponent> mComponentService = new HashMap<>();
  32 +
  33 + /**
  34 + * 组件注册器
  35 + *
  36 + * @param componentName 组件名称
  37 + * @param componentClazzFull 组件类全路径名
  38 + */
  39 + protected void registerComponent(String componentName, String componentClazzFull) {
  40 + if (TextUtils.isEmpty(componentName)) {
  41 + Logger.t(TAG).w("registerComponent failed, componentName is empty");
  42 + return;
  43 + }
  44 + if (TextUtils.isEmpty(componentClazzFull)) {
  45 + Logger.t(TAG).w("registerComponent failed, componentClazzFull is empty");
  46 + }
  47 +
  48 + BaseComponent component = createInstance(componentClazzFull);
  49 + if (component == null) {
  50 + Logger.t(TAG).w("registerComponent failed, component is null, please check the componentClazzFull");
  51 + }
  52 + mComponentService.put(componentName, component);
  53 + }
  54 +
  55 + private BaseComponent createInstance(String componentClazzFull) {
  56 + Class clazz = ReflectionUtils.getClass(componentClazzFull);
  57 + if (clazz == null) {
  58 + Logger.t(TAG).w("createInstance failed, clazz is not exist");
  59 + return null;
  60 + }
  61 + if (!ReflectionUtils.isSubClassOf(clazz, BaseComponent.class)) {
  62 + Logger.t(TAG).w("createInstance failed, clazz is not sub of BaseComponent");
  63 + return null;
  64 + }
  65 + BaseComponent component = CastUtils.cast(ReflectionUtils.newInstance(clazz), BaseComponent.class);
  66 + if (component == null) {
  67 + Logger.t(TAG).w("createInstance failed, get instance is null");
  68 + }
  69 + return component;
  70 + }
  71 +
  72 + /**
  73 + * 获得全部组件
  74 + *
  75 + * @return 全部组件
  76 + */
  77 + protected Collection<BaseComponent> getComponents() {
  78 + return mComponentService.values();
  79 + }
  80 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.scheduler;
  6 +
  7 +import java.util.Collection;
  8 +
  9 +import com.wd.base.log.Logger;
  10 +import com.wd.foundation.wdkit.scheduler.listener.IComponentRegister;
  11 +import com.wd.foundation.wdkit.scheduler.listener.InitListener;
  12 +import com.wd.foundation.wdkit.thread.ThreadPoolUtils;
  13 +import com.wd.foundation.wdkit.tools.CastUtils;
  14 +
  15 +/**
  16 + * <组件管理器>
  17 + *
  18 + * @author wangnaiwen
  19 + * @version [V1.0.0.0, 2020/4/7]
  20 + * @since V1.0.0.0
  21 + */
  22 +public class ComponentManager {
  23 +
  24 + private static final String TAG = "ComponentManager";
  25 +
  26 + /**
  27 + * 组件持有者
  28 + */
  29 + private ComponentHolder mComponentHolder = new ComponentHolder();
  30 +
  31 + /**
  32 + * 服务持有者
  33 + */
  34 + private ServiceHolder mServiceHolder = new ServiceHolder();
  35 +
  36 + /**
  37 + * 同步初始化
  38 + *
  39 + * @param listener 初始化监听
  40 + */
  41 + protected void init(InitListener listener) {
  42 + innerInit(listener);
  43 + }
  44 +
  45 + /**
  46 + * 异步初始化
  47 + *
  48 + * @param listener 初始化监听
  49 + */
  50 + protected void asynInit(final InitListener listener) {
  51 + ThreadPoolUtils.emergencySubmit(new Runnable() {
  52 + @Override
  53 + public void run() {
  54 + innerInit(listener);
  55 + }
  56 + });
  57 + }
  58 +
  59 + private void innerInit(InitListener listener) {
  60 + listener.beforeInit();
  61 + listener.registerComponent(new IComponentRegister() {
  62 + @Override
  63 + public void registerComponent(String componentName, String componentClazzFull) {
  64 + mComponentHolder.registerComponent(componentName, componentClazzFull);
  65 + }
  66 + });
  67 + registerService();
  68 + listener.initFinish();
  69 + }
  70 +
  71 + private void registerService() {
  72 + Collection collection = mComponentHolder.getComponents();
  73 + if (collection == null || collection.size() == 0) {
  74 + Logger.t(TAG).w("component collection is empty");
  75 + return;
  76 + }
  77 + for (Object object : collection) {
  78 + BaseComponent component = CastUtils.cast(object, BaseComponent.class);
  79 + if (component == null) {
  80 + continue;
  81 + }
  82 + component.registerServices();
  83 + }
  84 + }
  85 +
  86 + /**
  87 + * 获得组件服务
  88 + *
  89 + * @param serviceClazz 服务类
  90 + * @param <S> 服务类型
  91 + * @return 组件服务器
  92 + */
  93 + public <S extends IService> S getService(Class<S> serviceClazz) {
  94 + return (S) mServiceHolder.getService(serviceClazz);
  95 + }
  96 +
  97 + /**
  98 + * 注册服务组件
  99 + *
  100 + * @param serviceApi 服务接口
  101 + * @param serviceImpl 服务实现
  102 + */
  103 + public void registerService(Class<? extends IService> serviceApi, Class<? extends IService> serviceImpl) {
  104 + mServiceHolder.registerService(serviceApi, serviceImpl);
  105 + }
  106 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.scheduler;
  6 +
  7 +/**
  8 + * <服务接口类>
  9 + *
  10 + * @author wangnaiwen
  11 + * @version [V1.0.0.0, 2020/4/7]
  12 + * @since V1.0.0.0
  13 + */
  14 +public interface IService {
  15 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.scheduler;
  6 +
  7 +import java.util.HashMap;
  8 +import java.util.Map;
  9 +
  10 +import com.wd.base.log.Logger;
  11 +import com.wd.foundation.wdkit.tools.CastUtils;
  12 +import com.wd.foundation.wdkit.tools.ReflectionUtils;
  13 +
  14 +/**
  15 + * <服务的持有者>
  16 + *
  17 + * @author wangnaiwen
  18 + * @version [V1.0.0.0, 2020/5/23]
  19 + * @since V1.0.0.0
  20 + */
  21 +public class ServiceHolder {
  22 +
  23 + private static final String TAG = "ServiceHolder";
  24 +
  25 + /**
  26 + * 服务容器
  27 + */
  28 + private Map<String, IService> mServiceMap = new HashMap<>();
  29 +
  30 + public void registerService(Class<? extends IService> apiService, Class<? extends IService> serviceImpl) {
  31 + if (apiService == null) {
  32 + Logger.t(TAG).i("registerService failed, registerService is null");
  33 + return;
  34 + }
  35 + if (serviceImpl == null) {
  36 + Logger.t(TAG).i("registerService failed, serviceImpl is null");
  37 + return;
  38 + }
  39 + IService service = CastUtils.cast(ReflectionUtils.newInstance(serviceImpl), IService.class);
  40 + if (service == null) {
  41 + Logger.t(TAG).i("createServiceInstance failed, please check serviceImpl");
  42 + return;
  43 + }
  44 + mServiceMap.put(getKey(apiService), service);
  45 + }
  46 +
  47 + /**
  48 + * 获得组件服务
  49 + *
  50 + * @param serviceClazzApi 服务类
  51 + * @return 组件服务器
  52 + */
  53 + public IService getService(Class<? extends IService> serviceClazzApi) {
  54 + if (serviceClazzApi == null) {
  55 + Logger.t(TAG).i("getService failed, please check serviceClazzApi");
  56 + return null;
  57 + }
  58 + IService service = mServiceMap.get(getKey(serviceClazzApi));
  59 + if (service == null) {
  60 + Logger.t(TAG).i("getService failed, service has not init");
  61 + }
  62 + return service;
  63 + }
  64 +
  65 + private String getKey(Class<? extends IService> serviceClazzApi) {
  66 + return serviceClazzApi.getName();
  67 + }
  68 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.scheduler;
  6 +
  7 +import com.wd.foundation.wdkit.scheduler.listener.InitListener;
  8 +
  9 +/**
  10 + * <组件化:对外接口组件>
  11 + *
  12 + * @author wangnaiwen
  13 + * @version [V1.0.0.0, 2020/5/23]
  14 + * @since V1.0.0.0
  15 + */
  16 +public class WComponent {
  17 +
  18 + /**
  19 + * 组件管理器
  20 + */
  21 + private static ComponentManager mComponentManager = new ComponentManager();
  22 +
  23 + /**
  24 + * 初始化接口:同步
  25 + *
  26 + * @param listener 初始化监听器
  27 + */
  28 + public static void init(InitListener listener) {
  29 + mComponentManager.init(listener);
  30 + }
  31 +
  32 + /**
  33 + * 初始化接口:异步
  34 + *
  35 + * @param listener 初始化监听器
  36 + */
  37 + public static void asynInit(InitListener listener) {
  38 + mComponentManager.asynInit(listener);
  39 + }
  40 +
  41 + /**
  42 + * 获得组件服务
  43 + *
  44 + * @param serviceClazz 服务类
  45 + * @param <S> 服务类型
  46 + * @return 组件服务器
  47 + */
  48 + public static <S extends IService> S getService(Class<S> serviceClazz) {
  49 + return mComponentManager.getService(serviceClazz);
  50 + }
  51 +
  52 + /**
  53 + * 注册服务组件
  54 + *
  55 + * @param serviceApi 服务接口
  56 + * @param serviceImpl 服务实现
  57 + */
  58 + public static void registerService(Class<? extends IService> serviceApi, Class<? extends IService> serviceImpl) {
  59 + mComponentManager.registerService(serviceApi, serviceImpl);
  60 + }
  61 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.scheduler.listener;
  6 +
  7 +/**
  8 + * <组件注册器>
  9 + *
  10 + * @author wangnaiwen
  11 + * @version [V1.0.0.0, 2020/4/7]
  12 + * @since V1.0.0.0
  13 + */
  14 +public interface IComponentRegister {
  15 + /**
  16 + * 注册组件
  17 + *
  18 + * @param componentName 组件名称
  19 + * @param componentClazzFull 组件类全量名
  20 + */
  21 + void registerComponent(String componentName, String componentClazzFull);
  22 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.scheduler.listener;
  6 +
  7 +/**
  8 + * <初始化接口>
  9 + *
  10 + * @author wangnaiwen
  11 + * @version [V1.0.0.0, 2020/4/7]
  12 + * @since V1.0.0.0
  13 + */
  14 +public interface InitListener {
  15 +
  16 + /**
  17 + * 初始化之前
  18 + */
  19 + void beforeInit();
  20 +
  21 + /**
  22 + * 注册组件
  23 + *
  24 + * @param register 组件注册器
  25 + */
  26 + void registerComponent(IComponentRegister register);
  27 +
  28 + /**
  29 + * 初始化结束
  30 + */
  31 + void initFinish();
  32 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.thread;
  6 +
  7 +import java.util.ArrayList;
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * <自动释放的 Runnable 对象持有器>
  12 + *
  13 + * @author wangnaiwen
  14 + * @version [V1.0.0.0, 2020/5/23]
  15 + * @since V1.0.0.0
  16 + */
  17 +public final class AutoReleaseNestedHolder {
  18 + private List<Object> nestedObject = new ArrayList();
  19 +
  20 + private AutoReleaseNestedHolder() {
  21 + }
  22 +
  23 + public static AutoReleaseNestedHolder create() {
  24 + return new AutoReleaseNestedHolder();
  25 + }
  26 +
  27 + void deposit(Object obj) {
  28 + this.nestedObject.add(obj);
  29 + }
  30 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.thread;
  6 +
  7 +import java.lang.ref.WeakReference;
  8 +
  9 +import com.wd.base.log.Logger;
  10 +
  11 +/**
  12 + * <自动释放 Runnable>
  13 + *
  14 + * @author wangnaiwen
  15 + * @version [V1.0.0.0, 2020/5/23]
  16 + * @since V1.0.0.0
  17 + */
  18 +public abstract class AutoReleaseRunnable implements Runnable {
  19 + private static final String TAG = "AutoReleaseRunnable";
  20 +
  21 + private final WeakReference<AutoReleaseRunnable> ref;
  22 +
  23 + public AutoReleaseRunnable(AutoReleaseNestedHolder holder) {
  24 + if (holder == null) {
  25 + this.ref = null;
  26 + Logger.t(TAG).i("deposit holder is null");
  27 + } else {
  28 + holder.deposit(this);
  29 + this.ref = new WeakReference(this);
  30 + }
  31 + }
  32 +
  33 + static Runnable transfer(Runnable runnable) {
  34 + WeakReference<AutoReleaseRunnable> ref =
  35 + runnable instanceof AutoReleaseRunnable ? ((AutoReleaseRunnable) runnable).getRef() : null;
  36 + return (Runnable) (ref == null ? runnable : new AutoReleaseRunnableWrapper(runnable));
  37 + }
  38 +
  39 + private WeakReference<AutoReleaseRunnable> getRef() {
  40 + return this.ref;
  41 + }
  42 +
  43 + private static final class AutoReleaseRunnableWrapper implements Runnable {
  44 + private final WeakReference<AutoReleaseRunnable> autoReleaseRunnableRef;
  45 +
  46 + private AutoReleaseRunnableWrapper(Runnable runnable) {
  47 + this.autoReleaseRunnableRef =
  48 + runnable instanceof AutoReleaseRunnable ? ((AutoReleaseRunnable) runnable).getRef() : null;
  49 + }
  50 +
  51 + public void run() {
  52 + if (this.autoReleaseRunnableRef != null) {
  53 + AutoReleaseRunnable runnable = (AutoReleaseRunnable) this.autoReleaseRunnableRef.get();
  54 + if (runnable != null) {
  55 + runnable.run();
  56 + } else {
  57 + Logger.t(TAG).i("runnable is released");
  58 + }
  59 + }
  60 +
  61 + }
  62 + }
  63 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.thread;
  6 +
  7 +/**
  8 + * <取消接口>
  9 + *
  10 + * @author wangnaiwen
  11 + * @version [V1.0.0.0, 2020/05/23]
  12 + * @since V1.0.0.0
  13 + */
  14 +public interface Cancelable {
  15 +
  16 + /**
  17 + * 取消
  18 + */
  19 + void cancel();
  20 +
  21 + /**
  22 + * 是否已经取消
  23 + *
  24 + * @return true: 取消,false:未取消
  25 + */
  26 + boolean isCanceled();
  27 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.thread;
  6 +
  7 +import java.util.concurrent.ConcurrentHashMap;
  8 +import java.util.concurrent.atomic.AtomicLong;
  9 +
  10 +import androidx.lifecycle.Lifecycle;
  11 +import androidx.lifecycle.LifecycleObserver;
  12 +import androidx.lifecycle.OnLifecycleEvent;
  13 +
  14 +import com.wd.base.log.Logger;
  15 +
  16 +/**
  17 + * <带有生命周期的 Runnable>
  18 + *
  19 + * @author wangnaiwen
  20 + * @version [V1.0.0.0, 2020/4/7]
  21 + * @since V1.0.0.0
  22 + */
  23 +public abstract class LifecycleRunnable implements Runnable {
  24 + private static final String TAG = "LifecycleRunnable";
  25 +
  26 + private static final AtomicLong RUNNABLE_ID_COUNTER = new AtomicLong(0L);
  27 +
  28 + private static final ConcurrentHashMap<Long, LifecycleRunnable> RUNNABLE_CACHE = new ConcurrentHashMap();
  29 +
  30 + private final long runnableId;
  31 +
  32 + private final boolean isValid;
  33 +
  34 + public LifecycleRunnable(Lifecycle lifecycle) {
  35 + if (lifecycle != null) {
  36 + this.isValid = true;
  37 + this.runnableId = RUNNABLE_ID_COUNTER.getAndIncrement();
  38 + lifecycle.addObserver(new InnerLifecycleObserver(this.runnableId));
  39 + RUNNABLE_CACHE.put(this.runnableId, this);
  40 + Logger.t(TAG).i("register runnable:" + this.runnableId);
  41 + } else {
  42 + this.isValid = false;
  43 + this.runnableId = -1L;
  44 + Logger.t(TAG).i("lifecycle is null");
  45 + }
  46 +
  47 + }
  48 +
  49 + /**
  50 + * Runnable 转换成生命周期的 Runnable
  51 + *
  52 + * @param runnable 运行接口
  53 + * @return Runnable
  54 + */
  55 + static Runnable transfer(Runnable runnable) {
  56 + return (Runnable) (runnable instanceof LifecycleRunnable && ((LifecycleRunnable) runnable).isValid
  57 + ? new LifecycleRunnableWrapper(((LifecycleRunnable) runnable).runnableId) : runnable);
  58 + }
  59 +
  60 + /**
  61 + * 生命周期观察者
  62 + */
  63 + private static class InnerLifecycleObserver implements LifecycleObserver {
  64 + private final long runnableId;
  65 +
  66 + InnerLifecycleObserver(long id) {
  67 + this.runnableId = id;
  68 + }
  69 +
  70 + @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
  71 + public void onDestroy() {
  72 + Logger.t(TAG).i("remove runnable id:" + this.runnableId);
  73 + LifecycleRunnable.RUNNABLE_CACHE.remove(this.runnableId);
  74 + }
  75 + }
  76 +
  77 + private static class LifecycleRunnableWrapper implements Runnable {
  78 + private final long runnableId;
  79 +
  80 + LifecycleRunnableWrapper(long id) {
  81 + this.runnableId = id;
  82 + }
  83 +
  84 + public void run() {
  85 + Runnable runnable = (Runnable) LifecycleRunnable.RUNNABLE_CACHE.get(this.runnableId);
  86 + if (runnable != null) {
  87 + runnable.run();
  88 + } else {
  89 + Logger.t(TAG).i("runnable is released");
  90 + }
  91 +
  92 + }
  93 + }
  94 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.thread;
  6 +
  7 +import android.os.Handler;
  8 +
  9 +import androidx.annotation.Nullable;
  10 +
  11 +import com.wd.base.log.Logger;
  12 +
  13 +
  14 +/**
  15 + * <发送取消接口>
  16 + *
  17 + * @author wangnaiwen
  18 + * @version [V1.0.0.0, 2020/5/23]
  19 + * @since V1.0.0.0
  20 + */
  21 +final class PostCancelable implements Cancelable {
  22 + private static final String TAG = "PostCancelable";
  23 +
  24 + private final Runnable runnable;
  25 +
  26 + private final Handler handler;
  27 +
  28 + private volatile boolean canceled = false;
  29 +
  30 + private PostCancelable(@Nullable Handler h, @Nullable Runnable r) {
  31 + this.handler = h;
  32 + this.runnable = r;
  33 + }
  34 +
  35 + static PostCancelable from(@Nullable Handler h, @Nullable Runnable r) {
  36 + return new PostCancelable(h, r);
  37 + }
  38 +
  39 + public void cancel() {
  40 + if (this.runnable != null && this.handler != null) {
  41 + this.handler.removeCallbacks(this.runnable);
  42 + this.canceled = true;
  43 + } else {
  44 + Logger.t(TAG).e("runnable or handler not set, cannot cancel");
  45 + }
  46 + }
  47 +
  48 + public boolean isCanceled() {
  49 + return this.canceled;
  50 + }
  51 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.thread;
  6 +
  7 +import java.util.HashMap;
  8 +import java.util.Map;
  9 +import java.util.concurrent.BlockingQueue;
  10 +import java.util.concurrent.Future;
  11 +import java.util.concurrent.LinkedBlockingQueue;
  12 +import java.util.concurrent.RejectedExecutionException;
  13 +import java.util.concurrent.ScheduledThreadPoolExecutor;
  14 +import java.util.concurrent.SynchronousQueue;
  15 +import java.util.concurrent.ThreadFactory;
  16 +import java.util.concurrent.ThreadPoolExecutor;
  17 +import java.util.concurrent.TimeUnit;
  18 +import java.util.concurrent.atomic.AtomicInteger;
  19 +
  20 +import android.os.Handler;
  21 +import android.os.Looper;
  22 +import android.os.Process;
  23 +
  24 +import androidx.annotation.NonNull;
  25 +import androidx.annotation.Nullable;
  26 +
  27 +import com.wd.base.log.Logger;
  28 +import com.wd.foundation.wdkit.tools.StringUtils;
  29 +
  30 +/**
  31 + * <线程池工具类>
  32 + *
  33 + * @author wangnaiwen
  34 + * @version [V1.0.0.0, 2020/4/7]
  35 + * @since V1.0.0.0
  36 + */
  37 +public final class ThreadPoolUtils {
  38 +
  39 + private static final String TAG = "ThreadPoolUtil";
  40 +
  41 + /**
  42 + * CPU 个数
  43 + */
  44 + private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
  45 +
  46 + /**
  47 + * 主线程 Handler
  48 + */
  49 + private static final Handler MAIN_HANDLER = new Handler(Looper.getMainLooper());
  50 +
  51 + /**
  52 + * 一般优先级的线程池容量:和 CPU 一样多
  53 + */
  54 + private static final int NORMAL_POOL_SIZE = CPU_COUNT;
  55 +
  56 + /**
  57 + * 高优先级线程池大小
  58 + */
  59 + private static final int EMERGENCY_POOL_SIZE = 2;
  60 +
  61 + /**
  62 + * 低优先级线程池大小
  63 + */
  64 + private static final int BACKGROUND_POOL_SIZE = 2;
  65 +
  66 + /**
  67 + * 高优先级线程池
  68 + */
  69 + private static final ThreadPoolExecutor EMERGENCY_THREAD_POOL =
  70 + new ThreadPoolExecutor(EMERGENCY_POOL_SIZE, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue(),
  71 + new PriorityGroupedThreadFactory(Thread.MAX_PRIORITY, (String) null));;
  72 +
  73 + /**
  74 + * 普通优先级线程池
  75 + */
  76 + private static final ThreadPoolExecutor NORMAL_THREAD_POOL =
  77 + new ThreadPoolExecutor(NORMAL_POOL_SIZE, NORMAL_POOL_SIZE, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue(),
  78 + new PriorityGroupedThreadFactory(Thread.NORM_PRIORITY, (String) null));;
  79 +
  80 + /**
  81 + * 低优先级线程池
  82 + */
  83 + private static final ThreadPoolExecutor BACKGROUND_THREAD_POOL = new ThreadPoolExecutor(BACKGROUND_POOL_SIZE, 2, 0L,
  84 + TimeUnit.SECONDS, new LinkedBlockingQueue(), new PriorityGroupedThreadFactory(1, (String) null));
  85 +
  86 + /**
  87 + * 等待线程池
  88 + */
  89 + private static final ScheduledThreadPoolExecutor SCHEDULED_THREAD_POOL =
  90 + new ScheduledThreadPoolExecutor(NORMAL_POOL_SIZE);;
  91 +
  92 + /**
  93 + * 对象锁
  94 + */
  95 + private static final Object GROUP_LOCK = new Object();
  96 +
  97 + /**
  98 + * 普通的线程组池大小:1. (CPU个数 -1) 和 4 取最小值得到值 A 2. 值 A 和 2 取最大值,保证不低于两组
  99 + */
  100 + private static final int NORMAL_GROUP_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
  101 +
  102 + /**
  103 + * 线程组池的容器
  104 + */
  105 + private static final Map<String, ThreadPoolExecutor> GROUP_THREAD_POOLS = new HashMap<>();
  106 +
  107 + private ThreadPoolUtils() {
  108 + }
  109 +
  110 + /**
  111 + * 子线程执行:普通优先级
  112 + *
  113 + * @param runnable 运行接口
  114 + * @return 取消接口
  115 + */
  116 + public static Cancelable submit(Runnable runnable) {
  117 + return submitInner(runnable, Thread.NORM_PRIORITY, (String) null);
  118 + }
  119 +
  120 + /**
  121 + * 子线程执行:普通优先级
  122 + *
  123 + * @param groupName 指定的线程池
  124 + * @param runnable 执行
  125 + * @return 取消
  126 + */
  127 + public static Cancelable submitWithGroup(String groupName, Runnable runnable) {
  128 + return submitInner(runnable, Thread.NORM_PRIORITY, groupName);
  129 + }
  130 +
  131 + /**
  132 + * 关闭线程组
  133 + *
  134 + * @param groupName 组名字
  135 + */
  136 + public static void shutdownGroup(String groupName) {
  137 + ThreadPoolExecutor groupPool;
  138 + synchronized (GROUP_LOCK) {
  139 + groupPool = (ThreadPoolExecutor) GROUP_THREAD_POOLS.remove(groupName);
  140 + }
  141 +
  142 + if (groupPool != null) {
  143 + groupPool.shutdown();
  144 + Logger.t(TAG).i("group thread pool shutdown:" + groupName);
  145 + }
  146 +
  147 + }
  148 +
  149 + /**
  150 + * 子线程池执行:高优先级
  151 + *
  152 + * @param runnable 运行接口
  153 + * @return 取消接口
  154 + */
  155 + public static Cancelable emergencySubmit(Runnable runnable) {
  156 + return submitInner(runnable, Thread.MAX_PRIORITY, (String) null);
  157 + }
  158 +
  159 + /**
  160 + * 子线程池执行:高优先级
  161 + *
  162 + * @param runnable 运行接口
  163 + * @return 取消接口
  164 + */
  165 + public static Cancelable backgroundSubmit(Runnable runnable) {
  166 + return submitInner(runnable, Thread.MIN_PRIORITY, (String) null);
  167 + }
  168 +
  169 + private static Cancelable submitInner(Runnable runnable, int priority, String groupName) {
  170 + if (null == runnable) {
  171 + Logger.t(TAG)
  172 + .e("submit: Task is null, priority:" + PriorityGroupedThreadFactory.getPriorityName(priority)
  173 + + ", group:" + groupName);
  174 + return SubmitCancelable.from((Future) null);
  175 + } else {
  176 + ThreadPoolExecutor actualPool = getThreadPoolInner(groupName, priority);
  177 + BlockingQueue<Runnable> queue = actualPool.getQueue();
  178 + int queueSizeBeforeSend = queue.size();
  179 + long currTime = System.currentTimeMillis();
  180 + PriorityRunnable actualRunnable = new PriorityRunnable(runnable, priority, queueSizeBeforeSend, currTime);
  181 +
  182 + try {
  183 + Future<?> future = actualPool.submit(actualRunnable);
  184 + return SubmitCancelable.from(future);
  185 + } catch (RejectedExecutionException var10) {
  186 + Logger.t(TAG)
  187 + .e("submit: Task is rejected, priority:" + PriorityGroupedThreadFactory.getPriorityName(priority)
  188 + + ", group:" + groupName);
  189 + return SubmitCancelable.from((Future) null);
  190 + }
  191 + }
  192 + }
  193 +
  194 + /**
  195 + * 延迟提交
  196 + *
  197 + * @param runnable 执行接口
  198 + * @param delayTime 延迟时间
  199 + * @param unit 时间单位
  200 + * @return 取消接口
  201 + */
  202 + public static Cancelable schedule(Runnable runnable, long delayTime, TimeUnit unit) {
  203 + Runnable intermediate = LifecycleRunnable.transfer(runnable);
  204 + Runnable actualRunnable = AutoReleaseRunnable.transfer(intermediate);
  205 + Future<?> future = SCHEDULED_THREAD_POOL.schedule(actualRunnable, delayTime, unit);
  206 + return SubmitCancelable.from(future);
  207 + }
  208 +
  209 + /**
  210 + * 周期性执行线程
  211 + *
  212 + * @param runnable 执行接口
  213 + * @param initialDelay 延迟时间
  214 + * @param period 周期时间
  215 + * @param unit 单位
  216 + * @return 取消接口
  217 + */
  218 + public static Cancelable scheduleAtFixedRate(Runnable runnable, long initialDelay, long period, TimeUnit unit) {
  219 + Runnable intermediate = LifecycleRunnable.transfer(runnable);
  220 + Runnable actualRunnable = AutoReleaseRunnable.transfer(intermediate);
  221 + Future<?> future = SCHEDULED_THREAD_POOL.scheduleAtFixedRate(actualRunnable, initialDelay, period, unit);
  222 + return SubmitCancelable.from(future);
  223 + }
  224 +
  225 + private static ThreadPoolExecutor getThreadPoolInner(String groupName, int priority) {
  226 + if (!StringUtils.isEmpty(groupName)) {
  227 + return getGroupedThreadPool(groupName, -1, -1);
  228 + } else if (priority == Thread.MAX_PRIORITY) {
  229 + return EMERGENCY_THREAD_POOL;
  230 + } else {
  231 + return priority == Thread.MIN_PRIORITY ? BACKGROUND_THREAD_POOL : NORMAL_THREAD_POOL;
  232 + }
  233 + }
  234 +
  235 + /**
  236 + * 获得组线程池
  237 + *
  238 + * @param groupName 组名字
  239 + * @param threadCount 线程数量
  240 + * @param priority 线程的优先级
  241 + * @return 线程池
  242 + */
  243 + public static ThreadPoolExecutor getGroupedThreadPool(@NonNull String groupName, int threadCount, int priority) {
  244 + int actualThreadCount = threadCount <= 0 ? NORMAL_GROUP_POOL_SIZE : threadCount;
  245 + int actualPriority = priority == -1 ? Thread.NORM_PRIORITY : priority;
  246 + synchronized (GROUP_LOCK) {
  247 + // 如果在缓存中拿不到线程池,则新建一个线程池,并且添加到缓存中
  248 + ThreadPoolExecutor groupPool = (ThreadPoolExecutor) GROUP_THREAD_POOLS.get(groupName);
  249 + if (groupPool == null) {
  250 + groupPool = new ThreadPoolExecutor(actualThreadCount, actualThreadCount, 30L, TimeUnit.SECONDS,
  251 + new LinkedBlockingQueue(), new PriorityGroupedThreadFactory(actualPriority, groupName));
  252 + groupPool.allowCoreThreadTimeOut(true);
  253 + GROUP_THREAD_POOLS.put(groupName, groupPool);
  254 + }
  255 +
  256 + return groupPool;
  257 + }
  258 + }
  259 +
  260 + /**
  261 + * 主线程执行
  262 + *
  263 + * @param runnable 执行接口
  264 + * @return 取消接口
  265 + */
  266 + public static Cancelable postToMain(Runnable runnable) {
  267 + Runnable intermediate = LifecycleRunnable.transfer(runnable);
  268 + Runnable actualRunnable = AutoReleaseRunnable.transfer(intermediate);
  269 + MAIN_HANDLER.post(actualRunnable);
  270 + return PostCancelable.from(MAIN_HANDLER, actualRunnable);
  271 + }
  272 +
  273 + /**
  274 + * 主线程延时执行
  275 + *
  276 + * @param runnable 执行接口
  277 + * @param delayMillis 延时时间:毫秒
  278 + * @return 取消接口
  279 + */
  280 + public static Cancelable postToMainDelay(Runnable runnable, long delayMillis) {
  281 + Runnable intermediate = LifecycleRunnable.transfer(runnable);
  282 + Runnable actualRunnable = AutoReleaseRunnable.transfer(intermediate);
  283 + MAIN_HANDLER.postDelayed(actualRunnable, delayMillis);
  284 + return PostCancelable.from(MAIN_HANDLER, actualRunnable);
  285 + }
  286 +
  287 + /**
  288 + * 线程工厂类
  289 + */
  290 + private static class PriorityGroupedThreadFactory implements ThreadFactory {
  291 + /**
  292 + * 线程数量
  293 + */
  294 + private final AtomicInteger threadNumber = new AtomicInteger(1);
  295 +
  296 + /**
  297 + * 命名前缀
  298 + */
  299 + private final String namePrefix;
  300 +
  301 + /**
  302 + * 线程优先级
  303 + */
  304 + private final int threadPriority;
  305 +
  306 + PriorityGroupedThreadFactory(int priority, String groupName) {
  307 + this.threadPriority = priority;
  308 + String group = groupName == null ? "def" : StringUtils.str2LowerCase(groupName);
  309 + this.namePrefix = "x-" + getPriorityName(priority) + "-" + group + "-";
  310 + }
  311 +
  312 + static String getPriorityName(int priority) {
  313 + if (priority == 10) {
  314 + return "emrg";
  315 + } else {
  316 + return priority == 1 ? "back" : "norm";
  317 + }
  318 + }
  319 +
  320 + public Thread newThread(@NonNull Runnable r) {
  321 + Thread t = new Thread(r, this.namePrefix + this.threadNumber.getAndIncrement());
  322 + if (t.isDaemon()) {
  323 + t.setDaemon(false);
  324 + }
  325 +
  326 + if (this.threadPriority == 1) {
  327 + t.setPriority(1);
  328 + } else {
  329 + t.setPriority(5);
  330 + }
  331 +
  332 + return t;
  333 + }
  334 + }
  335 +
  336 + /**
  337 + * 线程取消接口
  338 + */
  339 + private static final class SubmitCancelable implements Cancelable {
  340 + private Future<?> futureTask;
  341 +
  342 + private SubmitCancelable(@Nullable Future<?> future) {
  343 + this.futureTask = future;
  344 + }
  345 +
  346 + static SubmitCancelable from(@Nullable Future<?> future) {
  347 + return new SubmitCancelable(future);
  348 + }
  349 +
  350 + public void cancel() {
  351 + if (this.futureTask == null) {
  352 + Logger.t(TAG).e("future not set, cannot cancel");
  353 + } else {
  354 + this.futureTask.cancel(true);
  355 + }
  356 + }
  357 +
  358 + public boolean isCanceled() {
  359 + if (this.futureTask == null) {
  360 + Logger.t(TAG).e("future not set, same as canceled");
  361 + return false;
  362 + } else {
  363 + return this.futureTask.isCancelled();
  364 + }
  365 + }
  366 + }
  367 +
  368 + /**
  369 + * 带有优先级响应接口
  370 + */
  371 + private static class PriorityRunnable implements Runnable {
  372 + private final int threadPriorityInner;
  373 +
  374 + private final Runnable runnableInner;
  375 +
  376 + private int queueSizeBeforeSend;
  377 +
  378 + private long queueTime;
  379 +
  380 + private static long WARNING_WAIT_THRESHOLD = 1000L;
  381 +
  382 + PriorityRunnable(Runnable runnable, int priority, int queueSizeBeforeSend, long queueTime) {
  383 + Runnable intermediate = LifecycleRunnable.transfer(runnable);
  384 + this.runnableInner = AutoReleaseRunnable.transfer(intermediate);
  385 + this.threadPriorityInner = priority == 1 ? 10 : 0;
  386 + this.queueSizeBeforeSend = queueSizeBeforeSend;
  387 + this.queueTime = queueTime;
  388 + }
  389 +
  390 + public void run() {
  391 + if (this.runnableInner == null) {
  392 + Logger.t(TAG).w("inner runnable is null");
  393 + } else {
  394 + long currTime = System.currentTimeMillis();
  395 + long waitTime = currTime - this.queueTime;
  396 + if (waitTime > WARNING_WAIT_THRESHOLD) {
  397 + Thread currThread = Thread.currentThread();
  398 + Logger.t(TAG)
  399 + .w("wait too long in queue, wait time:" + waitTime + ", waitNum:" + this.queueSizeBeforeSend
  400 + + ", tName:" + currThread.getName() + ", tPry:" + currThread.getPriority());
  401 + }
  402 +
  403 + Process.setThreadPriority(this.threadPriorityInner);
  404 + this.runnableInner.run();
  405 + }
  406 + }
  407 + }
  408 +}
  1 +package com.wd.foundation.wdkitcore.thread;
  2 +
  3 +/**
  4 + * 文件描述
  5 + *
  6 + * @author huweixiong
  7 + * @version [V1.0.0.1, 2020/11/12]
  8 + * @since V1.0.0.1
  9 + */
  10 +public final class WorkerThread {
  11 + private static final String TAG = "WorkerThread";
  12 +
  13 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.tools;
  6 +
  7 +import java.util.HashMap;
  8 +
  9 +import android.content.Context;
  10 +
  11 +import androidx.collection.SparseArrayCompat;
  12 +
  13 +/**
  14 + * <BR>
  15 + *
  16 + * @author wangnaiwen
  17 + * @version [V1.0.0.0, 2020/4/7]
  18 + * @since V1.0.0.0
  19 + */
  20 +public final class AppContext {
  21 +
  22 + private static final String TAG = "AppContext";
  23 +
  24 + private static Context mContext;
  25 +
  26 + public static boolean mPause = false;
  27 +
  28 + public AppContext() {
  29 + }
  30 +
  31 + public static SparseArrayCompat<HashMap<String, Boolean>> sparseArrayCompat = new SparseArrayCompat<>();
  32 +
  33 + public static HashMap<String, Boolean> mSet = new HashMap<>();
  34 +
  35 + public static void init(Context context) {
  36 + mContext = context;
  37 + }
  38 +
  39 + public static void setCurrentMap(int index) {
  40 + mSet = sparseArrayCompat.get(index);
  41 + }
  42 +
  43 + public static void clearMaps() {
  44 + sparseArrayCompat.clear();
  45 + }
  46 +
  47 + public static void intMaps(int index) {
  48 + HashMap<String, Boolean> map = new HashMap<>();
  49 + sparseArrayCompat.put(index, map);
  50 + }
  51 +
  52 + public static Context getContext() {
  53 + return mContext;
  54 + }
  55 +
  56 + public static String getFileDirPath() {
  57 + return mContext != null && mContext.getFilesDir() != null ? mContext.getFilesDir().getPath() : "";
  58 + }
  59 +
  60 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.tools;
  6 +
  7 +import java.util.ArrayList;
  8 +import java.util.Collection;
  9 +import java.util.Collections;
  10 +import java.util.Iterator;
  11 +import java.util.List;
  12 +import java.util.Map;
  13 +
  14 +import android.text.TextUtils;
  15 +import android.util.SparseBooleanArray;
  16 +
  17 +import androidx.annotation.NonNull;
  18 +import androidx.annotation.Nullable;
  19 +
  20 +import com.wd.base.log.Logger;
  21 +
  22 +/**
  23 + * <数组工具类>
  24 + *
  25 + * @author wangnaiwen
  26 + * @version [V1.0.0.0, 2020/4/7]
  27 + * @since V1.0.0.0
  28 + */
  29 +public class ArrayUtils {
  30 + private static final String TAG = "ArrayUtils";
  31 +
  32 + private ArrayUtils() {
  33 + }
  34 +
  35 + public static boolean isEmpty(String[] str) {
  36 + return null == str || 0 == str.length;
  37 + }
  38 +
  39 + public static boolean isEmpty(Object[] array) {
  40 + return null == array || 0 == array.length;
  41 + }
  42 +
  43 + public static boolean isEmpty(Collection<?> collection) {
  44 + return null == collection || collection.isEmpty();
  45 + }
  46 +
  47 + public static boolean isNotEmpty(Collection<?> collection) {
  48 + return null != collection && !collection.isEmpty();
  49 + }
  50 +
  51 + public static boolean isEmpty(Map<?, ?> map) {
  52 + return null == map || map.isEmpty();
  53 + }
  54 +
  55 + public static boolean isNotEmpty(Map<?, ?> map) {
  56 + return null != map && !map.isEmpty();
  57 + }
  58 +
  59 + public static boolean isEmpty(long[] array) {
  60 + return null == array || 0 == array.length;
  61 + }
  62 +
  63 + public static boolean isEmpty(int[] array) {
  64 + return null == array || 0 == array.length;
  65 + }
  66 +
  67 + public static boolean isEmpty(byte[] array) {
  68 + return null == array || 0 == array.length;
  69 + }
  70 +
  71 + public static <T> List<T> getSubList(List<T> source, int start, int end) {
  72 + return null != source && start >= 0 && end >= start && end <= source.size() ? source.subList(start, end) : null;
  73 + }
  74 +
  75 + public static <T> T getListElement(List<T> source, int index) {
  76 + return !isEmpty((Collection) source) && index >= 0 && index < source.size() ? source.get(index) : null;
  77 + }
  78 +
  79 + public static String arrayToString(String[] sources, String separator) {
  80 + if (sources == null) {
  81 + return "";
  82 + } else {
  83 + StringBuilder builder = new StringBuilder();
  84 + String[] var3 = sources;
  85 + int var4 = sources.length;
  86 +
  87 + for (int var5 = 0; var5 < var4; ++var5) {
  88 + String source = var3[var5];
  89 + builder.append(source).append(separator);
  90 + }
  91 +
  92 + String res = builder.toString();
  93 + return StringUtils.isEmpty(res) ? "" : StringUtils.cutString(res, 0, res.length() - 1);
  94 + }
  95 + }
  96 +
  97 + public static String listToString(List<String> sources, String separator) {
  98 + if (isEmpty((Collection) sources)) {
  99 + return null;
  100 + } else {
  101 + StringBuilder builder = new StringBuilder();
  102 + Iterator var3 = sources.iterator();
  103 +
  104 + while (var3.hasNext()) {
  105 + String source = (String) var3.next();
  106 + builder.append(source).append(separator);
  107 + }
  108 +
  109 + String res = builder.toString();
  110 + return TextUtils.isEmpty(res) ? "" : StringUtils.cutString(res, 0, res.length() - 1);
  111 + }
  112 + }
  113 +
  114 + public static <T> List<T> objToList(Object object, Class<T> clazz) {
  115 + if (clazz != null && object instanceof List) {
  116 + List objects = (List) object;
  117 + if (!isEmpty((Collection) objects)) {
  118 + Object obj = objects.get(0);
  119 + if (clazz.isInstance(obj)) {
  120 + try {
  121 + return (List) object;
  122 + } catch (ClassCastException var5) {
  123 + return null;
  124 + }
  125 + }
  126 + }
  127 + }
  128 +
  129 + return null;
  130 + }
  131 +
  132 + public static <T> ArrayList<T> objToArrayList(Object object, Class<T> clazz) {
  133 + if (clazz != null && object instanceof ArrayList) {
  134 + List objects = (ArrayList) object;
  135 + if (!isEmpty((Collection) objects)) {
  136 + Object obj = objects.get(0);
  137 + if (clazz.isInstance(obj)) {
  138 + try {
  139 + return (ArrayList) object;
  140 + } catch (ClassCastException var5) {
  141 + return null;
  142 + }
  143 + }
  144 + }
  145 + }
  146 +
  147 + return null;
  148 + }
  149 +
  150 + public static boolean getValueFromSparseBooleanArray(SparseBooleanArray sparseBooleanArray, int index,
  151 + boolean defaultValue) {
  152 + return sparseBooleanArray != null && sparseBooleanArray.size() > index ? sparseBooleanArray.get(index)
  153 + : defaultValue;
  154 + }
  155 +
  156 + public static <T> T getArrayElement(T[] source, int index) {
  157 + return !isEmpty(source) && index >= 0 && index < source.length ? source[index] : null;
  158 + }
  159 +
  160 + public static float getFloatArrayElement(float[] source, int index) {
  161 + return source != null && index >= 0 && index < source.length ? source[index] : 0.0F;
  162 + }
  163 +
  164 + public static int getIntArrayElement(int[] source, int index) {
  165 + return source != null && index >= 0 && index < source.length ? source[index] : 0;
  166 + }
  167 +
  168 + public static void modifyFloatArrayValue(float[] source, int index, float value) {
  169 + if (source != null && index >= 0 && index < source.length) {
  170 + source[index] = value;
  171 + }
  172 +
  173 + }
  174 +
  175 + public static void modifyIntArrayValue(int[] source, int index, int value) {
  176 + if (source != null && index >= 0 && index < source.length) {
  177 + source[index] = value;
  178 + }
  179 +
  180 + }
  181 +
  182 + public static int getListSize(List list) {
  183 + return isEmpty((Collection) list) ? 0 : list.size();
  184 + }
  185 +
  186 + public static void arrayCopy(byte[] src, int srcPos, byte[] dest, int destPos, int length) {
  187 + if (null != src && null != dest) {
  188 + if (srcPos >= 0 && srcPos + length <= src.length) {
  189 + if (destPos >= 0 && destPos + length <= dest.length) {
  190 + System.arraycopy(src, srcPos, dest, destPos, length);
  191 + }
  192 + }
  193 + }
  194 + }
  195 +
  196 + public static <T> void replaceAll(List<T> srcList, List<T> toAddedList) {
  197 + if (null == srcList) {
  198 + Logger.t(TAG).w("replaceAll but srcList is null");
  199 + } else {
  200 + srcList.clear();
  201 + if (!isEmpty((Collection) toAddedList)) {
  202 + srcList.addAll(toAddedList);
  203 + }
  204 +
  205 + }
  206 + }
  207 +
  208 + @Nullable
  209 + public static <T> List<T> getSubList(List<T> srcList, List<T> toRemovedList) {
  210 + if (null == srcList) {
  211 + Logger.t(TAG).w("removeAll but srcList is null");
  212 + return null;
  213 + } else {
  214 + List<T> res = new ArrayList(srcList.size());
  215 + res.addAll(srcList);
  216 + if (!isEmpty((Collection) toRemovedList)) {
  217 + res.removeAll(toRemovedList);
  218 + }
  219 +
  220 + return res;
  221 + }
  222 + }
  223 +
  224 + public static List<Integer> asList(int[] src) {
  225 + if (src != null && src.length > 0) {
  226 + List<Integer> list = new ArrayList();
  227 + int[] var2 = src;
  228 + int var3 = src.length;
  229 +
  230 + for (int var4 = 0; var4 < var3; ++var4) {
  231 + int i = var2[var4];
  232 + list.add(i);
  233 + }
  234 +
  235 + return list;
  236 + } else {
  237 + return null;
  238 + }
  239 + }
  240 +
  241 + public static void clearList(List list) {
  242 + if (!isEmpty((Collection) list)) {
  243 + list.clear();
  244 + }
  245 +
  246 + }
  247 +
  248 + public static <T> boolean arrayEquals(List<T> list1, List<T> list2) {
  249 + if (list1 == list2) {
  250 + return true;
  251 + } else if (list1 != null && list2 != null && list1.size() == list2.size()) {
  252 + for (int i = 0; i < list1.size(); ++i) {
  253 + if (!isObjectEqual(list1.get(i), list2.get(i))) {
  254 + return false;
  255 + }
  256 + }
  257 +
  258 + return true;
  259 + } else {
  260 + return false;
  261 + }
  262 + }
  263 +
  264 + private static boolean isObjectEqual(Object o1, Object o2) {
  265 + if (o1 == o2) {
  266 + return true;
  267 + } else {
  268 + return null != o1 && null != o2 ? o1.equals(o2) : false;
  269 + }
  270 + }
  271 +
  272 + public static <T> void add(List<T> list, T ele) {
  273 + if (list != null && ele != null && !list.contains(ele)) {
  274 + list.add(ele);
  275 + }
  276 +
  277 + }
  278 +
  279 + @NonNull
  280 + public static <T> List<T> getNonNullList(List<T> list) {
  281 + if (isEmpty((Collection) list)) {
  282 + return Collections.emptyList();
  283 + } else {
  284 + List<T> res = new ArrayList(list);
  285 + List<T> toRemoved = new ArrayList(list.size());
  286 + Iterator var3 = list.iterator();
  287 +
  288 + while (var3.hasNext()) {
  289 + T t = (T) var3.next();
  290 + if (null == t) {
  291 + toRemoved.add((T) (Object) null);
  292 + }
  293 + }
  294 +
  295 + res.removeAll(toRemoved);
  296 + return res;
  297 + }
  298 + }
  299 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.tools;
  6 +
  7 +import com.wd.base.log.Logger;
  8 +
  9 +/**
  10 + * <类型转换工具类>
  11 + *
  12 + * @author wangnaiwen
  13 + * @version [V1.0.0.0, 2020/5/16]
  14 + * @since V1.0.0.0
  15 + */
  16 +public class CastUtils {
  17 + private static final String TAG = "CastUtils";
  18 +
  19 + private CastUtils() {
  20 + }
  21 +
  22 + public static int castToInt(Object obj) {
  23 + return castToInt(obj, 0);
  24 + }
  25 +
  26 + public static int castToInt(Object obj, int defaultValue) {
  27 + Integer ret = (Integer) cast(obj, Integer.class);
  28 + return ret == null ? defaultValue : ret;
  29 + }
  30 +
  31 + public static boolean castToBoolean(Object obj) {
  32 + return castToBoolean(obj, false);
  33 + }
  34 +
  35 + public static boolean castToBoolean(Object obj, boolean defaultValue) {
  36 + Boolean ret = (Boolean) cast(obj, Boolean.class);
  37 + return ret == null ? defaultValue : ret;
  38 + }
  39 +
  40 + public static String castToString(Object obj) {
  41 + return castToString(obj, "");
  42 + }
  43 +
  44 + public static String castToString(Object obj, String defaultValue) {
  45 + String ret = (String) cast(obj, String.class);
  46 + return ret == null ? defaultValue : ret;
  47 + }
  48 +
  49 + public static <T> T cast(Object obj, Class<T> clz) {
  50 + if (clz == null) {
  51 + Logger.t(TAG).i("class is null");
  52 + return null;
  53 + } else {
  54 + return clz.isInstance(obj) ? (T) obj : null;
  55 + }
  56 + }
  57 +
  58 + public static <T> T cast(Object obj, T defaultValue) {
  59 + if (defaultValue == null) {
  60 + Logger.t(TAG).i("defaultValue is null.");
  61 + return null;
  62 + } else if (obj == null) {
  63 + Logger.t(TAG).i("object is null.");
  64 + return null;
  65 + } else {
  66 + return defaultValue.getClass() == obj.getClass() ? (T) obj : defaultValue;
  67 + }
  68 + }
  69 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.tools;
  6 +
  7 +import java.util.ArrayList;
  8 +import java.util.Iterator;
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * <转换帮助类>
  13 + *
  14 + * @author wangnaiwen
  15 + * @version [V1.0.0.0, 2020/5/16]
  16 + * @since V1.0.0.0
  17 + */
  18 +public class ConvertHelper {
  19 + public ConvertHelper() {
  20 + }
  21 +
  22 + public static <D, S> List<D> convert(List<S> sources, IConverter<S, D> converter) {
  23 + if (!ArrayUtils.isEmpty(sources) && null != converter) {
  24 + List<D> dests = new ArrayList(sources.size());
  25 + Iterator var3 = sources.iterator();
  26 +
  27 + while (var3.hasNext()) {
  28 + S source = (S) var3.next();
  29 + D dest = converter.convert(source);
  30 + if (null != dest) {
  31 + dests.add(dest);
  32 + }
  33 + }
  34 +
  35 + return dests;
  36 + } else {
  37 + return null;
  38 + }
  39 + }
  40 +
  41 + public static <D, S> List<D> convert(List<S> sources, IPositionConverter<S, D> converter) {
  42 + if (!ArrayUtils.isEmpty(sources) && null != converter) {
  43 + List<D> dests = new ArrayList(sources.size());
  44 + Iterator var3 = sources.iterator();
  45 +
  46 + while (var3.hasNext()) {
  47 + S source = (S) var3.next();
  48 + D dest = converter.convert(source, dests.size());
  49 + if (null != dest) {
  50 + dests.add(dest);
  51 + }
  52 + }
  53 +
  54 + return dests;
  55 + } else {
  56 + return null;
  57 + }
  58 + }
  59 +
  60 + public interface IPositionConverter<S, D> {
  61 + D convert(S var1, int var2);
  62 + }
  63 +
  64 + public interface IConverter<S, D> {
  65 + D convert(S var1);
  66 + }
  67 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.tools;
  6 +
  7 +import android.content.Context;
  8 +import android.os.Build;
  9 +
  10 +/**
  11 + * 设备相关工具类<BR>
  12 + *
  13 + * @author wangnaiwen
  14 + * @version [V1.0.0.0, 2020/4/7]
  15 + * @since V1.0.0.0
  16 + */
  17 +public class DeviceUtils {
  18 +
  19 + /**
  20 + * 设备屏幕宽度
  21 + *
  22 + * @return 屏幕宽度
  23 + */
  24 + public static int getDeviceWidth() {
  25 + Context context = AppContext.getContext();
  26 + if (context == null) {
  27 + return 0;
  28 + }
  29 + return Math.min(context.getResources().getDisplayMetrics().widthPixels,
  30 + context.getResources().getDisplayMetrics().heightPixels);
  31 + }
  32 +
  33 + /**
  34 + * 设备屏幕高度
  35 + *
  36 + * @return 屏幕高度
  37 + */
  38 + public static int getDeviceHeight() {
  39 + Context context = AppContext.getContext();
  40 + if (context == null) {
  41 + return 0;
  42 + }
  43 + return Math.max(context.getResources().getDisplayMetrics().widthPixels,
  44 + context.getResources().getDisplayMetrics().heightPixels);
  45 + }
  46 +
  47 + /**
  48 + * 获得版本 Model
  49 + *
  50 + * @return 版本 Model
  51 + */
  52 + public static String getModel() {
  53 + return Build.MODEL;
  54 + }
  55 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.tools;
  6 +
  7 +import java.util.regex.Matcher;
  8 +import java.util.regex.Pattern;
  9 +
  10 +/**
  11 + * <数据计算工具类>
  12 + *
  13 + * @author wangnaiwen
  14 + * @version [V1.0.0.0, 2020/5/16]
  15 + * @since V1.0.0.0
  16 + */
  17 +public class MathUtils {
  18 + private static final float FLOAT_SMALL_ENOUGH_NUM = 1.0E-7F;
  19 +
  20 + private static final double DOUBLE_SMALL_ENOUGH_NUM = 1.0E-7D;
  21 +
  22 + private MathUtils() {
  23 + }
  24 +
  25 + public static int parseInt(String str, int defInt) {
  26 + try {
  27 + return Integer.parseInt(str);
  28 + } catch (Exception var3) {
  29 + return defInt;
  30 + }
  31 + }
  32 +
  33 + public static int parseInt(Integer integer, int defInt) {
  34 + return null == integer ? defInt : integer;
  35 + }
  36 +
  37 + public static int parseInt(String str, int radix, int defInt) {
  38 + try {
  39 + return Integer.parseInt(str, radix);
  40 + } catch (Exception var4) {
  41 + return defInt;
  42 + }
  43 + }
  44 +
  45 + public static long parseLong(String str, long defLong) {
  46 + try {
  47 + return Long.parseLong(str);
  48 + } catch (Exception var4) {
  49 + return defLong;
  50 + }
  51 + }
  52 +
  53 + public static long parseLong(String str, int radix, long defLong) {
  54 + try {
  55 + return Long.parseLong(str, radix);
  56 + } catch (Exception var5) {
  57 + return defLong;
  58 + }
  59 + }
  60 +
  61 + public static Boolean parseBoolean(String str, Boolean defBool) {
  62 + try {
  63 + return Boolean.valueOf(str);
  64 + } catch (Exception var3) {
  65 + return defBool;
  66 + }
  67 + }
  68 +
  69 + public static float parseFloat(String str, Float defFloat) {
  70 + try {
  71 + return Float.parseFloat(str);
  72 + } catch (Exception var3) {
  73 + return defFloat;
  74 + }
  75 + }
  76 +
  77 + public static double parseDouble(String str, double defDouble) {
  78 + try {
  79 + return Double.parseDouble(str);
  80 + } catch (Exception var4) {
  81 + return defDouble;
  82 + }
  83 + }
  84 +
  85 + public static byte parseByte(String str, byte defByte) {
  86 + try {
  87 + return Byte.parseByte(str);
  88 + } catch (Exception var3) {
  89 + return defByte;
  90 + }
  91 + }
  92 +
  93 + public static short parseShort(String str, short defShort) {
  94 + try {
  95 + return Short.parseShort(str);
  96 + } catch (Exception var3) {
  97 + return defShort;
  98 + }
  99 + }
  100 +
  101 + public static byte[] xor(String prevStr, String lateStr) {
  102 + if (!StringUtils.isBlank(prevStr) && !StringUtils.isBlank(lateStr) && prevStr.length() == lateStr.length()) {
  103 + char[] prevArray = prevStr.toCharArray();
  104 + char[] lateArray = lateStr.toCharArray();
  105 + byte[] xoredArray = new byte[prevArray.length];
  106 + int length = prevStr.length();
  107 +
  108 + for (int i = 0; i < length; ++i) {
  109 + xoredArray[i] = (byte) (prevArray[i] ^ lateArray[i]);
  110 + }
  111 +
  112 + return xoredArray;
  113 + } else {
  114 + return new byte[0];
  115 + }
  116 + }
  117 +
  118 + public static boolean isEqual(float f1, float f2) {
  119 + return Math.abs(f1 - f2) < FLOAT_SMALL_ENOUGH_NUM;
  120 + }
  121 +
  122 + public static boolean isEqual(double f1, double f2) {
  123 + return Math.abs(f1 - f2) < DOUBLE_SMALL_ENOUGH_NUM;
  124 + }
  125 +
  126 + public static boolean biggerOrEqual(float f1, float f2) {
  127 + return isEqual(f1, f2) || f1 > f2;
  128 + }
  129 +
  130 + public static boolean biggerOrEqual(double f1, double f2) {
  131 + return isEqual(f1, f2) || f1 > f2;
  132 + }
  133 +
  134 + public static int getMaxCommonDivisor(int x, int y) {
  135 + int xLocal = x;
  136 +
  137 + int yLocal;
  138 + int temp;
  139 + for (yLocal = y; xLocal % yLocal != 0; yLocal = temp) {
  140 + temp = xLocal % yLocal;
  141 + xLocal = yLocal;
  142 + }
  143 +
  144 + return yLocal;
  145 + }
  146 +
  147 + public static int getMinCommonMultiple(int[] nums) {
  148 + int multiple = 1;
  149 + if (nums != null && nums.length >= 2) {
  150 + int x = nums[0];
  151 + int y = nums[1];
  152 + multiple = getMinCommonMultiple(x, y);
  153 +
  154 + for (int i = 2; i < nums.length; ++i) {
  155 + multiple = getMinCommonMultiple(multiple, nums[i]);
  156 + }
  157 + }
  158 +
  159 + return multiple;
  160 + }
  161 +
  162 + public static int getMinCommonMultiple(int x, int y) {
  163 + return x * y / getMaxCommonDivisor(x, y);
  164 + }
  165 +
  166 + public static boolean isNumber(String str) {
  167 + if (!StringUtils.isEmpty(str)) {
  168 + Pattern pattern = Pattern.compile("[0-9]*");
  169 + Matcher isNum = pattern.matcher(str);
  170 + return isNum.matches();
  171 + } else {
  172 + return false;
  173 + }
  174 + }
  175 +
  176 + public static float constrain(float minValue, float maxValue, float value) {
  177 + return Math.max(minValue, Math.min(maxValue, value));
  178 + }
  179 +
  180 + public static int compare(long x, long y) {
  181 + return x < y ? -1 : (x == y ? 0 : 1);
  182 + }
  183 +
  184 + public static int getMaxNumber(int minValue, int maxValue) {
  185 + return Math.max(minValue, maxValue);
  186 + }
  187 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.tools;
  6 +
  7 +import java.lang.reflect.AccessibleObject;
  8 +import java.lang.reflect.Field;
  9 +import java.lang.reflect.InvocationTargetException;
  10 +import java.lang.reflect.Method;
  11 +import java.lang.reflect.Modifier;
  12 +import java.lang.reflect.ParameterizedType;
  13 +import java.lang.reflect.Type;
  14 +
  15 +import android.text.TextUtils;
  16 +
  17 +import com.wd.base.log.Logger;
  18 +
  19 +/**
  20 + * <反射工具类>
  21 + *
  22 + * @author wangnaiwen
  23 + * @version [V1.0.0.0, 2020/5/16]
  24 + * @since V1.0.0.0
  25 + */
  26 +public final class ReflectionUtils {
  27 + private static final String TAG = "ReflectionUtils";
  28 +
  29 + private ReflectionUtils() {
  30 + }
  31 +
  32 + /**
  33 + * 启用或禁用安全检查
  34 + *
  35 + * @param object 对象名称
  36 + * @param flag 设置值为true表示反射对象应该在使用时抑制Java语言访问检查,设置值为false表示反射对象应强制执行Java语言访问检查。
  37 + */
  38 + public static void setAccessible(AccessibleObject object, boolean flag) {
  39 + if (null != object) {
  40 + object.setAccessible(flag);
  41 + }
  42 + }
  43 +
  44 + /**
  45 + * 获取方法
  46 + *
  47 + * @param className 类名称
  48 + * @param methodName 方法名称
  49 + * @param parameterTypes 按照声明顺序标识该方法的形参类型
  50 + * @return 方法
  51 + */
  52 + public static Method getMethod(String className, String methodName, Class<?>... parameterTypes) {
  53 + if (TextUtils.isEmpty(className)) {
  54 + Logger.t(TAG).w("getMethod param className is null");
  55 + return null;
  56 + }
  57 + if (TextUtils.isEmpty(methodName)) {
  58 + Logger.t(TAG).w("getMethod param methodName is null");
  59 + return null;
  60 + }
  61 +
  62 + Method method = null;
  63 + try {
  64 + Class<?> c = Class.forName(className);
  65 + method = c.getMethod(methodName, parameterTypes);
  66 + } catch (ClassNotFoundException e1) {
  67 + Logger.t(TAG).e("getMethod:", e1);
  68 + } catch (NoSuchMethodException e2) {
  69 + Logger.t(TAG).e("getMethod:", e2);
  70 + } catch (Exception e3) {
  71 + Logger.t(TAG).e("getMethod:", e3);
  72 + }
  73 + return method;
  74 + }
  75 +
  76 + /**
  77 + * 获取方法
  78 + *
  79 + * @param clz 类
  80 + * @param methodName 函数名称
  81 + * @param parameterTypes 按照声明顺序标识该方法的形参类型
  82 + * @return 方法
  83 + */
  84 + public static Method getMethod(Class<?> clz, String methodName, Class<?>... parameterTypes) {
  85 + if (clz == null) {
  86 + Logger.t(TAG).w("getMethod param clz is null");
  87 + return null;
  88 + }
  89 + if (TextUtils.isEmpty(methodName)) {
  90 + Logger.t(TAG).w("getMethod param methodName is null");
  91 + return null;
  92 + }
  93 +
  94 + Method method = null;
  95 + try {
  96 + method = clz.getMethod(methodName, parameterTypes);
  97 + } catch (NoSuchMethodException e1) {
  98 + Logger.t(TAG).e("getMethod:", e1);
  99 + } catch (Exception e2) {
  100 + Logger.t(TAG).e("getMethod:", e2);
  101 + }
  102 + return method;
  103 + }
  104 +
  105 + /**
  106 + * 获取此Class对象所表示的类或接口的指定已声明方法
  107 + *
  108 + * @param clazz 类
  109 + * @param methodName 函数名称
  110 + * @param parameterTypes 形参类型
  111 + * @return 返回一个Method对象,它反映此Class对象所表示的类或接口的指定已声明方法
  112 + */
  113 + public static Method getDeclaredMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
  114 + if (clazz != null && !TextUtils.isEmpty(methodName)) {
  115 + return getDeclaredMethodImp(clazz, methodName, parameterTypes);
  116 + } else {
  117 + Logger.t(TAG).w("getDeclaredMethod param clazz or methodname can not be null!");
  118 + return null;
  119 + }
  120 + }
  121 +
  122 + private static Method getDeclaredMethodImp(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
  123 + Method method = null;
  124 + try {
  125 + method = clazz.getDeclaredMethod(methodName, parameterTypes);
  126 + } catch (NoSuchMethodException e1) {
  127 + Logger.t(TAG).e(methodName, e1);
  128 + } catch (Exception e2) {
  129 + Logger.t(TAG).e("getDeclaredMethod", e2);
  130 + }
  131 + return method;
  132 + }
  133 +
  134 + /**
  135 + * 获取此Class对象所表示的类或接口的指定已声明方法
  136 + *
  137 + * @param className 类名称
  138 + * @param methodName 函数名称
  139 + * @param parameterTypes 形参类型
  140 + * @return 返回一个Method对象,它反映此Class对象所表示的类或接口的指定已声明方法
  141 + */
  142 + public static Method getDeclaredMethod(String className, String methodName, Class<?>... parameterTypes) {
  143 + if (!TextUtils.isEmpty(className) && !TextUtils.isEmpty(methodName)) {
  144 + Method method = null;
  145 + try {
  146 + Class<?> c = Class.forName(className);
  147 + method = getDeclaredMethodImp(c, methodName, parameterTypes);
  148 + } catch (ClassNotFoundException e1) {
  149 + Logger.t(TAG).e(className, e1);
  150 + }
  151 + return method;
  152 + } else {
  153 + Logger.t(TAG).w("getDeclaredMethod param className or methodname can not be null!");
  154 + return null;
  155 + }
  156 + }
  157 +
  158 + private static Field getDeclaredFieldImp(Class<?> clazz, String fieldName) {
  159 + Field field = null;
  160 +
  161 + try {
  162 + field = clazz.getDeclaredField(fieldName);
  163 + } catch (NoSuchFieldException e1) {
  164 + Logger.t(TAG).e(fieldName, e1);
  165 + } catch (Exception e2) {
  166 + Logger.t(TAG).e("getDeclaredField", e2);
  167 + }
  168 +
  169 + return field;
  170 + }
  171 +
  172 + /**
  173 + * 此Class对象所表示的类或接口的指定已声明字段
  174 + *
  175 + * @param clazz 类
  176 + * @param fieldName 字段名称
  177 + * @return 字段
  178 + */
  179 + public static Field getDeclaredField(Class<?> clazz, String fieldName) {
  180 + if (clazz != null && !TextUtils.isEmpty(fieldName)) {
  181 + return getDeclaredFieldImp(clazz, fieldName);
  182 + } else {
  183 + Logger.t(TAG).w("getDeclaredField param klass or fieldName can not be null!");
  184 + return null;
  185 + }
  186 + }
  187 +
  188 + /**
  189 + * 此Class对象所表示的类或接口的指定已声明字段
  190 + *
  191 + * @param className 类名称
  192 + * @param fieldName 字段名称
  193 + * @return 字段
  194 + */
  195 + public static Field getDeclaredField(String className, String fieldName) {
  196 + if (!TextUtils.isEmpty(className) && !TextUtils.isEmpty(fieldName)) {
  197 + try {
  198 + Class<?> c = Class.forName(className);
  199 + return getDeclaredFieldImp(c, fieldName);
  200 + } catch (ClassNotFoundException e1) {
  201 + Logger.t(TAG).e(className, e1);
  202 + return null;
  203 + }
  204 + } else {
  205 + Logger.t(TAG).w("getDeclaredField param className or fieldName can not be null!");
  206 + return null;
  207 + }
  208 + }
  209 +
  210 + /**
  211 + * 此Class对象所表示的类或接口的指定已声明字段
  212 + *
  213 + * @param clz 类子
  214 + * @param fieldName 字段名称
  215 + * @param instance 实例
  216 + * @param clazz 泛型类
  217 + * @return 字段
  218 + */
  219 + public static <T> T getFieldValueIgnoreError(Class<?> clz, String fieldName, Object instance, Class<T> clazz) {
  220 + if (clz != null && !TextUtils.isEmpty(fieldName) && clazz != null) {
  221 + Object result = null;
  222 +
  223 + try {
  224 + Field field = clz.getField(fieldName);
  225 + Object obj = field.get(instance);
  226 + if (clazz.isInstance(obj)) {
  227 + result = obj;
  228 + }
  229 + } catch (NoSuchFieldException e1) {
  230 + Logger.t(TAG).d(fieldName);
  231 + } catch (IllegalArgumentException e2) {
  232 + Logger.t(TAG).d("IllegalArgumentException");
  233 + } catch (IllegalAccessException e3) {
  234 + Logger.t(TAG).d("IllegalAccessException");
  235 + } catch (Exception var10) {
  236 + Logger.t(TAG).d("getFieldValue");
  237 + }
  238 +
  239 + return (T) result;
  240 + } else {
  241 + Logger.t(TAG).w("getFieldValueIgnoreError getFieldValue param className or fieldName can not be null!");
  242 + return null;
  243 + }
  244 + }
  245 +
  246 + /**
  247 + * 此Class对象所表示的类或接口的指定已声明字段
  248 + *
  249 + * @param clz 类子
  250 + * @param fieldName 字段名称
  251 + * @param instance 实例
  252 + * @param clazz 泛型类
  253 + * @return 字段
  254 + */
  255 + public static <T> T getFieldValue(Class<?> clz, String fieldName, Object instance, Class<T> clazz) {
  256 + if (clz != null && !TextUtils.isEmpty(fieldName) && clazz != null) {
  257 + Object result = null;
  258 +
  259 + try {
  260 + Field field = clz.getField(fieldName);
  261 + Object obj = field.get(instance);
  262 + if (clazz.isInstance(obj)) {
  263 + result = obj;
  264 + }
  265 + } catch (NoSuchFieldException e1) {
  266 + Logger.t(TAG).e(fieldName, e1);
  267 + } catch (IllegalArgumentException e2) {
  268 + Logger.t(TAG).e("IllegalArgumentException", e2);
  269 + } catch (IllegalAccessException e3) {
  270 + Logger.t(TAG).e("IllegalAccessException", e3);
  271 + } catch (Exception e4) {
  272 + Logger.t(TAG).e("getFieldValue", e4);
  273 + }
  274 +
  275 + return (T) result;
  276 + } else {
  277 + Logger.t(TAG).w("getFieldValue param clz or fieldName can not be null!");
  278 + return null;
  279 + }
  280 + }
  281 +
  282 + /**
  283 + * 代理
  284 + *
  285 + * @param method 函数
  286 + * @param receiver 接收的对象
  287 + * @param args 参数
  288 + * @return 代理类
  289 + */
  290 + public static Object invoke(Method method, Object receiver, Object... args) {
  291 + if (null == method) {
  292 + Logger.t(TAG).w("invoke param method can not be null!");
  293 + return null;
  294 + } else {
  295 + try {
  296 + return method.invoke(receiver, args);
  297 + } catch (InvocationTargetException e1) {
  298 + Logger.t(TAG).e(method + " invoke ", e1.getTargetException());
  299 + } catch (Exception e2) {
  300 + Logger.t(TAG).e(method + " invoke ", e2);
  301 + }
  302 + return null;
  303 + }
  304 + }
  305 +
  306 + /**
  307 + * 获得类实例
  308 + *
  309 + * @param clazz 类
  310 + * @return 类实例
  311 + */
  312 + public static Object newInstance(Class<?> clazz) {
  313 + if (clazz == null) {
  314 + return null;
  315 + } else {
  316 + try {
  317 + return clazz.newInstance();
  318 + } catch (InstantiationException e1) {
  319 + Logger.t(TAG).e("newInstance InstantiationException ", e1);
  320 + } catch (IllegalAccessException e2) {
  321 + Logger.t(TAG).e("newInstance IllegalAccessException ", e2);
  322 + }
  323 +
  324 + return null;
  325 + }
  326 + }
  327 +
  328 + /**
  329 + * 获得类的实例
  330 + *
  331 + * @param className 类名称
  332 + * @param baseClz 类的基类
  333 + * @param <T> 泛型
  334 + * @return 类的实例
  335 + */
  336 + public static <T> T newInstance(String className, Class<T> baseClz) {
  337 + if (!TextUtils.isEmpty(className) && baseClz != null) {
  338 + try {
  339 + Class clz = Class.forName(className);
  340 + if (isSubClassOf(clz, baseClz)) {
  341 + return (T) clz.newInstance();
  342 + }
  343 + } catch (ClassNotFoundException e1) {
  344 + Logger.t(TAG).w("newInstance ClassNotFoundException");
  345 + } catch (InstantiationException e2) {
  346 + Logger.t(TAG).w("newInstance InstantiationException");
  347 + } catch (IllegalAccessException e3) {
  348 + Logger.t(TAG).w("newInstance IllegalAccessException");
  349 + }
  350 + }
  351 +
  352 + return null;
  353 + }
  354 +
  355 + /**
  356 + * 是否是一个类的子类对象
  357 + *
  358 + * @param childClz 子类
  359 + * @param parentClz 父类
  360 + * @return true: 是子类,false: 不是子类
  361 + */
  362 + public static boolean isSubClassOf(Class childClz, Class parentClz) {
  363 + return childClz != null && parentClz != null ? parentClz.isAssignableFrom(childClz) : false;
  364 + }
  365 +
  366 + /**
  367 + * 代理
  368 + *
  369 + * @param className 类名称
  370 + * @param methodName 函数名
  371 + * @param paramTypes 形参类型
  372 + * @param params 参数
  373 + * @return 代理类
  374 + */
  375 + public static Object invoke(String className, String methodName, Class<?>[] paramTypes, Object... params) {
  376 + if (className != null && !TextUtils.isEmpty(methodName)) {
  377 + try {
  378 + Class<?> cls = Class.forName(className);
  379 + Method method = cls.getMethod(methodName, paramTypes);
  380 + return invoke(method, cls.newInstance(), params);
  381 + } catch (ClassNotFoundException e1) {
  382 + Logger.t(TAG).e("ClassNotFoundException", e1);
  383 + } catch (NoSuchMethodException e2) {
  384 + Logger.t(TAG).e("NoSuchMethodException", e2);
  385 + } catch (InstantiationException e3) {
  386 + Logger.t(TAG).e("InstantiationException", e3);
  387 + } catch (IllegalAccessException e4) {
  388 + Logger.t(TAG).e("IllegalAccessException", e4);
  389 + }
  390 +
  391 + return null;
  392 + } else {
  393 + Logger.t(TAG).w("invoke param className or methodName can not be null!");
  394 + return null;
  395 + }
  396 + }
  397 +
  398 + /**
  399 + * 代理
  400 + *
  401 + * @param clazz 类
  402 + * @param methodName 函数名
  403 + * @param paramTypes 形参类型
  404 + * @param params 参数
  405 + * @return 代理类
  406 + */
  407 + public static Object invoke(Class<?> clazz, String methodName, Class<?>[] paramTypes, Object... params) {
  408 + if (clazz != null && !TextUtils.isEmpty(methodName)) {
  409 + try {
  410 + Method method = clazz.getMethod(methodName, paramTypes);
  411 + return invoke(method, clazz.newInstance(), params);
  412 + } catch (NoSuchMethodException e1) {
  413 + Logger.t(TAG).e("NoSuchMethodException", e1);
  414 + } catch (InstantiationException e2) {
  415 + Logger.t(TAG).e("InstantiationException", e2);
  416 + } catch (IllegalAccessException e3) {
  417 + Logger.t(TAG).e("IllegalAccessException", e3);
  418 + }
  419 +
  420 + return null;
  421 + } else {
  422 + Logger.t(TAG).w("invoke param clazz or methodName can not be null!");
  423 + return null;
  424 + }
  425 + }
  426 +
  427 + /**
  428 + * 静态
  429 + *
  430 + * @param clazz 类
  431 + * @param methodName 函数名
  432 + * @param paramTypes 形参类型
  433 + * @param params 参数
  434 + * @return 代理类
  435 + */
  436 + public static Object invokeStatic(Class<?> clazz, String methodName, Class<?>[] paramTypes, Object... params) {
  437 + if (clazz != null && !TextUtils.isEmpty(methodName)) {
  438 + try {
  439 + Method method = clazz.getMethod(methodName, paramTypes);
  440 + return method.invoke((Object) null, params);
  441 + } catch (NoSuchMethodException e1) {
  442 + Logger.t(TAG).e("NoSuchMethodException", e1);
  443 + } catch (IllegalAccessException e2) {
  444 + Logger.t(TAG).e("IllegalAccessException", e2);
  445 + } catch (InvocationTargetException e3) {
  446 + Logger.t(TAG).e("InvocationTargetException", e3.getTargetException());
  447 + }
  448 +
  449 + return null;
  450 + } else {
  451 + Logger.t(TAG).w("invoke param className or methodName can not be null!");
  452 + return null;
  453 + }
  454 + }
  455 +
  456 + /**
  457 + * 获取类
  458 + *
  459 + * @param className 类名
  460 + * @return 类
  461 + */
  462 + public static Class<?> getClass(String className) {
  463 + return getClass(className, false);
  464 + }
  465 +
  466 + private static Class<?> getClass(String className, boolean isSilent) {
  467 + if (null == className) {
  468 + return null;
  469 + } else {
  470 + Class clazz = null;
  471 + try {
  472 + clazz = Class.forName(className);
  473 + } catch (ClassNotFoundException e1) {
  474 + if (!isSilent) {
  475 + Logger.t(TAG).e("ClassNotFoundException:", e1);
  476 + }
  477 + } catch (LinkageError e2) {
  478 + if (!isSilent) {
  479 + Logger.t(TAG).e("an error occurs during linkage");
  480 + }
  481 + }
  482 + return clazz;
  483 + }
  484 + }
  485 +
  486 + /**
  487 + * 给属性设置新值
  488 + *
  489 + * @param field 属性
  490 + * @param object 类对象
  491 + * @param value 值
  492 + */
  493 + public static void setField(Field field, Object object, Object value) {
  494 + if (null != field) {
  495 + if (!Modifier.isStatic(field.getModifiers()) && null == object) {
  496 + Logger.t(TAG).w("field is not null and not static, but object is null");
  497 + } else {
  498 + try {
  499 + field.set(object, value);
  500 + } catch (IllegalAccessException e1) {
  501 + Logger.t(TAG).e("IllegalAccessException", e1);
  502 + } catch (IllegalArgumentException e2) {
  503 + Logger.t(TAG).e("IllegalArgumentException", e2);
  504 + }
  505 +
  506 + }
  507 + }
  508 + }
  509 +
  510 + /**
  511 + * 返回直接继承的父类(包含泛型参数)
  512 + *
  513 + * @param clz 类
  514 + * @return 直接继承的父类(包含泛型参数)
  515 + */
  516 + public static String getTypeArgument(Class clz) {
  517 + String arg = null;
  518 + if (clz != null) {
  519 + Type superType = clz.getGenericSuperclass();
  520 + if (superType instanceof ParameterizedType) {
  521 + arg = ((ParameterizedType) superType).getActualTypeArguments()[0].toString();
  522 + }
  523 + }
  524 +
  525 + return arg;
  526 + }
  527 +
  528 + /**
  529 + * 获取默认值
  530 + *
  531 + * @param type 类型
  532 + * @return 默认值
  533 + */
  534 + public static Object getDefaultValue(Class<?> type) {
  535 + return null == type ? null : getDefaultValue(type.getName());
  536 + }
  537 +
  538 + public static Object getDefaultValue(String fullyQualifiedTypeName) {
  539 + if (fullyQualifiedTypeName == null) {
  540 + return "";
  541 + } else if (fullyQualifiedTypeName.equals(Byte.TYPE.getName())) {
  542 + return 0;
  543 + } else if (fullyQualifiedTypeName.equals(Integer.TYPE.getName())) {
  544 + return 0;
  545 + } else if (fullyQualifiedTypeName.equals(Short.TYPE.getName())) {
  546 + return Short.valueOf((short) 0);
  547 + } else if (fullyQualifiedTypeName.equals(Long.TYPE.getName())) {
  548 + return 0L;
  549 + } else if (fullyQualifiedTypeName.equals(Float.TYPE.getName())) {
  550 + return 0.0F;
  551 + } else if (fullyQualifiedTypeName.equals(Double.TYPE.getName())) {
  552 + return 0.0D;
  553 + } else if (fullyQualifiedTypeName.equals(Boolean.TYPE.getName())) {
  554 + return false;
  555 + } else {
  556 + return fullyQualifiedTypeName.equals(Character.TYPE.getName()) ? ' ' : null;
  557 + }
  558 + }
  559 +
  560 + public static boolean isVoidMethod(Method method) {
  561 + if (method != null && method.getReturnType() != null) {
  562 + return StringUtils.isEqual("void", method.getReturnType().getName());
  563 + }
  564 + return true;
  565 + }
  566 +}
  1 +/*
  2 + * Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
  3 + */
  4 +
  5 +package com.wd.foundation.wdkitcore.tools;
  6 +
  7 +import java.util.ArrayList;
  8 +import java.util.IllegalFormatException;
  9 +import java.util.Iterator;
  10 +import java.util.List;
  11 +import java.util.Locale;
  12 +
  13 +import android.text.TextUtils;
  14 +
  15 +import androidx.annotation.Nullable;
  16 +
  17 +import com.wd.base.log.Logger;
  18 +
  19 +/**
  20 + * <字符串工具类>
  21 + *
  22 + * @author wangnaiwen
  23 + * @version [V1.0.0.0, 2020/5/16]
  24 + * @since V1.0.0.0
  25 + */
  26 +public class StringUtils {
  27 + private static final String EMPTY_ARRAYS = "[]";
  28 +
  29 + private static final String TAG = "StringUtils";
  30 +
  31 + private static final String HEXSTRING = "0x";
  32 +
  33 + private static final String IP_REGEX =
  34 + "((?:(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))\\.){3}(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d))))";
  35 +
  36 + private static final int HEX_VALUE = 255;
  37 +
  38 + private static final String EMPTY = "";
  39 +
  40 + private static final int ARRAY_INDEX = 2;
  41 +
  42 + private StringUtils() {
  43 + }
  44 +
  45 + public static boolean isEmpty(String value) {
  46 + return null == value || 0 == value.length();
  47 + }
  48 +
  49 + public static boolean isNotEmpty(String value) {
  50 + return value != null && 0 != value.length();
  51 + }
  52 +
  53 + public static boolean isBlank(String value) {
  54 + return null == value || 0 == value.length() || EMPTY.equals(value.trim());
  55 + }
  56 +
  57 + public static boolean isNotBlank(String value) {
  58 + return !isBlank(value);
  59 + }
  60 +
  61 + public static String trimNonBlankStr(String value, String defValue) {
  62 + return isBlank(value) ? defValue : value.trim();
  63 + }
  64 +
  65 + public static boolean isIPAddress(String strIp) {
  66 + return null == strIp ? false : strIp.matches(IP_REGEX);
  67 + }
  68 +
  69 + public static String trimNonNullStr(String value, String defValue) {
  70 + return null == value ? defValue : value.trim();
  71 + }
  72 +
  73 + public static String emptyIfBlank(String value) {
  74 + return null == value ? EMPTY : value.trim();
  75 + }
  76 +
  77 + public static String trimAndLowerCase(String value) {
  78 + return str2LowerCase(emptyIfBlank(value));
  79 + }
  80 +
  81 + public static String trimAndUpperCase(String value) {
  82 + return str2UpperCase(emptyIfBlank(value));
  83 + }
  84 +
  85 + public static String trimAndToString(Object object) {
  86 + return null == object ? EMPTY : object.toString().trim();
  87 + }
  88 +
  89 + public static boolean isNull(String string) {
  90 + if (null != string) {
  91 + string = string.trim();
  92 + if (string.length() != 0) {
  93 + return false;
  94 + }
  95 + }
  96 +
  97 + return true;
  98 + }
  99 +
  100 + public static String pickNotEmptyString(String... strings) {
  101 + if (strings != null && strings.length != 0) {
  102 + String[] var1 = strings;
  103 + int var2 = strings.length;
  104 +
  105 + for (int var3 = 0; var3 < var2; ++var3) {
  106 + String s = var1[var3];
  107 + if (!isEmpty(s)) {
  108 + return s;
  109 + }
  110 + }
  111 +
  112 + return null;
  113 + } else {
  114 + return null;
  115 + }
  116 + }
  117 +
  118 + public static String getImageOfSize(String url, String size) {
  119 + if (url == null) {
  120 + return url;
  121 + } else {
  122 + String[] parts = url.split(",");
  123 + String sizeSeparator = "_" + size;
  124 + if (parts.length == 1) {
  125 + return url;
  126 + } else {
  127 + String[] var4 = parts;
  128 + int var5 = parts.length;
  129 +
  130 + for (int var6 = 0; var6 < var5; ++var6) {
  131 + String part = var4[var6];
  132 + String[] urlParts = part.split("\\.");
  133 + if (urlParts.length < ARRAY_INDEX) {
  134 + return url;
  135 + }
  136 +
  137 + String filename = urlParts[urlParts.length - ARRAY_INDEX];
  138 + if (filename.endsWith(sizeSeparator)) {
  139 + return part;
  140 + }
  141 + }
  142 +
  143 + if (parts.length > 1) {
  144 + return parts[parts.length - 1];
  145 + } else {
  146 + return url;
  147 + }
  148 + }
  149 + }
  150 + }
  151 +
  152 + public static int stringToInt(String str, int def) {
  153 + if (isEmpty(str)) {
  154 + return def;
  155 + } else {
  156 + int result;
  157 + if (str.contains(HEXSTRING)) {
  158 + String strTemp = cutString(str, str.indexOf(HEXSTRING) + HEXSTRING.length());
  159 + result = MathUtils.parseInt(strTemp, 16, def);
  160 + } else {
  161 + result = MathUtils.parseInt(str, def);
  162 + }
  163 + return result;
  164 + }
  165 + }
  166 +
  167 + public static boolean contains(String str, String def) {
  168 + if (isEmpty(str)) {
  169 + return isEmpty(def);
  170 + }
  171 + if (isEmpty(def)) {
  172 + return true;
  173 + }
  174 +
  175 + return str.contains(def);
  176 + }
  177 +
  178 + public static String retrieveNumberStr(String str, int def) {
  179 + return isEmpty(str) ? String.valueOf(def) : String.valueOf(MathUtils.parseInt(str, def));
  180 + }
  181 +
  182 + public static String cutString(String originalStr, int beginIndex) {
  183 + if (isEmpty(originalStr)) {
  184 + return originalStr;
  185 + } else {
  186 + try {
  187 + return originalStr.substring(beginIndex);
  188 + } catch (IndexOutOfBoundsException var3) {
  189 + return originalStr;
  190 + }
  191 + }
  192 + }
  193 +
  194 + public static String cutString(String originalStr, int beginIndex, int endIndex) {
  195 + if (isEmpty(originalStr)) {
  196 + return originalStr;
  197 + } else {
  198 + try {
  199 + return originalStr.substring(beginIndex, endIndex);
  200 + } catch (IndexOutOfBoundsException var4) {
  201 + return originalStr;
  202 + }
  203 + }
  204 + }
  205 +
  206 + public static String str2UpperCase(String source) {
  207 + return TextUtils.isEmpty(source) ? source : source.toUpperCase(Locale.US);
  208 + }
  209 +
  210 + public static String str2LowerCase(String source) {
  211 + return TextUtils.isEmpty(source) ? source : source.toLowerCase(Locale.US);
  212 + }
  213 +
  214 + public static String formatByUSLocale(String format, Object... args) {
  215 + return format(Locale.US, format, args);
  216 + }
  217 +
  218 + public static String formatForShow(String format, Object... args) {
  219 + return format(Locale.getDefault(), format, args);
  220 + }
  221 +
  222 + private static String format(Locale l, String format, Object... args) {
  223 + if (TextUtils.isEmpty(format)) {
  224 + return null;
  225 + } else {
  226 + String target;
  227 + try {
  228 + target = String.format(l, format, args);
  229 + } catch (IllegalFormatException var5) {
  230 + Logger.t(TAG).e("IllegalFormatException happened.");
  231 + target = null;
  232 + }
  233 +
  234 + return target;
  235 + }
  236 + }
  237 +
  238 + public static String getIndexOfString(List<String> strs) {
  239 + if (ArrayUtils.isEmpty(strs)) {
  240 + return null;
  241 + } else {
  242 + List<String> res = new ArrayList();
  243 + Iterator var2 = strs.iterator();
  244 +
  245 + while (var2.hasNext()) {
  246 + String str = (String) var2.next();
  247 + if (!TextUtils.isEmpty(str)) {
  248 + res.add(str);
  249 + }
  250 + }
  251 +
  252 + if (res.size() > 0 && res.size() <= ARRAY_INDEX) {
  253 + return (String) res.get(res.size() - 1);
  254 + } else if (res.size() > ARRAY_INDEX) {
  255 + return (String) res.get(res.size() - ARRAY_INDEX);
  256 + } else {
  257 + return null;
  258 + }
  259 + }
  260 + }
  261 +
  262 + public static String bytesToHexString(byte[] bytes) {
  263 + StringBuilder sb = new StringBuilder();
  264 +
  265 + for (int i = 0; i < bytes.length; ++i) {
  266 + String hex = Integer.toHexString(HEX_VALUE & bytes[i]);
  267 + if (hex.length() == 1) {
  268 + sb.append('0');
  269 + }
  270 +
  271 + sb.append(hex);
  272 + }
  273 +
  274 + return sb.toString();
  275 + }
  276 +
  277 + public static boolean isEqual(String str1, String str2) {
  278 + if (str1 == null) {
  279 + return str2 == null;
  280 + } else {
  281 + return str1.equals(str2);
  282 + }
  283 + }
  284 +
  285 + public static boolean isEqualIgnoreCase(String str1, String str2) {
  286 + if (str1 == null) {
  287 + return str2 == null;
  288 + } else {
  289 + return str1.equalsIgnoreCase(str2);
  290 + }
  291 + }
  292 +
  293 + public static String substringBefore(String str, String separator) {
  294 + if (!isEmpty(str) && separator != null) {
  295 + if (separator.length() == 0) {
  296 + return EMPTY;
  297 + } else {
  298 + int pos = str.indexOf(separator);
  299 + return pos == -1 ? str : str.substring(0, pos);
  300 + }
  301 + } else {
  302 + return str;
  303 + }
  304 + }
  305 +
  306 + public static String substringAfter(String str, String separator) {
  307 + if (isEmpty(str)) {
  308 + return str;
  309 + } else if (separator == null) {
  310 + return EMPTY;
  311 + } else {
  312 + int pos = str.indexOf(separator);
  313 + return pos == -1 ? EMPTY : str.substring(pos + separator.length());
  314 + }
  315 + }
  316 +
  317 + public static String substringBetween(String str, String open, String close) {
  318 + if (str != null && open != null && close != null) {
  319 + int start = str.indexOf(open);
  320 + if (start != -1) {
  321 + int end = str.indexOf(close, start + open.length());
  322 + if (end != -1) {
  323 + return str.substring(start + open.length(), end);
  324 + }
  325 + }
  326 +
  327 + return str;
  328 + } else {
  329 + return str;
  330 + }
  331 + }
  332 +
  333 + public static String getValueFromKeyValueStr(String keyValueStr, String spliter) {
  334 + if (keyValueStr != null && spliter != null) {
  335 + String[] keyValuePair = keyValueStr.split(spliter);
  336 + return keyValuePair.length > 1 ? keyValuePair[1] : null;
  337 + } else {
  338 + return null;
  339 + }
  340 + }
  341 +
  342 + public static <S> String getArrayStrings(List<S> list) {
  343 + return getArrayStrings(list, (ConvertHelper.IConverter) null);
  344 + }
  345 +
  346 + public static <S> String getArrayStrings(List<S> list, @Nullable ConvertHelper.IConverter<S, String> iConverter) {
  347 + if (null == iConverter) {
  348 + iConverter = new ConvertHelper.IConverter<S, String>() {
  349 + public String convert(S source) {
  350 + return null == source ? null : source.toString();
  351 + }
  352 + };
  353 + }
  354 +
  355 + List<String> prints = ConvertHelper.convert(list, iConverter);
  356 + if (!ArrayUtils.isEmpty(prints)) {
  357 + StringBuilder sb = new StringBuilder();
  358 + sb.append('[');
  359 + int pos = 0;
  360 +
  361 + for (Iterator var5 = prints.iterator(); var5.hasNext(); ++pos) {
  362 + String print = (String) var5.next();
  363 + if (pos != 0) {
  364 + sb.append(',');
  365 + }
  366 +
  367 + sb.append(print);
  368 + }
  369 +
  370 + return sb.append(']').toString();
  371 + } else {
  372 + return EMPTY_ARRAYS;
  373 + }
  374 + }
  375 +
  376 + public static String append(String... strings) {
  377 + if (!ArrayUtils.isEmpty(strings)) {
  378 + StringBuilder sb = new StringBuilder();
  379 + int pos = 0;
  380 + String[] var3 = strings;
  381 + int var4 = strings.length;
  382 +
  383 + for (int var5 = 0; var5 < var4; ++var5) {
  384 + String s = var3[var5];
  385 + if (pos != 0) {
  386 + sb.append('_');
  387 + }
  388 +
  389 + sb.append(s);
  390 + ++pos;
  391 + }
  392 +
  393 + return sb.toString();
  394 + } else {
  395 + return EMPTY;
  396 + }
  397 + }
  398 +
  399 + public static String getStringWithLimit(String originalStr, int limit) {
  400 + if (isEmpty(originalStr)) {
  401 + return originalStr;
  402 + } else if (originalStr.length() <= limit) {
  403 + return originalStr;
  404 + } else {
  405 + String replaceString = "...";
  406 + int replaceLength = replaceString.length();
  407 + return cutString(originalStr, 0, limit - replaceLength) + replaceString;
  408 + }
  409 + }
  410 +}
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 +
  4 +</resources>