张波

提交代码

Showing 57 changed files with 3064 additions and 0 deletions
*.iml
.gradle
/local.properties
/.idea
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
... ...
/build
\ No newline at end of file
... ...
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
}
android {
compileSdkVersion var.compileSdkVersion
buildToolsVersion var.buildToolsVersion
defaultConfig {
applicationId "com.example.myapplication"
minSdkVersion var.minSdkVersion
targetSdkVersion var.targetSdkVersion
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
ndk {
// noinspection ChromeOsAbiSupport
abiFilters "armeabi-v7a", "arm64-v8a", "x86"
}
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
compileOptions {
// Java兼容性设置为Java 8
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
// implementation 'androidx.appcompat:appcompat:1.6.1'
implementation "com.google.android.material:material:1.4.0"
// implementation project(path: ':wdlog')
api(name: "wdlog-debug-v1.0.0", ext: "aar")
}
\ No newline at end of file
... ...
No preview for this file type
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.myapplication">
<!-- 请求网络 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature
android:name="android.software.leanback"
android:required="false" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication"
tools:targetApi="31">
<activity
android:name="com.example.myapplication.MainActivity"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
... ...
package com.example.myapplication;
import android.app.Activity;
import android.os.Bundle;
import androidx.annotation.Nullable;
/**
* @ProjectName: PeopleDailyVideo
* @Package: com.people.displayui.main
* @ClassName: WelcomeActivity
* @Description: 启动APP过渡页面
* @Author: wd
* @CreateDate: 2022/10/28 17:36
* @UpdateUser: wd
* @UpdateDate: 2022/10/28 17:36
* @UpdateRemark: 更新说明:
* @Version: 1.0
*/
public class MainActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 直接进入首页
}
}
... ...
package com.example.myapplication;
import android.app.Application;
import android.util.Log;
import com.wd.base.log.Logger;
import com.wd.base.log.LoggerDefaultInit;
/**
* @author devel
* @time 2024/8/28 星期三 16:23
*/
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Log.e("zzzz","MyApplication onCreate");
LoggerDefaultInit.getInstance().init(true);
// test
Logger.t("zzzz").e("zzzz lalalalla");
}
}
... ...
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>
... ...
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<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">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
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"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white" />
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
... ...
No preview for this file type
No preview for this file type
No preview for this file type
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>
\ No newline at end of file
... ...
<resources>
<string name="app_name">My Application</string>
</resources>
\ No newline at end of file
... ...
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?><!--
Sample backup rules file; uncomment and customize as necessary.
See https://developer.android.com/guide/topics/data/autobackup
for details.
Note: This file is ignored for devices older that API 31
See https://developer.android.com/about/versions/12/backup-restore
-->
<full-backup-content>
<!--
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
-->
</full-backup-content>
\ No newline at end of file
... ...
apply plugin: 'maven'
buildscript {
ext.kotlin_version = "1.4.32"
repositories {
mavenLocal()
mavenCentral()
// 以下四行代码为阿里gradle源,需要的人自己放開使用
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/releases' }
//阿里云 maven
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/repository/releases' }
google()
maven { url "https://jitpack.io" }
//华为
maven { url 'https://developer.huawei.com/repo/' }
//阿里云QuickTracking
maven { url 'https://repo1.maven.org/maven2/' }
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven {
url 'https://maven.aliyun.com/nexus/content/repositories/google/'
name 'aliyun-google'
}
// TingYun
maven { url "https://nexus2.tingyun.com/nexus/content/repositories/snapshots/" }
}
dependencies {
classpath "com.android.tools.build:gradle:4.0.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.billy.android:autoregister:1.4.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenLocal()
mavenCentral()
// 以下四行代码为阿里gradle源,需要的人自己放開使用
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/releases' }
//阿里云 maven
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/repository/releases' }
google()
maven { url "https://jitpack.io" }
//华为
maven { url 'https://developer.huawei.com/repo/' }
//阿里云QuickTracking
maven { url 'https://repo1.maven.org/maven2/' }
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven {
url 'https://maven.aliyun.com/nexus/content/repositories/google/'
name 'aliyun-google'
}
flatDir { dirs 'src/main/libs' }
}
project.configurations.configureEach {
resolutionStrategy.eachDependency { details ->
if (details.requested.group == 'com.android.android.support' && !details.requested.name.contains('multidex')) {
details.useVersion "28.0.0"
}
}
}
// 强制依赖
configurations.configureEach {
exclude group: 'com.alipay.android.phone.thirdparty', module: 'securityguard-build'
resolutionStrategy {
force 'androidx.activity:activity:1.2.1'
force 'androidx.annotation:annotation:1.1.0'
force 'androidx.appcompat:appcompat:1.2.0'
force 'androidx.arch.core:core-common:2.1.0'
force 'androidx.arch.core:core-runtime:2.1.0'
force 'androidx.core:core-ktx:1.6.0'
force 'androidx.core:core:1.5.0'
force 'androidx.collection:collection:1.1.0'
force 'androidx.constraintlayout:constraintlayout:2.0.4'
force 'androidx.constraintlayout:constraintlayout-solver:2.0.4'
force 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
force 'androidx.fragment:fragment:1.3.1'
force 'androidx.lifecycle:lifecycle-common:2.3.0'
force 'androidx.multidex:multidex:2.0.1'
force 'androidx.recyclerview:recyclerview:1.2.0'
force 'androidx.vectordrawable:vectordrawable:1.1.0'
force 'androidx.vectordrawable:vectordrawable-animated:1.1.0'
force 'com.squareup.okhttp3:okhttp:4.9.1'
force 'com.squareup.okio:okio:2.7.0'
force 'org.jetbrains.kotlin:kotlin-stdlib:1.4.32'
force 'org.jetbrains.kotlin:kotilin-stdlib-jdk8:1.4.32'
force 'org.jetbrains:annotations:15.0'
force 'net.sf.proguard:proguard-base:6.1.0'
}
}
}
ext {
var = [
// SDK And Tools
applicationId : "com.wondertek.dss",
minSdkVersion : 25,
targetSdkVersion : 30,
compileSdkVersion: 30,
buildToolsVersion: "30.0.3",
// 版本号,正式版本 1.0.0 1000080 后两位,80即标识为发布版本
// 测试版本 1.0.0_TF1 1000001 后两位,01即为测试版本号,01-79
// 升级版本 1.0.0_RC1 1000081 后两位,81即为升级版本号,81-99
versionName : "1.0.0", // release正式
debugVnName : "", // debug开发模式 用于区分debug模式下上报的日志
versionCode : 100,
//此版本号是SDK版本,不能随便改
aar_version : "1.0.0",
]
}
... ...
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="12">
<profile kind="CodeFormatterProfile" name="WonderTek_CodeFormatter_Convention_v1.0"
version="12">
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment"
value="common_lines" />
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries"
value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation"
value="common_lines" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement"
value="common_lines" />
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true" />
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration"
value="common_lines" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off" />
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="1" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="49" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement"
value="common_lines" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true" />
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration"
value="20" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line"
value="false" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations"
value="1" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column"
value="false" />
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="120" />
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments"
value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration"
value="end_of_line" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch"
value="16" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body"
value="0" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line"
value="false" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause"
value="common_lines" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration"
value="20" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration"
value="20" />
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error" />
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer"
value="20" />
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation"
value="common_lines" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="20" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header"
value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration"
value="16" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration"
value="0" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line"
value="false" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case"
value="end_of_line" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while"
value="insert" />
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="16" />
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases"
value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines"
value="2147483647" />
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="16" />
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations"
value="false" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause"
value="common_lines" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation"
value="80" />
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column"
value="false" />
<setting id="org.eclipse.jdt.core.compiler.source" value="1.8" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="1" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer"
value="1" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator"
value="false" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement"
value="do not insert" />
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration"
value="common_lines" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16" />
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation"
value="16" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header"
value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration"
value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch"
value="do not insert" />
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration"
value="common_lines" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration"
value="end_of_line" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="1" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header"
value="16" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters"
value="do not insert" />
<setting
id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header"
value="true" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration"
value="insert" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="false" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional"
value="insert" />
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description"
value="false" />
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space" />
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1" />
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation"
value="do not insert" />
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch"
value="insert" />
</profile>
</profiles>
\ No newline at end of file
... ...
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
#org.gradle.jvmargs=-Xmx2048m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
android.enableResourceOptimizations=false
#建议您关闭 R8 后再进行混淆
android.enableR8=false
android.enableR8.libraries=false
# 如果使用最新稳定版本 Android Studio 3.5 或以上,那么您需要在 gradle.properties 里面新增
android.buildOnlyTargetAbi=false
#网络请求接口版本 202204151851
requestVersion=107
#设置组件是否作为app还是lib,true是lib ,false 是app
#分享
isShareModule=true
#播放器
isPlayerModule=true
#是否直播模块运行 false可以单独运行
isLiveModule=true
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
#android.nonTransitiveRClass=true
... ...
No preview for this file type
#Fri Oct 23 14:37:25 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-6.8-all.zip
... ...
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
... ...
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
... ...
rootProject.name = "wdlog"
include ':app'
include ':wdlog'
\ No newline at end of file
... ...
/build
\ No newline at end of file
... ...
plugins {
id 'com.android.library'
id 'kotlin-android'
}
android {
compileSdkVersion var.compileSdkVersion
defaultConfig {
minSdkVersion var.minSdkVersion
targetSdkVersion var.targetSdkVersion
versionCode var.versionCode
versionName var.versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
buildConfigField "String", "API_VERSION", "\"${requestVersion}\""
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// 自定义AAR包名
android.libraryVariants.all { variant ->
variant.outputs.all {
if (outputFileName != null && outputFileName.endsWith(".aar")) {
def fileName = "${project.name}-${buildType.name}-v${var.aar_version}.aar"
outputFileName = fileName
}
}
}
}
dependencies {
implementation 'androidx.annotation:annotation:1.8.2'
}
\ No newline at end of file
... ...
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
... ...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wd.log">
</manifest>
\ No newline at end of file
... ...
package com.wd.base.log;
import static com.wd.base.log.Utils.checkNotNull;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Android terminal log output implementation for {@link LogAdapter}.
* Prints output to LogCat with pretty borders.
*
* <pre>
* ┌──────────────────────────
* │ Method stack history
* ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
* │ Log message
* └──────────────────────────
* </pre>
*/
public class AndroidLogAdapter implements LogAdapter {
@NonNull
private final FormatStrategy formatStrategy;
public AndroidLogAdapter() {
this.formatStrategy = PrettyFormatStrategy.newBuilder().build();
}
public AndroidLogAdapter(@NonNull FormatStrategy formatStrategy) {
this.formatStrategy = checkNotNull(formatStrategy);
}
@Override
public boolean isLoggable(int priority, @Nullable String tag) {
return true;
}
@Override
public void log(int priority, @Nullable String tag, @NonNull String message) {
formatStrategy.log(priority, tag, message);
}
}
... ...
package com.wd.base.log;
import static com.wd.base.log.Utils.checkNotNull;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* CSV formatted file logging for Android.
* Writes to CSV the following data:
* epoch timestamp, ISO8601 timestamp (human-readable), log level, tag, log message.
*/
public class CsvFormatStrategy implements FormatStrategy {
private static final String NEW_LINE = System.getProperty("line.separator");
private static final String NEW_LINE_REPLACEMENT = " <br> ";
private static final String SEPARATOR = ",";
@NonNull
private final Date date;
@NonNull
private final SimpleDateFormat dateFormat;
@NonNull
private final LogStrategy logStrategy;
@Nullable
private final String tag;
private CsvFormatStrategy(@NonNull CsvFormatStrategy.Builder builder) {
checkNotNull(builder);
date = builder.date;
dateFormat = builder.dateFormat;
logStrategy = builder.logStrategy;
tag = builder.tag;
}
@NonNull
public static CsvFormatStrategy.Builder newBuilder() {
return new CsvFormatStrategy.Builder();
}
@Override
public void log(int priority, @Nullable String onceOnlyTag, @NonNull String message) {
checkNotNull(message);
String tag = formatTag(onceOnlyTag);
date.setTime(System.currentTimeMillis());
StringBuilder builder = new StringBuilder();
// machine-readable date/time
builder.append(Long.toString(date.getTime()));
// human-readable date/time
builder.append(SEPARATOR);
builder.append(dateFormat.format(date));
// level
builder.append(SEPARATOR);
builder.append(Utils.logLevel(priority));
// tag
builder.append(SEPARATOR);
builder.append(tag);
// message
if (message.contains(NEW_LINE)) {
// a new line would break the CSV format, so we replace it here
message = message.replaceAll(NEW_LINE, NEW_LINE_REPLACEMENT);
}
builder.append(SEPARATOR);
builder.append(message);
// new line
builder.append(NEW_LINE);
logStrategy.log(priority, tag, builder.toString());
}
@Nullable
private String formatTag(@Nullable String tag) {
if (!Utils.isEmpty(tag) && !Utils.equals(this.tag, tag)) {
return this.tag + "-" + tag;
}
return this.tag;
}
public static final class Builder {
private static final int MAX_BYTES = 500 * 1024; // 500K averages to a 4000 lines per file
Date date;
SimpleDateFormat dateFormat;
LogStrategy logStrategy;
String tag = "PRETTY_LOGGER";
private Builder() {
}
@NonNull
public CsvFormatStrategy.Builder date(@Nullable Date val) {
date = val;
return this;
}
@NonNull
public CsvFormatStrategy.Builder dateFormat(@Nullable SimpleDateFormat val) {
dateFormat = val;
return this;
}
@NonNull
public CsvFormatStrategy.Builder logStrategy(@Nullable LogStrategy val) {
logStrategy = val;
return this;
}
@NonNull
public CsvFormatStrategy.Builder tag(@Nullable String tag) {
this.tag = tag;
return this;
}
@NonNull
public CsvFormatStrategy build() {
if (date == null) {
date = new Date();
}
if (dateFormat == null) {
dateFormat = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss.SSS", Locale.UK);
}
if (logStrategy == null) {
String diskPath = Environment.getExternalStorageDirectory().getAbsolutePath();
String folder = diskPath + File.separatorChar + "logger";
HandlerThread ht = new HandlerThread("AndroidFileLogger." + folder);
ht.start();
Handler handler = new DiskLogStrategy.WriteHandler(ht.getLooper(), folder, MAX_BYTES);
logStrategy = new DiskLogStrategy(handler);
}
return new CsvFormatStrategy(this);
}
}
}
... ...
package com.wd.base.log;
import static com.wd.base.log.Utils.checkNotNull;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* This is used to saves log messages to the disk.
* By default it uses {@link CsvFormatStrategy} to translates text message into CSV format.
*/
public class DiskLogAdapter implements LogAdapter {
@NonNull private final FormatStrategy formatStrategy;
public DiskLogAdapter() {
formatStrategy = CsvFormatStrategy.newBuilder().build();
}
public DiskLogAdapter(@NonNull FormatStrategy formatStrategy) {
this.formatStrategy = checkNotNull(formatStrategy);
}
@Override public boolean isLoggable(int priority, @Nullable String tag) {
return true;
}
@Override public void log(int priority, @Nullable String tag, @NonNull String message) {
formatStrategy.log(priority, tag, message);
}
}
... ...
package com.wd.base.log;
import static com.wd.base.log.Utils.checkNotNull;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Abstract class that takes care of background threading the file log operation on Android.
* implementing classes are free to directly perform I/O operations there.
* Writes all logs to the disk with CSV format.
*/
public class DiskLogStrategy implements LogStrategy {
@NonNull
private final Handler handler;
public DiskLogStrategy(@NonNull Handler handler) {
this.handler = checkNotNull(handler);
}
@Override
public void log(int level, @Nullable String tag, @NonNull String message) {
checkNotNull(message);
// do nothing on the calling thread, simply pass the tag/msg to the background thread
handler.sendMessage(handler.obtainMessage(level, message));
}
static class WriteHandler extends Handler {
@NonNull
private final String folder;
private final int maxFileSize;
WriteHandler(@NonNull Looper looper, @NonNull String folder, int maxFileSize) {
super(checkNotNull(looper));
this.folder = checkNotNull(folder);
this.maxFileSize = maxFileSize;
}
@SuppressWarnings("checkstyle:emptyblock")
@Override
public void handleMessage(@NonNull Message msg) {
String content = (String) msg.obj;
FileWriter fileWriter = null;
File logFile = getLogFile(folder, "logs");
try {
fileWriter = new FileWriter(logFile, true);
writeLog(fileWriter, content);
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
if (fileWriter != null) {
try {
fileWriter.flush();
fileWriter.close();
} catch (IOException e1) {
/* fail silently */ }
}
}
}
/**
* This is always called on a single background thread.
* Implementing classes must ONLY write to the fileWriter and nothing more.
* The abstract class takes care of everything else including close the stream and catching IOException
*
* @param fileWriter an instance of FileWriter already initialised to the correct file
*/
private void writeLog(@NonNull FileWriter fileWriter, @NonNull String content) throws IOException {
checkNotNull(fileWriter);
checkNotNull(content);
fileWriter.append(content);
}
private File getLogFile(@NonNull String folderName, @NonNull String fileName) {
checkNotNull(folderName);
checkNotNull(fileName);
File folder = new File(folderName);
if (!folder.exists()) {
// TODO: What if folder is not created, what happens then?
folder.mkdirs();
}
int newFileCount = 0;
File newFile;
File existingFile = null;
newFile = new File(folder, String.format("%s_%s.csv", fileName, newFileCount));
while (newFile.exists()) {
existingFile = newFile;
newFileCount++;
newFile = new File(folder, String.format("%s_%s.csv", fileName, newFileCount));
}
if (existingFile != null) {
if (existingFile.length() >= maxFileSize) {
return newFile;
}
return existingFile;
}
return newFile;
}
}
}
... ...
package com.wd.base.log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Used to determine how messages should be printed or saved.
*/
public interface FormatStrategy {
void log(int priority, @Nullable String tag, @NonNull String message);
}
... ...
package com.wd.base.log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Provides a common interface to emits logs through. This is a required contract for Logger.
*
* @see AndroidLogAdapter
* @see DiskLogAdapter
*/
public interface LogAdapter {
/**
* Used to determine whether log should be printed out or not.
*
* @param priority is the log level e.g. DEBUG, WARNING
* @param tag is the given tag for the log message
* @return is used to determine if log should printed.
* If it is true, it will be printed, otherwise it'll be ignored.
*/
boolean isLoggable(int priority, @Nullable String tag);
/**
* Each log will use this pipeline
*
* @param priority is the log level e.g. DEBUG, WARNING
* @param tag is the given tag for the log message.
* @param message is the given message for the log message.
*/
void log(int priority, @Nullable String tag, @NonNull String message);
}
... ...
package com.wd.base.log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Determines destination target for the logs such as Disk, Logcat etc.
*
* @see LogcatLogStrategy
* @see DiskLogStrategy
*/
public interface LogStrategy {
/**
* This is invoked by Logger each time a log message is processed.
* Interpret this method as last destination of the log in whole pipeline.
*
* @param priority is the log level e.g. DEBUG, WARNING
* @param tag is the given tag for the log message.
* @param message is the given message for the log message.
*/
void log(int priority, @Nullable String tag, @NonNull String message);
}
... ...
package com.wd.base.log;
import static com.wd.base.log.Utils.checkNotNull;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* LogCat implementation for {@link LogStrategy}
* This simply prints out all logs to Logcat by using standard {@link Log} class.
*/
public class LogcatLogStrategy implements LogStrategy {
static final String DEFAULT_TAG = "NO_TAG";
@Override
public void log(int priority, @Nullable String tag, @NonNull String message) {
checkNotNull(message);
if (tag == null) {
tag = DEFAULT_TAG;
}
Log.println(priority, tag, message);
}
}
... ...
package com.wd.base.log;
import static com.wd.base.log.Utils.checkNotNull;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Logger, but more pretty, simple and powerful
*/
public final class Logger {
public static final int VERBOSE = 2;
public static final int DEBUG = 3;
public static final int INFO = 4;
public static final int WARN = 5;
public static final int ERROR = 6;
public static final int ASSERT = 7;
@NonNull
private static Printer printer = new LoggerPrinter();
private Logger() {
// no instance
}
public static void printer(@NonNull Printer printer) {
Logger.printer = checkNotNull(printer);
}
public static void addLogAdapter(@NonNull LogAdapter adapter) {
printer.addAdapter(checkNotNull(adapter));
}
public static void clearLogAdapters() {
printer.clearLogAdapters();
}
/**
* Given tag will be used as tag only once for this method call regardless of the tag that's been
* set during initialization. After this invocation, the general tag that's been set will
* be used for the subsequent log calls
*/
public static Printer t(@Nullable String tag) {
return printer.t(tag);
}
/**
* General log function that accepts all configurations as parameter
*/
public static void log(int priority, @Nullable String tag, @Nullable String message,
@Nullable Throwable throwable) {
printer.log(priority, tag, message, throwable);
}
public static void d(@NonNull String message, @Nullable Object... args) {
printer.d(message, args);
}
public static void d(@Nullable Object object) {
printer.d(object);
}
public static void e(@NonNull String message, @Nullable Object... args) {
printer.e(null, message, args);
}
public static void e(@Nullable Throwable throwable, @NonNull String message, @Nullable Object... args) {
printer.e(throwable, message, args);
}
public static void i(@NonNull String message, @Nullable Object... args) {
printer.i(message, args);
}
public static void v(@NonNull String message, @Nullable Object... args) {
printer.v(message, args);
}
public static void w(@NonNull String message, @Nullable Object... args) {
printer.w(message, args);
}
/**
* Tip: Use this for exceptional situations to log
* ie: Unexpected errors etc
*/
public static void wtf(@NonNull String message, @Nullable Object... args) {
printer.wtf(message, args);
}
/**
* Formats the given json content and print it
*/
public static void json(@Nullable String json) {
printer.json(json);
}
/**
* Formats the given xml content and print it
*/
public static void xml(@Nullable String xml) {
printer.xml(xml);
}
}
... ...
package com.wd.base.log;
/**
* @author yangchenggong
* @date 2022/7/4 15:18
*/
public class LoggerDefaultInit {
private static volatile LoggerDefaultInit s = null;
private LoggerDefaultInit() {
System.out.println("构造方法");
}
public static LoggerDefaultInit getInstance() {
if (s == null) {
// 这里可能被其他线程插入,并抢先实例化Singleton
synchronized (LoggerDefaultInit.class) {
if (s == null) {
try {
// 将问题极端化
Thread.sleep(50);
} catch (InterruptedException e) {
}
s = new LoggerDefaultInit();
}
}
}
return s;
}
/**
* 是否显示 Log
*
* @param isShow 编译debug展示
*/
public void init(boolean isShow) {
FormatStrategy formatStrategy =
PrettyFormatStrategy.newBuilder().showThreadInfo(false).methodCount(1).tag("RMLog").build();
Logger.addLogAdapter(new AndroidLogAdapter(formatStrategy) {
@Override
public boolean isLoggable(int priority, String tag) {
return isShow;
}
});
}
}
... ...
package com.wd.base.log;
import static com.wd.base.log.Logger.ASSERT;
import static com.wd.base.log.Logger.DEBUG;
import static com.wd.base.log.Logger.ERROR;
import static com.wd.base.log.Logger.INFO;
import static com.wd.base.log.Logger.VERBOSE;
import static com.wd.base.log.Logger.WARN;
import static com.wd.base.log.Utils.checkNotNull;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
class LoggerPrinter implements Printer {
/**
* It is used for json pretty print
*/
private static final int JSON_INDENT = 2;
/**
* Provides one-time used tag for the log message
*/
private final ThreadLocal<String> localTag = new ThreadLocal<>();
private final List<LogAdapter> logAdapters = new ArrayList<>();
@Override
public Printer t(String tag) {
if (tag != null) {
localTag.set(tag);
}
return this;
}
@Override
public void d(@NonNull String message, @Nullable Object... args) {
log(DEBUG, null, message, args);
}
@Override
public void d(@Nullable Object object) {
log(DEBUG, null, Utils.toString(object));
}
@Override
public void e(@NonNull String message, @Nullable Object... args) {
e(null, message, args);
}
@Override
public void e(@Nullable Throwable throwable, @NonNull String message, @Nullable Object... args) {
log(ERROR, throwable, message, args);
}
@Override
public void w(@NonNull String message, @Nullable Object... args) {
log(WARN, null, message, args);
}
@Override
public void i(@NonNull String message, @Nullable Object... args) {
log(INFO, null, message, args);
}
@Override
public void v(@NonNull String message, @Nullable Object... args) {
log(VERBOSE, null, message, args);
}
@Override
public void wtf(@NonNull String message, @Nullable Object... args) {
log(ASSERT, null, message, args);
}
@Override
public void json(@Nullable String json) {
if (Utils.isEmpty(json)) {
d("Empty/Null json content");
return;
}
try {
json = json.trim();
if (json.startsWith("{")) {
JSONObject jsonObject = new JSONObject(json);
String message = jsonObject.toString(JSON_INDENT);
d(message);
return;
}
if (json.startsWith("[")) {
JSONArray jsonArray = new JSONArray(json);
String message = jsonArray.toString(JSON_INDENT);
d(message);
return;
}
e("Invalid Json");
} catch (JSONException e) {
e("Invalid Json");
}
}
@Override
public void xml(@Nullable String xml) {
if (Utils.isEmpty(xml)) {
d("Empty/Null xml content");
return;
}
try {
Source xmlInput = new StreamSource(new StringReader(xml));
StreamResult xmlOutput = new StreamResult(new StringWriter());
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(xmlInput, xmlOutput);
d(xmlOutput.getWriter().toString().replaceFirst(">", ">\n"));
} catch (TransformerException e) {
e("Invalid xml");
}
}
@Override
public synchronized void log(int priority, @Nullable String tag, @Nullable String message,
@Nullable Throwable throwable) {
if (throwable != null && message != null) {
message += " : " + Utils.getStackTraceString(throwable);
}
if (throwable != null && message == null) {
message = Utils.getStackTraceString(throwable);
}
if (Utils.isEmpty(message)) {
message = "Empty/NULL log message";
}
for (LogAdapter adapter : logAdapters) {
if (adapter.isLoggable(priority, tag)) {
adapter.log(priority, tag, message);
}
}
}
@Override
public void clearLogAdapters() {
logAdapters.clear();
}
@Override
public void addAdapter(@NonNull LogAdapter adapter) {
logAdapters.add(checkNotNull(adapter));
}
/**
* This method is synchronized in order to avoid messy of logs' order.
*/
private synchronized void log(int priority, @Nullable Throwable throwable, @NonNull String msg,
@Nullable Object... args) {
checkNotNull(msg);
String tag = getTag();
String message = createMessage(msg, args);
log(priority, tag, message, throwable);
}
/**
* @return the appropriate tag based on local or global
*/
@Nullable
private String getTag() {
String tag = localTag.get();
if (tag != null) {
localTag.remove();
return tag;
}
return null;
}
@NonNull
private String createMessage(@NonNull String message, @Nullable Object... args) {
return args == null || args.length == 0 ? message : String.format(message, args);
}
}
... ...
package com.wd.base.log;
import static com.wd.base.log.Utils.checkNotNull;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Draws borders around the given log message along with additional information such as :
* <ul>
* <li>Thread information</li>
* <li>Method stack trace</li>
* </ul>
*
* <pre>
* ┌──────────────────────────
* │ Method stack history
* ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
* │ Thread information
* ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
* │ Log message
* └──────────────────────────
* </pre>
*/
public class PrettyFormatStrategy implements FormatStrategy {
/**
* Android's max limit for a log entry is ~4076 bytes,
* so 4000 bytes is used as chunk size since default charset
* is UTF-8
*/
private static final int CHUNK_SIZE = 4000;
/**
* The minimum stack trace index, starts at this class after two native calls.
*/
private static final int MIN_STACK_OFFSET = 5;
/**
* Drawing toolbox
*/
private static final char TOP_LEFT_CORNER = '┌';
private static final char BOTTOM_LEFT_CORNER = '└';
private static final char MIDDLE_CORNER = '├';
private static final char HORIZONTAL_LINE = '│';
private static final String DOUBLE_DIVIDER = "────────────────────────────────────────────────────────";
private static final String SINGLE_DIVIDER = "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄";
private static final String TOP_BORDER = TOP_LEFT_CORNER + DOUBLE_DIVIDER + DOUBLE_DIVIDER;
private static final String BOTTOM_BORDER = BOTTOM_LEFT_CORNER + DOUBLE_DIVIDER + DOUBLE_DIVIDER;
private static final String MIDDLE_BORDER = MIDDLE_CORNER + SINGLE_DIVIDER + SINGLE_DIVIDER;
private final int methodCount;
private final int methodOffset;
private final boolean showThreadInfo;
@NonNull
private final LogStrategy logStrategy;
@Nullable
private final String tag;
private PrettyFormatStrategy(@NonNull PrettyFormatStrategy.Builder builder) {
checkNotNull(builder);
methodCount = builder.methodCount;
methodOffset = builder.methodOffset;
showThreadInfo = builder.showThreadInfo;
logStrategy = builder.logStrategy;
tag = builder.tag;
}
@NonNull
public static PrettyFormatStrategy.Builder newBuilder() {
return new PrettyFormatStrategy.Builder();
}
@Override
public void log(int priority, @Nullable String onceOnlyTag, @NonNull String message) {
checkNotNull(message);
String tag = formatTag(onceOnlyTag);
logTopBorder(priority, tag);
logHeaderContent(priority, tag, methodCount);
// get bytes of message with system's default charset (which is UTF-8 for Android)
byte[] bytes = message.getBytes();
int length = bytes.length;
if (length <= CHUNK_SIZE) {
if (methodCount > 0) {
logDivider(priority, tag);
}
logContent(priority, tag, message);
logBottomBorder(priority, tag);
return;
}
if (methodCount > 0) {
logDivider(priority, tag);
}
for (int i = 0; i < length; i += CHUNK_SIZE) {
int count = Math.min(length - i, CHUNK_SIZE);
// create a new String with system's default charset (which is UTF-8 for Android)
logContent(priority, tag, new String(bytes, i, count));
}
logBottomBorder(priority, tag);
}
private void logTopBorder(int logType, @Nullable String tag) {
logChunk(logType, tag, TOP_BORDER);
}
@SuppressWarnings("StringBufferReplaceableByString")
private void logHeaderContent(int logType, @Nullable String tag, int methodCount) {
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
if (showThreadInfo) {
logChunk(logType, tag, HORIZONTAL_LINE + " Thread: " + Thread.currentThread().getName());
logDivider(logType, tag);
}
String level = "";
int stackOffset = getStackOffset(trace) + methodOffset;
// corresponding method count with the current stack may exceeds the stack trace. Trims the count
if (methodCount + stackOffset > trace.length) {
methodCount = trace.length - stackOffset - 1;
}
for (int i = methodCount; i > 0; i--) {
int stackIndex = i + stackOffset;
if (stackIndex >= trace.length) {
continue;
}
StringBuilder builder = new StringBuilder();
builder.append(HORIZONTAL_LINE)
.append(' ')
.append(level)
.append(getSimpleClassName(trace[stackIndex].getClassName()))
.append(".")
.append(trace[stackIndex].getMethodName())
.append(" ")
.append(" (")
.append(trace[stackIndex].getFileName())
.append(":")
.append(trace[stackIndex].getLineNumber())
.append(")");
level += " ";
logChunk(logType, tag, builder.toString());
}
}
private void logBottomBorder(int logType, @Nullable String tag) {
logChunk(logType, tag, BOTTOM_BORDER);
}
private void logDivider(int logType, @Nullable String tag) {
logChunk(logType, tag, MIDDLE_BORDER);
}
private void logContent(int logType, @Nullable String tag, @NonNull String chunk) {
checkNotNull(chunk);
String[] lines = chunk.split(System.getProperty("line.separator"));
for (String line : lines) {
logChunk(logType, tag, HORIZONTAL_LINE + " " + line);
}
}
private void logChunk(int priority, @Nullable String tag, @NonNull String chunk) {
checkNotNull(chunk);
logStrategy.log(priority, tag, chunk);
}
private String getSimpleClassName(@NonNull String name) {
checkNotNull(name);
int lastIndex = name.lastIndexOf(".");
return name.substring(lastIndex + 1);
}
/**
* Determines the starting index of the stack trace, after method calls made by this class.
*
* @param trace the stack trace
* @return the stack offset
*/
private int getStackOffset(@NonNull StackTraceElement[] trace) {
checkNotNull(trace);
for (int i = MIN_STACK_OFFSET; i < trace.length; i++) {
StackTraceElement e = trace[i];
String name = e.getClassName();
if (!name.equals(LoggerPrinter.class.getName()) && !name.equals(Logger.class.getName())) {
return --i;
}
}
return -1;
}
@Nullable
private String formatTag(@Nullable String tag) {
if (!Utils.isEmpty(tag) && !Utils.equals(this.tag, tag)) {
return this.tag + "-" + tag;
}
return this.tag;
}
public static class Builder {
int methodCount = 2;
int methodOffset = 0;
boolean showThreadInfo = true;
@Nullable
LogStrategy logStrategy;
@Nullable
String tag = "PRETTY_LOGGER";
private Builder() {
}
@NonNull
public PrettyFormatStrategy.Builder methodCount(int val) {
methodCount = val;
return this;
}
@NonNull
public PrettyFormatStrategy.Builder methodOffset(int val) {
methodOffset = val;
return this;
}
@NonNull
public PrettyFormatStrategy.Builder showThreadInfo(boolean val) {
showThreadInfo = val;
return this;
}
@NonNull
public PrettyFormatStrategy.Builder logStrategy(@Nullable LogStrategy val) {
logStrategy = val;
return this;
}
@NonNull
public PrettyFormatStrategy.Builder tag(@Nullable String tag) {
this.tag = tag;
return this;
}
@NonNull
public PrettyFormatStrategy build() {
if (logStrategy == null) {
logStrategy = new LogcatLogStrategy();
}
return new PrettyFormatStrategy(this);
}
}
}
... ...
package com.wd.base.log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* A proxy interface to enable additional operations.
* Contains all possible Log message usages.
*/
public interface Printer {
void addAdapter(@NonNull LogAdapter adapter);
Printer t(@Nullable String tag);
void d(@NonNull String message, @Nullable Object... args);
void d(@Nullable Object object);
void e(@NonNull String message, @Nullable Object... args);
void e(@Nullable Throwable throwable, @NonNull String message, @Nullable Object... args);
void w(@NonNull String message, @Nullable Object... args);
void i(@NonNull String message, @Nullable Object... args);
void v(@NonNull String message, @Nullable Object... args);
void wtf(@NonNull String message, @Nullable Object... args);
/**
* Formats the given json content and print it
*/
void json(@Nullable String json);
/**
* Formats the given xml content and print it
*/
void xml(@Nullable String xml);
void log(int priority, @Nullable String tag, @Nullable String message, @Nullable Throwable throwable);
void clearLogAdapters();
}
... ...
package com.wd.base.log;
import static com.wd.base.log.Logger.ASSERT;
import static com.wd.base.log.Logger.DEBUG;
import static com.wd.base.log.Logger.ERROR;
import static com.wd.base.log.Logger.INFO;
import static com.wd.base.log.Logger.VERBOSE;
import static com.wd.base.log.Logger.WARN;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.UnknownHostException;
import java.util.Arrays;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Provides convenient methods to some common operations
*/
final class Utils {
private Utils() {
// Hidden constructor.
}
/**
* Returns true if the string is null or 0-length.
*
* @param str the string to be examined
* @return true if str is null or zero length
*/
static boolean isEmpty(CharSequence str) {
return str == null || str.length() == 0;
}
/**
* Returns true if a and b are equal, including if they are both null.
* <p>
* <i>Note: In platform versions 1.1 and earlier, this method only worked well if
* both the arguments were instances of String.</i>
* </p>
*
* @param a first CharSequence to check
* @param b second CharSequence to check
* @return true if a and b are equal
* <p>
* NOTE: Logic slightly change due to strict policy on CI -
* "Inner assignments should be avoided"
*/
static boolean equals(CharSequence a, CharSequence b) {
if (a == b)
return true;
if (a != null && b != null) {
int length = a.length();
if (length == b.length()) {
if (a instanceof String && b instanceof String) {
return a.equals(b);
} else {
for (int i = 0; i < length; i++) {
if (a.charAt(i) != b.charAt(i))
return false;
}
return true;
}
}
}
return false;
}
/**
* Copied from "android.util.Log.getStackTraceString()" in order to avoid usage of Android stack
* in unit tests.
*
* @return Stack trace in form of String
*/
static String getStackTraceString(Throwable tr) {
if (tr == null) {
return "";
}
// This is to reduce the amount of log spew that apps do in the non-error
// condition of the network being unavailable.
Throwable t = tr;
while (t != null) {
if (t instanceof UnknownHostException) {
return "";
}
t = t.getCause();
}
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
tr.printStackTrace(pw);
pw.flush();
return sw.toString();
}
static String logLevel(int value) {
switch (value) {
case VERBOSE:
return "VERBOSE";
case DEBUG:
return "DEBUG";
case INFO:
return "INFO";
case WARN:
return "WARN";
case ERROR:
return "ERROR";
case ASSERT:
return "ASSERT";
default:
return "UNKNOWN";
}
}
public static String toString(Object object) {
if (object == null) {
return "null";
}
if (!object.getClass().isArray()) {
return object.toString();
}
if (object instanceof boolean[]) {
return Arrays.toString((boolean[]) object);
}
if (object instanceof byte[]) {
return Arrays.toString((byte[]) object);
}
if (object instanceof char[]) {
return Arrays.toString((char[]) object);
}
if (object instanceof short[]) {
return Arrays.toString((short[]) object);
}
if (object instanceof int[]) {
return Arrays.toString((int[]) object);
}
if (object instanceof long[]) {
return Arrays.toString((long[]) object);
}
if (object instanceof float[]) {
return Arrays.toString((float[]) object);
}
if (object instanceof double[]) {
return Arrays.toString((double[]) object);
}
if (object instanceof Object[]) {
return Arrays.deepToString((Object[]) object);
}
return "Couldn't find a correct type for the object";
}
@NonNull
static <T> T checkNotNull(@Nullable final T obj) {
if (obj == null) {
throw new NullPointerException();
}
return obj;
}
}
... ...
/*
* Copyright (c) Wondertek Technologies Co., Ltd. 2019-2020. All rights reserved.
*/
package com.wd.base.log.wheat;
import java.io.FileNotFoundException;
import java.net.BindException;
import java.net.SocketTimeoutException;
import java.security.acl.NotOwnerException;
import java.util.ConcurrentModificationException;
import java.util.MissingResourceException;
import java.util.jar.JarException;
import org.json.JSONException;
import android.database.SQLException;
import android.util.Log;
/**
* <日志工具类>
*
* @author wangnaiwen
* @version [V1.0.0.0, 2020/5/16]
* @since V1.0.0.0
*/
final class Logger {
/**
* 播放模块统一日志标签
*/
public static final String DEFAULT_TAG = "<WHEAT>|";
/**
* 播放模块统一日志标签
*/
public static final String PLAYER_TAG = "<PLAYER>|";
/**
* 播放模块统一日志标签
*/
public static final String NETWORK_TAG = "<NETWORK>|";
private static int mLogLevel = Log.DEBUG;
private Logger() {
}
public static void setLogLevel(int level) {
mLogLevel = level;
}
public static void d(String tag, Object message) {
if (mLogLevel <= Log.DEBUG) {
printLog(tag, message, Log.DEBUG);
}
}
public static void i(String tag, Object message) {
if (mLogLevel <= Log.INFO) {
printLog(tag, message, Log.INFO);
}
}
public static void w(String tag, Object message) {
if (mLogLevel <= Log.WARN) {
printLog(tag, message, Log.WARN);
}
}
public static void e(String tag, Object message) {
if (mLogLevel <= Log.ERROR) {
printLog(tag, message, Log.ERROR);
}
}
public static void d(String tag, Object message, Throwable throwable) {
if (mLogLevel <= Log.DEBUG) {
String newMessage = message + ":" + checkSensitiveException(throwable);
printLog(tag, newMessage, Log.DEBUG);
}
}
public static void i(String tag, Object message, Throwable throwable) {
if (mLogLevel <= Log.INFO) {
String newMessage = message + ":" + checkSensitiveException(throwable);
printLog(tag, newMessage, Log.INFO);
}
}
public static void w(String tag, Object message, Throwable throwable) {
if (mLogLevel <= Log.WARN) {
String newMessage = message + ":" + checkSensitiveException(throwable);
printLog(tag, newMessage, Log.WARN);
}
}
public static void e(String tag, Object message, Throwable throwable) {
if (mLogLevel <= Log.ERROR) {
String newMessage = message + ":" + checkSensitiveException(throwable);
printLog(tag, newMessage, Log.ERROR);
}
}
private static String checkSensitiveException(Object object) {
if (object instanceof FileNotFoundException) {
return "File is not legal ";
} else if (object instanceof ConcurrentModificationException) {
return "Illegal operation";
} else if (object instanceof SQLException) {
return "Sql exception";
} else if (object instanceof JSONException) {
return "Json convert exception";
} else if (object instanceof MissingResourceException) {
return "Resource is missing.";
} else if (object instanceof JarException) {
return "Error occurred while reading or writing a JAR file.";
} else if (object instanceof OutOfMemoryError) {
return "No more memory could be made available.";
} else if (object instanceof StackOverflowError) {
return "Stack overflow occurs because an application recurses too deeply.";
} else if (object instanceof NotOwnerException) {
return "Modification principal is not the owner of the object.";
} else if (object instanceof BindException) {
return "Exception occurred while binding a socket to a local address and port.";
} else {
return object instanceof SocketTimeoutException ? "Socket timeout exception" : null;
}
}
private static void printLog(String tag, Object msg, int level) {
// 日志打印统一出口
String logTag = tag == null ? DEFAULT_TAG : DEFAULT_TAG + tag;
Log.println(level, logTag, String.valueOf(msg));
}
}
... ...
<?xml version="1.0" encoding="utf-8"?>
<resources>
</resources>
\ No newline at end of file
... ...