Parcourir la source

积分墙v1.1.0

zhipeng il y a 3 ans
Parent
commit
db28e9099f
34 fichiers modifiés avec 1045 ajouts et 1675 suppressions
  1. 9 18
      build.gradle
  2. 1 8
      consumer-rules.pro
  3. 0 996
      proguard-dic.txt
  4. 1 29
      proguard-rules.pro
  5. 67 0
      publish.gradle
  6. 1 1
      src/main/AndroidManifest.xml
  7. 7 8
      src/main/java/com/atmob/task/utils/AppTaskEvent.java
  8. 233 233
      src/main/java/com/atmob/task/adapter/AppTaskItemAdapter.java
  9. 124 77
      src/main/java/com/atmob/task/AppTaskView.java
  10. 1 1
      src/main/java/com/atmob/task/bean/AppTaskBean.java
  11. 46 0
      src/main/java/com/atmob/rewardtask/bean/AppTaskControlResponse.java
  12. 1 5
      src/main/java/com/atmob/task/bean/AppTaskDataResponse.java
  13. 1 1
      src/main/java/com/atmob/task/bean/AppTaskDownloadWrapper.java
  14. 2 6
      src/main/java/com/atmob/task/bean/AppTaskUpdateRequest.java
  15. 1 4
      src/main/java/com/atmob/task/bean/AppTaskUpdateResponse.java
  16. 12 0
      src/main/java/com/atmob/rewardtask/bean/EventRequest.java
  17. 8 8
      src/main/java/com/atmob/task/data/Api.java
  18. 45 0
      src/main/java/com/atmob/rewardtask/network/BaseHttpObserver.java
  19. 75 0
      src/main/java/com/atmob/rewardtask/network/NetworkClient.java
  20. 47 0
      src/main/java/com/atmob/rewardtask/utils/AppInfoUtils.java
  21. 63 0
      src/main/java/com/atmob/rewardtask/utils/AppTaskHandler.java
  22. 3 3
      src/main/java/com/atmob/task/utils/InstallFaultToleranceUtils.java
  23. 47 0
      src/main/java/com/atmob/rewardtask/utils/MMKVUtils.java
  24. 5 5
      src/main/java/com/atmob/task/utils/RetrofitDownloader.java
  25. 233 0
      src/main/java/com/atmob/rewardtask/view/NormalProgressBar.java
  26. 1 1
      src/main/java/com/atmob/task/view/TwinklingRecyclerView.java
  27. 0 24
      src/main/java/com/atmob/task/AppTaskAdapter.java
  28. 0 46
      src/main/java/com/atmob/task/bean/AdAppInfoData.java
  29. 0 26
      src/main/java/com/atmob/task/bean/AppTaskControlResponse.java
  30. 0 15
      src/main/java/com/atmob/task/data/LocalData.java
  31. 0 9
      src/main/java/com/atmob/task/data/NetworkClient.java
  32. 0 151
      src/main/java/com/atmob/task/utils/ATLog.java
  33. BIN
      src/main/res/drawable-xxhdpi/atmob_default_icon.png
  34. 11 0
      src/main/res/values/attrs.xml

+ 9 - 18
build.gradle

@@ -1,22 +1,21 @@
 plugins {
     id 'com.android.library'
 }
+apply from: 'publish.gradle'
 
 android {
-    compileSdkVersion 30
+    compileSdkVersion 32
 
     defaultConfig {
         minSdkVersion 21
-        targetSdkVersion 30
-        versionCode 100
-        versionName "1.0.0"
+        targetSdkVersion 32
 
         consumerProguardFiles "consumer-rules.pro"
     }
 
     buildTypes {
         release {
-            minifyEnabled true
+            minifyEnabled false
             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
         }
     }
@@ -24,20 +23,12 @@ android {
         sourceCompatibility JavaVersion.VERSION_1_8
         targetCompatibility JavaVersion.VERSION_1_8
     }
-
-    libraryVariants.all { variant ->
-        variant.outputs.all {
-            def fileName = "AtmobTask" +
-                    "-v${defaultConfig.versionName}" +
-                    "-${variant.buildType.name}" +
-                    ".aar"
-            outputFileName = fileName
-        }
-    }
 }
 
 dependencies {
-    implementation 'androidx.recyclerview:recyclerview:1.2.1'
-    compileOnly project(':atmob-ad')
-    compileOnly project(':group-ad')
+    compileOnly "extra.common:core:1.0.0"
+    compileOnly 'androidx.annotation:annotation:+'
+    compileOnly 'androidx.recyclerview:recyclerview:+'
+    compileOnly 'com.google.code.gson:gson:2.8.7'
+    compileOnly 'com.github.bumptech.glide:glide:+'
 }

+ 1 - 8
consumer-rules.pro

@@ -1,8 +1 @@
--keep class com.atmob.task.AppTaskAdapter{*;}
--keep class com.atmob.task.AppTaskView{
-    public <methods>;
-}
--keep class com.atmob.task.bean.AppTaskBean$*{*;}
--keep class com.atmob.task.bean.AppTaskBean{*;}
--keep class com.atmob.task.bean.**{*;}
--keep class com.atmob.task.AppTaskView$*{*;}
+-keep class com.atmob.rewardtask.bean.**{*;}

+ 0 - 996
proguard-dic.txt

@@ -1,996 +0,0 @@
-ᐝ
-ι
-ʿ
-ᐧ
-ᐨ
-・
-ﹳ
-゙
-ᴵ
-ᵎ
-ᵔ
-ᵢ
-ⁱ
-ﹶ
-ﹺ
-ー
-ᐠ
-ᐣ
-ᐩ
-ᑊ
-ᕀ
-ᵕ
-ᵣ
-יִ
-יּ
-ᐟ
-ᐡ
-ᐪ
-ᒽ
-ᔇ
-ᔈ
-ᗮ
-ᴶ
-ᴸ
-ᵀ
-ᵋ
-ᵗ
-゚
-เ
-Ꭵ
-ᐤ
-ᒡ
-ᒢ
-ᖮ
-ᵌ
-ᵓ
-ᵙ
-ᵛ
-ᵥ
-ﯨ
-ﹴ
-ﹸ
-ﹾ
-৲
-ᐢ
-ᒻ
-ᔅ
-ᔉ
-ᔊ
-ᔋ
-ᕁ
-ᕑ
-ᕽ
-ᘁ
-ᵄ
-ᵞ
-ᵧ
-וּ
-וֹ
-ﹲ
-ﹷ
-ﹻ
-ﹼ
-ﺑ
-ﻧ
-ᑉ
-ᑋ
-ᑦ
-ᒾ
-ᓪ
-ᓫ
-ᔾ
-ᕐ
-ᕝ
-ᵒ
-ᵘ
-ᵤ
-ⁿ
-Ⅰ
-ⅰ
-丶
-ﭔ
-ﭠ
-ﯦ
-ﯩ
-ﯾ
-ﹰ
-ﺗ
-ﻳ
-_
-ニ
-า
-ᐥ
-ᒃ
-ᓒ
-ᕪ
-ᙆ
-ᴊ
-ᴷ
-ᵏ
-ⅼ
-ﭘ
-ﺒ
-ﺛ
-ﺩ
-ﻨ
-ィ
-ɿ
-ง
-ว
-ᐦ
-ᒄ
-ᒼ
-ᓑ
-ᔆ
-ᴖ
-ᴬ
-ᴱ
-ᴲ
-ᴾ
-ᵁ
-ᵃ
-ᵅ
-ᵉ
-ᵊ
-ᵡ
-ᵪ
-ḯ
-Ị
-ị
-ゝ
-ー
-ヽ
-一
-גּ
-זּ
-נּ
-רּ
-ﭕ
-ﭜ
-ﭡ
-ﭤ
-ﯧ
-ﯿ
-ﹹ
-ﹿ
-ﺘ
-ﺫ
-ﻴ
-ſ
-৳
-ฯ
-ๅ
-ᐞ
-ᓐ
-ᓭ
-ᓯ
-ᓱ
-ᓴ
-ᔥ
-ᖦ
-ᴗ
-ᴴ
-ᴿ
-ᵇ
-ᵖ
-ᵟ
-ḷ
-ṙ
-ṛ
-ỉ
-ἰ
-ἱ
-ὶ
-ί
-ῐ
-ῑ
-‿
-⁀
-⁔
-丨
-氵
-灬
-ﭙ
-ﮂ
-ﮄ
-ﹽ
-ﺋ
-ﺜ
-ﻟ
-ノ
-ઽ
-ເ
-ᓰ
-ᓲ
-ᓵ
-ᔿ
-ᕻ
-ᴄ
-ᴐ
-ᴛ
-ᴺ
-ᵈ
-ᵑ
-ᵨ
-Ḯ
-Ἰ
-Ἱ
-Ῐ
-Ῑ
-Ὶ
-Ί
-ℴ
-ⅹ
-ⅽ
-ײַ
-ﬧ
-דּ
-ﭝ
-ﭥ
-ﮆ
-ﹱ
-ﺀ
-ﺪ
-ﺭ
-j
-ュ
-ა
-ი
-Ꮀ
-Ꮮ
-ᒣ
-ᒥ
-ᒧ
-ᒪ
-ᓳ
-ᘄ
-ᴠ
-ᴰ
-ᴻ
-ᵠ
-ᵩ
-ḻ
-ṟ
-ẛ
-Ỉ
-ῒ
-ΐ
-Ⅼ
-ⅴ
-ィ
-ךּ
-כּ
-ﭨ
-ﮢ
-ﺌ
-ﺬ
-ﺯ
-ﻣ
-J
-L
-ァ
-イ
-フ
-ヘ
-ণ
-จ
-แ
-ๆ
-Ꭻ
-Ꮁ
-Ꮣ
-ᒦ
-ᒨ
-ᒫ
-ᖟ
-ᘇ
-ᙇ
-ᴧ
-ᴮ
-ᴳ
-ᴼ
-ᵍ
-ᵐ
-ᵚ
-ᵝ
-ᵦ
-ẋ
-ẍ
-〳
-〵
-ノ
-亅
-亠
-冫
-לּ
-ﮃ
-ﮅ
-ﱠ
-ﱢ
-ﺮ
-ﻠ
-ﻩ
-c
-ゥ
-ェ
-テ
-ナ
-ン
-Ŀ
-ধ
-ร
-ใ
-Ꭲ
-Ꭸ
-Ꮠ
-ᐜ
-ᒩ
-ᓶ
-ᓷ
-ᓸ
-ᓹ
-ᓼ
-ᓽ
-ᔀ
-ᔁ
-ᔄ
-ᔨ
-ᔭ
-ᖕ
-ᘆ
-ᴋ
-ᴹ
-ᴽ
-ḟ
-Ḷ
-ḹ
-ḽ
-ṝ
-ṿ
-ἲ
-ἳ
-ἴ
-ἵ
-ῖ
-ℐ
-〱
-丿
-בּ
-ﭩ
-ﮇ
-ﮊ
-ﮞ
-ﮣ
-ﺰ
-ﻪ
-ッ
-シ
-ソ
-ト
-ユ
-ο
-ऽ
-บ
-ย
-ะ
-າ
-ᐳ
-ᐸ
-ᒉ
-ᒋ
-ᒍ
-ᒐ
-ᓓ
-ᓕ
-ᓗ
-ᓚ
-ᓺ
-ᓻ
-ᓾ
-ᓿ
-ᔂ
-ᔃ
-ᔦ
-ᔩ
-ᔪ
-ᔮ
-ᘤ
-ᚐ
-ᴈ
-ᴏ
-ᴢ
-ᴣ
-ᵂ
-Ḭ
-ḭ
-ṫ
-ṭ
-Ẏ
-ẗ
-Ἲ
-Ἳ
-Ἴ
-Ἵ
-ⅈ
-冖
-הּ
-כֿ
-ﮈ
-ﺓ
-ﻤ
-ﻥ
-f
-i
-t
-v
-ャ
-エ
-コ
-ヒ
-ミ
-リ
-レ
-र
-ঌ
-গ
-ঢ
-ব
-শ
-ঽ
-ก
-კ
-ᐯ
-ᐴ
-ᐹ
-ᒌ
-ᒎ
-ᒑ
-ᒬ
-ᒭ
-ᒮ
-ᒯ
-ᒲ
-ᒳ
-ᒶ
-ᒷ
-ᒺ
-ᓖ
-ᓘ
-ᓛ
-ᔫ
-ᘂ
-ᘢ
-ᚁ
-ᚆ
-ᴒ
-ᴫ
-Ḻ
-Ṫ
-Ỳ
-Ỵ
-ἶ
-ἷ
-ῗ
-ℓ
-Ⅴ
-ゞ
-イ
-忄
-אּ
-ﮋ
-ﺏ
-ﺔ
-ﺣ
-ﻡ
-u
-z
-ォ
-ョ
-ア
-マ
-ラ
-ワ
-ट
-ও
-চ
-দ
-ন
-প
-য
-র
-হ
-ৰ
-ค
-ฅ
-ถ
-ท
-ป
-ผ
-ภ
-ล
-ห
-โ
-ไ
-Ⴡ
-ძ
-ᐵ
-ᑈ
-ᒏ
-ᒰ
-ᒱ
-ᒴ
-ᒵ
-ᒸ
-ᒹ
-ᓙ
-ᔬ
-ᖧ
-ᖨ
-ᖪ
-ᖬ
-ᖽ
-ᖾ
-ᖿ
-ᗁ
-ᘅ
-ᘣ
-ᘦ
-ᘧ
-ᴉ
-ᴘ
-ᴝ
-ᴦ
-ᴩ
-ᴭ
-Ṭ
-ṯ
-ẏ
-ẓ
-ọ
-ỵ
-Ἶ
-Ἷ
-ℷ
-Ⅱ
-ⅱ
-々
-ぃ
-ァ
-ッ
-ヾ
-乀
-宀
-ﬥ
-צּ
-בֿ
-ﭒ
-ﭞ
-ﺕ
-ﺟ
-ﺧ
-ﻋ
-ﻌ
-ﻢ
-F
-I
-l
-n
-r
-s
-ヲ
-ウ
-キ
-ク
-ケ
-ス
-チ
-ハ
-モ
-п
-ऱ
-এ
-খ
-ঘ
-ষ
-ঢ়
-ฑ
-ต
-น
-ม
-อ
-ງ
-ე
-პ
-Ꮧ
-Ꮭ
-ᐱ
-ᓮ
-ᔱ
-ᔲ
-ᔹ
-ᔺ
-ᔽ
-ᕂ
-ᕃ
-ᕄ
-ᕆ
-ᖅ
-ᖩ
-ᖫ
-ᖭ
-ᖸ
-ᖺ
-ᗀ
-ᘥ
-ᵆ
-Ḟ
-Ḹ
-Ḽ
-Ṿ
-Ὑ
-Ῠ
-Ῡ
-Ὺ
-Ύ
-K
-Ⅽ
-Ↄ
-く
-っ
-へ
-ゥ
-ト
-リ
-ヮ
-ヶ
-丫
-乁
-爫
-ﬤ
-טּ
-סּ
-ףּ
-ﭖ
-ﭴ
-ﭸ
-ﮉ
-ﮌ
-ﮐ
-ﱟ
-ﱡ
-ﺙ
-ﻏ
-ﻐ
-ﻛ
-k
-ヌ
-メ

+ 1 - 29
proguard-rules.pro

@@ -19,32 +19,4 @@
 # If you keep the line number information, uncomment this to
 # hide the original source file name.
 #-renamesourcefileattribute SourceFile
--packageobfuscationdictionary proguard-dic.txt
--obfuscationdictionary proguard-dic.txt
--classobfuscationdictionary proguard-dic.txt
-
--optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
--optimizationpasses 5
--allowaccessmodification
-
--dontusemixedcaseclassnames
--dontskipnonpubliclibraryclasses
--verbose
--dontwarn
--dontusemixedcaseclassnames
--dontskipnonpubliclibraryclasses
--dontskipnonpubliclibraryclassmembers
--dontpreverify
--verbose
--keepattributes *Annotation*,InnerClasses
--keepattributes Signature
--keepattributes SourceFile,LineNumberTable
-
--keep class com.atmob.task.AppTaskAdapter{*;}
--keep class com.atmob.task.AppTaskView{
-    public <methods>;
-}
--keep class com.atmob.task.bean.AppTaskBean$*{*;}
--keep class com.atmob.task.bean.AppTaskBean{*;}
--keep class com.atmob.task.bean.**{*;}
--keep class com.atmob.task.AppTaskView$*{*;}
+-keep class com.atmob.rewardtask.bean.**{*;}

+ 67 - 0
publish.gradle

@@ -0,0 +1,67 @@
+apply plugin: 'maven'
+apply plugin: 'signing'
+
+signing {
+    required { hasProperty("release") && gradle.taskGraph.hasTask("uploadArchives") }
+    sign configurations.archives
+}
+
+boolean release = false
+
+String suffix = "-SNAPSHOT"
+if (release) suffix = ""
+
+String ver = "1.1.0" + suffix
+
+String publishUrl = ver.endsWith("-SNAPSHOT") ? "http://192.168.10.99:8081/repository/android-snapshot/"
+        : "http://192.168.10.99:8081/repository/android-release/"
+
+uploadArchives {
+    configuration = configurations.archives
+    repositories.mavenDeployer {
+        beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
+
+        repository(url: "${atmob_maven_url}/repository/android-release/") {
+            //仓库地址
+            authentication(userName: "$atmob_maven_username",   //用户名
+                    password: "$atmob_maven_password")    //密码
+        }
+
+        snapshotRepository(url: "${atmob_maven_url}/repository/android-snapshot/") {
+            //仓库地址
+            authentication(userName: "$atmob_maven_username",   //用户名
+                    password: "$atmob_maven_password")    //密码
+        }
+
+        pom.project {
+            name 'integral'    //仓库命名
+            packaging 'aar'    //打包类型
+            description '积分墙模块'     //描述
+            url publishUrl  //仓库地址
+            groupId "plus.ad"    //仓库分组(最好用自己的包名)
+            artifactId "integral"     //项目名称(随意)
+            version ver
+        }
+    }
+}
+
+task androidJavadocs(type: Javadoc) {
+    source = android.sourceSets.main.java.sourceFiles
+    ext.androidJar = "${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar"
+    classpath += files(ext.androidJar)
+}
+
+task androidJavadocsJar(type: Jar) {
+    getArchiveClassifier().set("javadoc")
+    from androidJavadocs.destinationDir
+}
+
+task androidSourcesJar(type: Jar) {
+    getArchiveClassifier().set("sources")
+    from android.sourceSets.main.java.srcDirs
+}
+
+artifacts {
+    archives androidSourcesJar
+    archives androidJavadocsJar
+}

+ 1 - 1
src/main/AndroidManifest.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.atmob.task">
+    package="com.atmob.rewardtask">
 
 </manifest>

+ 7 - 8
src/main/java/com/atmob/task/utils/AppTaskEvent.java

@@ -1,13 +1,14 @@
-package com.atmob.task.utils;
+package com.atmob.rewardtask;
 
 import androidx.annotation.IntDef;
 
-import com.atmob.http.BaseHttpObserver;
-import com.atmob.request.EventRequest;
-import com.atmob.task.data.NetworkClient;
-import com.atmob.utils.RxSchedulersUtils;
+import com.atmob.rewardtask.bean.EventRequest;
+import com.atmob.rewardtask.network.BaseHttpObserver;
+import com.atmob.rewardtask.network.NetworkClient;
 
+import atmob.io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
 import atmob.io.reactivex.rxjava3.disposables.Disposable;
+import atmob.io.reactivex.rxjava3.schedulers.Schedulers;
 
 public class AppTaskEvent {
 
@@ -46,7 +47,7 @@ public class AppTaskEvent {
 
     public static void report(@ID int eventId) {
         NetworkClient.api().eventReport(new EventRequest(String.valueOf(eventId)))
-                .compose(RxSchedulersUtils.observableIOOnly())
+                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                 .subscribe(new BaseHttpObserver<Object>() {
 
                     @Override
@@ -56,12 +57,10 @@ public class AppTaskEvent {
 
                     @Override
                     public void onSuccess(Object data) {
-                        ATLog.d("AppTaskEvent", "report success, eventId ==> " + eventId);
                     }
 
                     @Override
                     public void onFailed(int code, String msg) {
-                        ATLog.d("AppTaskEvent", "report failed, eventId ==> " + eventId);
                     }
                 });
     }

+ 233 - 233
src/main/java/com/atmob/task/adapter/AppTaskItemAdapter.java

@@ -1,37 +1,36 @@
-package com.atmob.task.adapter;
+package com.atmob.rewardtask;
 
 import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.text.TextUtils;
+import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
 import android.widget.Toast;
 
+import androidx.annotation.IntegerRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.recyclerview.widget.AsyncListDiffer;
 import androidx.recyclerview.widget.DiffUtil;
 import androidx.recyclerview.widget.RecyclerView;
 
-import com.atmob.http.BaseHttpObserver;
-import com.atmob.manager.HttpFailManager;
-import com.atmob.task.AppTaskAdapter;
-import com.atmob.task.AppTaskView.AppTaskViewHolder;
-import com.atmob.task.bean.AdAppInfoData;
-import com.atmob.task.bean.AppTaskBean;
-import com.atmob.task.bean.AppTaskDownloadWrapper;
-import com.atmob.task.bean.AppTaskUpdateRequest;
-import com.atmob.task.bean.AppTaskUpdateResponse;
-import com.atmob.task.data.LocalData;
-import com.atmob.task.data.NetworkClient;
-import com.atmob.task.utils.ATLog;
-import com.atmob.task.utils.AppTaskEvent;
-import com.atmob.task.utils.InstallFaultToleranceUtils;
-import com.atmob.task.utils.RetrofitDownloader;
-import com.atmob.utils.AppInfoUtils;
-import com.atmob.utils.RxSchedulersUtils;
-import com.atmob.utils.Utils;
+import com.atmob.rewardtask.bean.AppTaskBean;
+import com.atmob.rewardtask.bean.AppTaskDownloadWrapper;
+import com.atmob.rewardtask.utils.AppInfoUtils;
+import com.atmob.rewardtask.utils.InstallFaultToleranceUtils;
+import com.atmob.rewardtask.utils.RetrofitDownloader;
+import com.atmob.rewardtask.view.NormalProgressBar;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.RequestBuilder;
+import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
+import com.bumptech.glide.request.RequestOptions;
+import com.ishumei.smantifraud.SmAntiFraud;
 
 import java.io.File;
 import java.util.ArrayList;
@@ -46,16 +45,15 @@ import atmob.io.reactivex.rxjava3.core.Completable;
 import atmob.io.reactivex.rxjava3.core.CompletableObserver;
 import atmob.io.reactivex.rxjava3.core.Observable;
 import atmob.io.reactivex.rxjava3.core.Observer;
-import atmob.io.reactivex.rxjava3.core.SingleObserver;
 import atmob.io.reactivex.rxjava3.disposables.CompositeDisposable;
 import atmob.io.reactivex.rxjava3.disposables.Disposable;
 import atmob.io.reactivex.rxjava3.schedulers.Schedulers;
 
-public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerView.Adapter<T> {
+public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.AppTaskItemViewHolder> {
 
     private static final String TAG = AppTaskItemAdapter.class.getSimpleName();
 
-    private static final String DIR_PATH = Utils.getContext().getExternalCacheDir().getPath();
+    private static String DIR_PATH;
 
     /**
      * 安装成功后, 是否强制打开
@@ -68,87 +66,62 @@ public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerVie
 
     private final CompositeDisposable compositeDisposable;
 
-    private RecyclerView recyclerView;
+    private final Context context;
 
     private OnItemActionCallback onItemActionCallback;
 
-    private AppTaskAdapter<T> appTaskAdapter;
+    private ViewHolderCreator viewHolderCreator;
 
-    private int maxLength = Integer.MAX_VALUE;
-
-    private List<AppTaskDownloadWrapper> dataCache = Collections.EMPTY_LIST;
-
-    public AppTaskItemAdapter(RecyclerView recyclerView, AppTaskAdapter<T> appTaskAdapter, CompositeDisposable compositeDisposable) {
+    public AppTaskItemAdapter(ViewHolderCreator viewHolderCreator, CompositeDisposable compositeDisposable, Context context) {
+        this.context = context;
+        this.viewHolderCreator = viewHolderCreator;
         this.compositeDisposable = compositeDisposable;
-        this.appTaskAdapter = appTaskAdapter;
-        this.recyclerView = recyclerView;
+        File cacheDir = context.getExternalCacheDir();
+        if (cacheDir == null) {
+            cacheDir = context.getCacheDir();
+        }
+        DIR_PATH = cacheDir.getPath();
     }
 
     @NonNull
     @Override
-    public T onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
-        if (appTaskAdapter == null) {
-            throw new IllegalStateException("appTaskAdapter can't not be null.");
-        }
-        T appTaskViewHolder = appTaskAdapter.onCreateViewHolder(LayoutInflater.from(parent.getContext()), parent);
-        bindClickListener(appTaskViewHolder);
-        return appTaskViewHolder;
-    }
-
-    private void bindClickListener(T appTaskViewHolder) {
-        if (appTaskAdapter == null) {
-            throw new IllegalStateException("appTaskAdapter can't not be null.");
-        }
-        View[] clickViews = appTaskAdapter.getClickViews(appTaskViewHolder);
-        if (clickViews == null || clickViews.length == 0) {
-            return;
-        }
-        View.OnClickListener onClickListener = v -> onAppTaskItemClick((AppTaskDownloadWrapper) v.getTag());
-        for (View clickView : clickViews) {
-            clickView.setOnClickListener(onClickListener);
-        }
+    public AppTaskItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+        AppTaskItemViewHolder appTaskItemViewHolder = viewHolderCreator.onCreateViewHolder(LayoutInflater.from(parent.getContext()), parent);
+        appTaskItemViewHolder.getTriggerBtn().setOnClickListener(v -> {
+            SmAntiFraud.track("onViewItemClick", String.valueOf(v.getId()), null);
+            onAppTaskItemClick((AppTaskDownloadWrapper) v.getTag());
+        });
+        return appTaskItemViewHolder;
     }
 
     @SuppressLint("ResourceType")
     @Override
-    public void onBindViewHolder(@NonNull T holder, int position) {
-        if (appTaskAdapter == null) {
-            throw new IllegalStateException("appTaskAdapter can't not be null.");
-        }
+    public void onBindViewHolder(@NonNull AppTaskItemViewHolder holder, int position) {
         AppTaskDownloadWrapper appTaskDownloadWrapper = asyncListDiffer.getCurrentList().get(position);
-        // download status
-        appTaskAdapter.onDownloadStatusChanged(holder, appTaskDownloadWrapper.isDownloading());
         // app name
-        appTaskAdapter.onRenderAppName(holder, appTaskDownloadWrapper, appTaskDownloadWrapper.getAppName());
+        holder.getAppName().setText(appTaskDownloadWrapper.getAppName());
         // app icon
-        appTaskAdapter.onRenderAppIcon(holder, appTaskDownloadWrapper, appTaskDownloadWrapper.getAppIcon());
-        // click view
-        setTag2ClickViews(holder, appTaskDownloadWrapper);
-        // task status
-        appTaskAdapter.onRenderTaskStatus(holder, appTaskDownloadWrapper, appTaskDownloadWrapper.getTaskStatus());
-        // download progress
-        appTaskAdapter.onRenderDownloadProgress(holder, appTaskDownloadWrapper.getTotal(), appTaskDownloadWrapper.getProgress());
-    }
-
-    private void setTag2ClickViews(T holder, AppTaskDownloadWrapper appTaskDownloadWrapper) {
-        if (appTaskAdapter == null) {
-            throw new IllegalStateException("appTaskAdapter can't not be null.");
-        }
-        View[] clickViews = appTaskAdapter.getClickViews(holder);
-        if (clickViews != null && clickViews.length > 0) {
-            for (View clickView : clickViews) {
-                clickView.setTag(appTaskDownloadWrapper);
-            }
+        RequestBuilder<Drawable> requestBuilder = Glide.with(holder.getAppIcon()).load(appTaskDownloadWrapper.getAppIcon());
+        if (holder.getAppIconConfig().round > 0) {
+            requestBuilder.apply(RequestOptions.bitmapTransform(new RoundedCorners(holder.getAppIconConfig().round)));
         }
+        requestBuilder.placeholder(holder.getAppIconConfig().placeholderResId).into(holder.getAppIcon());
+        // btn related
+        holder.getTriggerBtn().setTag(appTaskDownloadWrapper);
+        holder.getTriggerBtn().setText(holder.getBtnText(appTaskDownloadWrapper.getTaskStatus()));
+        holder.getTriggerBtn().setBackground(holder.getBtnBackground(appTaskDownloadWrapper.getTaskStatus(), appTaskDownloadWrapper.getRewardRatio() > 1));
+        holder.getTriggerBtn().setVisibility(appTaskDownloadWrapper.isDownloading() ? View.GONE : View.VISIBLE);
+        // progress related
+        holder.getProgressBar().setVisibility(appTaskDownloadWrapper.isDownloading() ? View.VISIBLE : View.GONE);
+        holder.getProgressBar().setProgress(appTaskDownloadWrapper.getTotal(), appTaskDownloadWrapper.getProgress());
+        // reward text
+        holder.onRenderReward(appTaskDownloadWrapper.getRewardRatio());
     }
 
     @Override
-    public void onBindViewHolder(@NonNull T holder, int position, @NonNull List<Object> payloads) {
-        if (appTaskAdapter == null) {
-            throw new IllegalStateException("appTaskAdapter can't not be null.");
-        }
+    public void onBindViewHolder(@NonNull AppTaskItemViewHolder holder, int position, @NonNull List<Object> payloads) {
         AppTaskDownloadWrapper appTaskDownloadWrapper = asyncListDiffer.getCurrentList().get(position);
-        setTag2ClickViews(holder, appTaskDownloadWrapper);
+        holder.getTriggerBtn().setTag(appTaskDownloadWrapper);
         if (payloads.size() == 0) {
             onBindViewHolder(holder, position);
         } else {
@@ -159,19 +132,22 @@ public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerVie
                     String key = iterator.next();
                     switch (key) {
                         case "payload_app_name":
-                            appTaskAdapter.onRenderAppName(holder, appTaskDownloadWrapper, bundle.getString(key));
+                            holder.getAppName().setText(bundle.getString(key));
                             break;
                         case "payload_task_status":
-                            appTaskAdapter.onRenderTaskStatus(holder, appTaskDownloadWrapper, bundle.getInt(key));
+                            holder.getTriggerBtn().setText(holder.getBtnText(bundle.getInt(key)));
+                            holder.getTriggerBtn().setBackground(holder.getBtnBackground(bundle.getInt(key), appTaskDownloadWrapper.getRewardRatio() > 1));
                             break;
                         case "payload_downloading":
-                            appTaskAdapter.onDownloadStatusChanged(holder, bundle.getBoolean(key));
+                            holder.getTriggerBtn().setVisibility(bundle.getBoolean(key) ? View.GONE : View.VISIBLE);
+                            holder.getProgressBar().setVisibility(bundle.getBoolean(key) ? View.VISIBLE : View.GONE);
                             break;
                         case "payload_progress":
+                        case "payload_total":
                             if (bundle.get("payload_progress") == null || bundle.get("payload_total") == null) {
                                 break;
                             }
-                            appTaskAdapter.onRenderDownloadProgress(holder, bundle.getLong("payload_total"), bundle.getLong("payload_progress"));
+                            holder.getProgressBar().startProgress(bundle.getLong("payload_total"), bundle.getLong("payload_progress"));
                             iterator.remove();
                             break;
                     }
@@ -193,13 +169,13 @@ public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerVie
             case AppTaskBean.AppTaskStatus.Initial:
             case AppTaskBean.AppTaskStatus.Installed:
                 toOpen(appTaskDownloadWrapper);
-                ATLog.d(TAG, "onAppTaskItemClick: toOpen.");
+                Log.d(TAG, "onAppTaskItemClick: toOpen.");
                 break;
             case AppTaskBean.AppTaskStatus.Opened:
                 if (onItemActionCallback != null) {
                     onItemActionCallback.getReward(appTaskDownloadWrapper);
                 }
-                ATLog.d(TAG, "onAppTaskItemClick: getReward.");
+                Log.d(TAG, "onAppTaskItemClick: getReward.");
                 break;
             case AppTaskBean.AppTaskStatus.Finish:
                 //ignore
@@ -208,53 +184,29 @@ public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerVie
         if (onItemActionCallback != null) {
             onItemActionCallback.onClick(appTaskDownloadWrapper);
         }
-        reportClickEvent(appTaskDownloadWrapper);
-    }
-
-    private void reportClickEvent(AppTaskBean appTaskBean) {
-        switch (appTaskBean.getTaskStatus()) {
-            case AppTaskBean.AppTaskStatus.Finish:
-                break;
-            case AppTaskBean.AppTaskStatus.Initial:
-            case AppTaskBean.AppTaskStatus.Installed:
-                AppTaskEvent.report(AppTaskEvent.ATE_CLICK_ITEM_INITIAL);
-                break;
-            case AppTaskBean.AppTaskStatus.Opened:
-                AppTaskEvent.report(AppTaskEvent.ATE_CLICK_ITEM_REWARD);
-                break;
-        }
     }
 
     private void toOpen(@NonNull AppTaskDownloadWrapper appTaskDownloadWrapper) {
         String appPkgName = appTaskDownloadWrapper.getAppPkgName();
-        if (AppInfoUtils.isExistPackage(Utils.getContext(), appPkgName)) {
+        if (AppInfoUtils.isExistPackage(context, appPkgName)) {
             AppTaskEvent.report(AppTaskEvent.ATE_LAUNCH);
-            AppInfoUtils.launchApp(appPkgName);
-            updateStatus(appTaskDownloadWrapper.getId(), AppTaskBean.AppTaskStatus.Opened);
+            AppInfoUtils.launchApp(context, appPkgName);
+            if (onItemActionCallback != null) {
+                onItemActionCallback.updateStatus(appTaskDownloadWrapper.getId(), AppTaskBean.AppTaskStatus.Opened);
+            }
             removeFromCheckList(appTaskDownloadWrapper.getId());
-            ATLog.d(TAG, "toOpen: app exist, open it.");
+            Log.d(TAG, "toOpen: app exist, open it.");
         } else {
             AppTaskEvent.report(AppTaskEvent.ATE_DOWNLOAD);
             toInstall(appTaskDownloadWrapper);
-            ATLog.d(TAG, "toOpen: app not exist, try to download.");
+            Log.d(TAG, "toOpen: app not exist, try to download.");
         }
     }
 
     private void toInstall(@NonNull AppTaskDownloadWrapper appTaskDownloadWrapper) {
         // first of all, check local apk file is exists
         Observable.just(appTaskDownloadWrapper.getAppPkgName())
-                .map(appPackageName -> {
-                    // this step is check apk file that download by sdk is exists
-                    AdAppInfoData adAppInfoData = LocalData.queryAdAppInfoByPackageName(appPackageName);
-                    if (adAppInfoData == null) {
-                        return new File("");
-                    }
-                    String apkPath = adAppInfoData.getApkPath();
-                    File file = new File(apkPath);
-                    file = file.exists() && file.isFile() ? file : new File("");
-                    ATLog.d(TAG, "toInstall: sdk apk path ==> " + apkPath + ", file available ==> " + (!"".equals(file.getPath())));
-                    return file;
-                })
+                .map(appPackageName -> new File(""))// 去除原有逻辑: 查找SDK安装包(未维护)
                 .map(apkFile -> {
                     // if sdk download file is exist just use it
                     if ("".equals(apkFile.getPath())) {
@@ -263,7 +215,7 @@ public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerVie
                         if (downloadFile.exists() && downloadFile.isFile() && !checkFileOccupy(downloadFile)) {
                             apkFile = downloadFile;
                         }
-                        ATLog.d(TAG, "toInstall: download apk path ==> " + downloadFile.getPath() + ", file available ==> " + (!"".equals(apkFile.getPath())));
+                        Log.d(TAG, "toInstall: download apk path ==> " + downloadFile.getPath() + ", file available ==> " + (!"".equals(apkFile.getPath())));
                     }
                     if ("".equals(apkFile.getPath())) {
                         throw new Exception("none available apk file");
@@ -271,7 +223,7 @@ public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerVie
                         return apkFile;
                     }
                 })
-                .compose(RxSchedulersUtils.observableIO2Main())
+                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                 .subscribe(new Observer<File>() {
                     @Override
                     public void onSubscribe(@atmob.io.reactivex.rxjava3.annotations.NonNull Disposable d) {
@@ -281,10 +233,10 @@ public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerVie
                     @Override
                     public void onNext(@atmob.io.reactivex.rxjava3.annotations.NonNull File file) {
                         // local file exists, install it
-                        InstallFaultToleranceUtils.installApk(Utils.getContext(), file, () -> {
+                        InstallFaultToleranceUtils.installApk(context, file, () -> {
                             AppTaskEvent.report(AppTaskEvent.ATE_DOWNLOAD);
                             toDownload(appTaskDownloadWrapper);
-                            ATLog.d(TAG, "toInstall: apk install failed, try to download");
+                            Log.d(TAG, "toInstall: apk install failed, try to download");
                         });
                         addToCheckList(appTaskDownloadWrapper);
                     }
@@ -294,7 +246,7 @@ public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerVie
                         // local file not exist, try to download
                         AppTaskEvent.report(AppTaskEvent.ATE_DOWNLOAD);
                         toDownload(appTaskDownloadWrapper);
-                        ATLog.d(TAG, "toInstall: None available apk file, try to download, msg ==> " + e.getMessage());
+                        Log.d(TAG, "toInstall: None available apk file, try to download, msg ==> " + e.getMessage());
                     }
 
                     @Override
@@ -312,8 +264,8 @@ public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerVie
                 appTaskDownloadWrapper.setDownloading(true);
                 Bundle bundle = new Bundle();
                 bundle.putBoolean("payload_downloading", true);
-                notifyItem(appTaskDownloadWrapper, bundle);
-                ATLog.d(TAG, "toDownload onStart: download start, task ==> " + appTaskDownloadWrapper);
+                notifyItemChanged(asyncListDiffer.getCurrentList().indexOf(appTaskDownloadWrapper), bundle);
+                Log.d(TAG, "toDownload onStart: download start, task ==> " + appTaskDownloadWrapper);
             }
 
             @Override
@@ -325,105 +277,104 @@ public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerVie
                 bundle.putBoolean("payload_downloading", true);
                 bundle.putLong("payload_progress", progress);
                 bundle.putLong("payload_total", total);
-                notifyItem(appTaskDownloadWrapper, bundle);
+                notifyItemChanged(asyncListDiffer.getCurrentList().indexOf(appTaskDownloadWrapper), bundle);
             }
 
             @Override
             public void onComplete(File file) {
                 appTaskDownloadWrapper.setDownloading(false);
-                InstallFaultToleranceUtils.installApk(Utils.getContext(), file, null);
+                InstallFaultToleranceUtils.installApk(context, file, null);
                 addToCheckList(appTaskDownloadWrapper);
                 Bundle bundle = new Bundle();
                 bundle.putBoolean("payload_downloading", false);
-                notifyItem(appTaskDownloadWrapper, bundle);
-                ATLog.d(TAG, "toDownload onComplete: download complete, task ==> " + appTaskDownloadWrapper);
+                notifyItemChanged(asyncListDiffer.getCurrentList().indexOf(appTaskDownloadWrapper), bundle);
+                Log.d(TAG, "toDownload onComplete: download complete, task ==> " + appTaskDownloadWrapper);
                 AppTaskEvent.report(AppTaskEvent.ATE_DOWNLOAD_SUCCESS);
             }
 
             @Override
             public void onError(String message) {
                 appTaskDownloadWrapper.setDownloading(false);
-                Toast.makeText(Utils.getContext(), "下载失败,请重试", Toast.LENGTH_SHORT).show();
+                Toast.makeText(context, "下载失败,请重试", Toast.LENGTH_SHORT).show();
                 Bundle bundle = new Bundle();
                 bundle.putBoolean("payload_downloading", false);
-                notifyItem(appTaskDownloadWrapper, bundle);
-                ATLog.d(TAG, "toDownload onError: download error, msg ==> " + message + ", task ==> " + appTaskDownloadWrapper);
+                notifyItemChanged(asyncListDiffer.getCurrentList().indexOf(appTaskDownloadWrapper), bundle);
+                Log.d(TAG, "toDownload onError: download error, msg ==> " + message + ", task ==> " + appTaskDownloadWrapper);
             }
         });
     }
 
-    private void notifyItem(AppTaskDownloadWrapper item, Bundle payload) {
-        recyclerView.setHasFixedSize(true);
-        int position = asyncListDiffer.getCurrentList().indexOf(item);
-        notifyItemChanged(position, payload);
-    }
-
     private boolean checkFileOccupy(File downloadFile) {
         return !downloadFile.renameTo(downloadFile);
     }
 
     public void update(ArrayList<AppTaskBean> appTaskBeans) {
-        ATLog.d(TAG, "update() called with: appTaskBeans = [" + appTaskBeans + "]");
+        ArrayList<AppTaskDownloadWrapper> appTaskDownloadWrappers = new ArrayList<>();
         Observable.fromIterable(appTaskBeans)
                 .filter(appTaskBean -> appTaskBean.getTaskStatus() != AppTaskBean.AppTaskStatus.Finish)
                 .map(AppTaskDownloadWrapper::new)
-                .doOnNext(appTaskDownloadWrapper -> {
-                    if (RetrofitDownloader.isActiveTaskExist(appTaskDownloadWrapper.getAppLink())) {
-                        toDownload(appTaskDownloadWrapper);
-                    }
-                })
-                .toList()
                 .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
-                .subscribe(new SingleObserver<List<AppTaskDownloadWrapper>>() {
+                .subscribe(new Observer<AppTaskDownloadWrapper>() {
                     @Override
-                    public void onSubscribe(Disposable d) {
+                    public void onSubscribe(@atmob.io.reactivex.rxjava3.annotations.NonNull Disposable d) {
                         compositeDisposable.add(d);
-                        ATLog.d(TAG, "onSubscribe() called with: d = [" + d + "]");
                     }
 
                     @Override
-                    public void onSuccess(List<AppTaskDownloadWrapper> list) {
-                        ATLog.d(TAG, "onComplete: app task list update success, total length ==> " + list.size());
-                        Collections.reverse(list);
-                        submit(list);
+                    public void onNext(@atmob.io.reactivex.rxjava3.annotations.NonNull AppTaskDownloadWrapper appTaskDownloadWrapper) {
+                        if (RetrofitDownloader.isActiveTaskExist(appTaskDownloadWrapper.getAppLink())) {
+                            toDownload(appTaskDownloadWrapper);
+                        }
+                        appTaskDownloadWrappers.add(appTaskDownloadWrapper);
+                    }
+
+                    @Override
+                    public void onError(@atmob.io.reactivex.rxjava3.annotations.NonNull Throwable e) {
+                        Log.e(TAG, "onError: AppTaskBean transform to AppTaskDownloadWrapper error", e);
                     }
 
                     @Override
-                    public void onError(Throwable e) {
-                        ATLog.e(TAG, "onError: AppTaskBean transform to AppTaskDownloadWrapper error", e);
+                    public void onComplete() {
+                        Log.d(TAG, "onComplete: app task list update success, total length ==> " + appTaskDownloadWrappers.size());
+                        Collections.reverse(appTaskDownloadWrappers);
+                        asyncListDiffer.submitList(appTaskDownloadWrappers);
                     }
                 });
     }
 
     public void checkAppExist() {
-        ATLog.d(TAG, "app resume, start checkAppExist()");
+        Log.d(TAG, "app resume, start checkAppExist()");
         Completable.fromAction(() -> {
-            Iterator<Map.Entry<Long, String>> iterator = potentialInstalledList.entrySet().iterator();
-            while (iterator.hasNext()) {
-                Map.Entry<Long, String> next = iterator.next();
-                Long appTaskId = next.getKey();
-                String appTaskPackageName = next.getValue();
-                if (TextUtils.isEmpty(appTaskPackageName)) {
-                    iterator.remove();
-                    continue;
-                }
-                boolean existPackage = AppInfoUtils.isExistPackage(Utils.getContext(), appTaskPackageName);
-                if (existPackage) {
-                    if (FORCE_OPEN) {
-                        ATLog.d(TAG, "checkAppExist: app exist, open it. (id ==> " + appTaskId + ", packageName ==> " + appTaskPackageName + ")");
-                        AppTaskEvent.report(AppTaskEvent.ATE_CONFIRM_INSTALLED_LAUNCH);
-                        AppInfoUtils.launchApp(appTaskPackageName);
-                        updateStatus(appTaskId, AppTaskBean.AppTaskStatus.Opened);
-                    } else {
-                        ATLog.d(TAG, "checkAppExist: app exist, just report. (id ==> " + appTaskId + ", packageName ==> " + appTaskPackageName + ")");
-                        updateStatus(appTaskId, AppTaskBean.AppTaskStatus.Installed);
+                    Iterator<Map.Entry<Long, String>> iterator = potentialInstalledList.entrySet().iterator();
+                    while (iterator.hasNext()) {
+                        Map.Entry<Long, String> next = iterator.next();
+                        Long appTaskId = next.getKey();
+                        String appTaskPackageName = next.getValue();
+                        if (TextUtils.isEmpty(appTaskPackageName)) {
+                            iterator.remove();
+                            continue;
+                        }
+                        boolean existPackage = AppInfoUtils.isExistPackage(context, appTaskPackageName);
+                        if (existPackage) {
+                            if (FORCE_OPEN) {
+                                Log.d(TAG, "checkAppExist: app exist, open it. (id ==> " + appTaskId + ", packageName ==> " + appTaskPackageName + ")");
+                                AppTaskEvent.report(AppTaskEvent.ATE_CONFIRM_INSTALLED_LAUNCH);
+                                AppInfoUtils.launchApp(context, appTaskPackageName);
+                                if (onItemActionCallback != null) {
+                                    onItemActionCallback.updateStatus(appTaskId, AppTaskBean.AppTaskStatus.Opened);
+                                }
+                            } else {
+                                Log.d(TAG, "checkAppExist: app exist, just report. (id ==> " + appTaskId + ", packageName ==> " + appTaskPackageName + ")");
+                                if (onItemActionCallback != null) {
+                                    onItemActionCallback.updateStatus(appTaskId, AppTaskBean.AppTaskStatus.Installed);
+                                }
+                            }
+                            iterator.remove();
+                        } else {
+                            Log.d(TAG, "checkAppExist: app not exist. (id ==> " + appTaskId + ", packageName ==> " + appTaskPackageName + ")");
+                        }
                     }
-                    iterator.remove();
-                } else {
-                    ATLog.d(TAG, "checkAppExist: app not exist. (id ==> " + appTaskId + ", packageName ==> " + appTaskPackageName + ")");
-                }
-            }
-        })
+                })
                 .subscribeOn(Schedulers.io())
                 .observeOn(Schedulers.io())
                 .subscribe(new CompletableObserver() {
@@ -449,12 +400,12 @@ public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerVie
             return;
         }
         potentialInstalledList.put(appTaskBeanGet.getId(), appTaskBeanGet.getAppPkgName());
-        ATLog.d(TAG, "addToCheckList() called with: appTaskBeanGet = [" + appTaskBeanGet + "]");
+        Log.d(TAG, "addToCheckList() called with: appTaskBeanGet = [" + appTaskBeanGet + "]");
     }
 
     private void removeFromCheckList(long id) {
         potentialInstalledList.remove(id);
-        ATLog.d(TAG, "removeFromCheckList() called with: id = [" + id + "]");
+        Log.d(TAG, "removeFromCheckList() called with: id = [" + id + "]");
     }
 
     public void setOnItemActionCallback(OnItemActionCallback onItemActionCallback) {
@@ -463,7 +414,8 @@ public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerVie
 
     public void release() {
         RetrofitDownloader.clearAllObserver();
-        ATLog.d(TAG, "release: clear all observer.");
+        viewHolderCreator = null;
+        Log.d(TAG, "release: clear all observer.");
     }
 
     public void triggerFirstTask() {
@@ -474,69 +426,115 @@ public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerVie
             }
             if (appTaskDownloadWrapper.getTaskStatus() != AppTaskBean.AppTaskStatus.Opened && !appTaskDownloadWrapper.isDownloading()) {
                 onAppTaskItemClick(appTaskDownloadWrapper);
-                ATLog.d(TAG, "triggerFirstTask: task ==> " + appTaskDownloadWrapper);
+                Log.d(TAG, "triggerFirstTask: task ==> " + appTaskDownloadWrapper);
                 return;
             }
         }
-        ATLog.d(TAG, "triggerFirstTask: not has available task.");
+        Log.d(TAG, "triggerFirstTask: not has available task.");
     }
 
-    private void updateStatus(long id, int targetStatus) {
-        NetworkClient.api().updateAppTaskStatus(new AppTaskUpdateRequest(id, targetStatus))
-                .compose(RxSchedulersUtils.observableIO2Main())
-                .subscribe(new BaseHttpObserver<AppTaskUpdateResponse>() {
+    /**
+     * 列表内部通过这个类获取item必要组件
+     */
+    public abstract static class AppTaskItemViewHolder extends RecyclerView.ViewHolder {
 
-                    @Override
-                    public void onGotDisposable(Disposable disposable) {
-                        compositeDisposable.add(disposable);
-                    }
+        public AppTaskItemViewHolder(@NonNull View itemView) {
+            super(itemView);
+        }
 
-                    @Override
-                    public void onSuccess(AppTaskUpdateResponse data) {
-                        List<AppTaskDownloadWrapper> currentList = asyncListDiffer.getCurrentList();
-                        for (AppTaskDownloadWrapper wrapper : currentList) {
-                            if (wrapper == null) {
-                                continue;
-                            }
-                            if (wrapper.getId() == id) {
-                                int i = currentList.indexOf(wrapper);
-                                wrapper.setTaskStatus(targetStatus);
-                                notifyItemChanged(i);
-                                return;
-                            }
-                        }
-                        ATLog.d(TAG, "app task status update success, id ==> " + id + ", target status ==> " + targetStatus);
-                    }
+        /**
+         * @return 用于显示app名字的TextView
+         */
+        @NonNull
+        public abstract TextView getAppName();
+
+        /**
+         * @return 用于显示app图标的ImageView
+         */
+        @NonNull
+        public abstract ImageView getAppIcon();
+
+        /**
+         * @return 触发积分墙任务的按钮, 这里后面考虑换成View, 因为ui可能并不是以按钮的形式出现
+         */
+        @NonNull
+        public abstract TextView getTriggerBtn();
+
+        /**
+         * 根据不同的任务状态, 触发按钮上显示的文字提示
+         * <p>
+         * 如果触发按钮以后换成View, 这里需要看下怎么修改
+         *
+         * @param appTaskStatus 任务当前状态
+         * @return 文字提示
+         */
+        public abstract String getBtnText(@AppTaskBean.AppTaskStatus int appTaskStatus);
+
+        /**
+         * 根据不同的任务状态, 触发按钮的背景
+         * <p>
+         * 如果触发按钮以后换成View, 这里需要看下怎么修改
+         *
+         * @param appTaskStatus 任务当前状态
+         * @return {@link Drawable}
+         */
+        public abstract Drawable getBtnBackground(@AppTaskBean.AppTaskStatus int appTaskStatus, boolean isSpecial);
+
+        /**
+         * @return 下载时用的进度条
+         */
+        @NonNull
+        public abstract NormalProgressBar getProgressBar();
+
+        /**
+         * app图标的样式设置
+         *
+         * @return {@link AppIconConfig}
+         */
+        public AppIconConfig getAppIconConfig() {
+            return new AppIconConfig();
+        }
 
-                    @Override
-                    public void onFailed(int code, String msg) {
-                        HttpFailManager.handleHttpFail(code, msg);
-                        ATLog.e(TAG, "app task status update failed, code ==> " + code + ", msg ==> " + msg);
-                    }
-                });
+        public void onRenderReward(float radio) {
+
+        }
     }
 
-    public void setMaxLength(int length) {
-        maxLength = length < 0 ? Integer.MAX_VALUE : length;
-        if (getItemCount() == 0) {
-            return;
+    public static class AppIconConfig {
+
+        /**
+         * 默认图标
+         */
+        @IntegerRes
+        private int placeholderResId;
+
+        /**
+         * 图标的圆角 in dip
+         */
+        private int round;
+
+        @SuppressWarnings("ResourceType")
+        public AppIconConfig() {
+            placeholderResId = R.drawable.atmob_default_icon;
+            round = 0;
         }
-        if (dataCache.size() == getItemCount() && getItemCount() < maxLength) {
-            return;
+
+        public AppIconConfig placeholderResId(int placeholderResId) {
+            this.placeholderResId = placeholderResId;
+            return this;
         }
-        if (getItemCount() == maxLength) {
-            return;
+
+        public AppIconConfig round(int round) {
+            this.round = round;
+            return this;
         }
-        submit(dataCache);
     }
 
-    private void submit(List<AppTaskDownloadWrapper> list) {
-        dataCache = list;
-        List<AppTaskDownloadWrapper> subList = dataCache.subList(0, Math.min(maxLength, dataCache.size()));
-        if (subList.size() != asyncListDiffer.getCurrentList().size()) {
-            recyclerView.setHasFixedSize(false);
-        }
-        asyncListDiffer.submitList(subList);
+    /**
+     * 用于构建积分墙item, see{@link AppTaskItemViewHolder}
+     */
+    public interface ViewHolderCreator {
+        AppTaskItemViewHolder onCreateViewHolder(LayoutInflater layoutInflater, ViewGroup parent);
     }
 
     private static class DiffCallback extends DiffUtil.ItemCallback<AppTaskDownloadWrapper> {
@@ -591,6 +589,8 @@ public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerVie
     public interface OnItemActionCallback {
         void onClick(AppTaskBean appTaskBean);
 
+        void updateStatus(long id, int targetStatus);
+
         void getReward(AppTaskBean appTaskBean);
     }
 }

+ 124 - 77
src/main/java/com/atmob/task/AppTaskView.java

@@ -1,31 +1,30 @@
-package com.atmob.task;
+package com.atmob.rewardtask;
 
 import android.content.Context;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.AttributeSet;
-import android.view.View;
-import android.widget.TextView;
+import android.util.Log;
 
-import androidx.annotation.IdRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
-import com.atmob.http.BaseHttpObserver;
-import com.atmob.manager.HttpFailManager;
-import com.atmob.request.CommonBaseRequest;
-import com.atmob.task.adapter.AppTaskItemAdapter;
-import com.atmob.task.bean.AppTaskBean;
-import com.atmob.task.bean.AppTaskDataResponse;
-import com.atmob.task.data.NetworkClient;
-import com.atmob.task.utils.AppTaskEvent;
-import com.atmob.task.view.TwinklingRecyclerView;
-import com.atmob.utils.RxSchedulersUtils;
+import com.atmob.rewardtask.bean.AppTaskBean;
+import com.atmob.rewardtask.bean.AppTaskDataResponse;
+import com.atmob.rewardtask.bean.AppTaskUpdateRequest;
+import com.atmob.rewardtask.bean.AppTaskUpdateResponse;
+import com.atmob.rewardtask.network.BaseHttpObserver;
+import com.atmob.rewardtask.network.NetworkClient;
+import com.atmob.rewardtask.view.TwinklingRecyclerView;
+import com.ishumei.smantifraud.SmAntiFraud;
 
+import atmob.io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
 import atmob.io.reactivex.rxjava3.disposables.CompositeDisposable;
 import atmob.io.reactivex.rxjava3.disposables.Disposable;
+import atmob.io.reactivex.rxjava3.schedulers.Schedulers;
+import atmob.request.CommonBaseRequest;
 
 public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAdapter.OnItemActionCallback {
 
@@ -35,13 +34,17 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
 
     private CompositeDisposable compositeDisposable;
 
-    private AppTaskItemAdapter<? extends AppTaskViewHolder> appTaskItemAdapter;
+    private RecyclerView.OnScrollListener smTrackOnScrollListener;
+
+    private AppTaskItemAdapter appTaskItemAdapter;
+
+    private OnAppTaskRewardListener onAppTaskRewardListener;
 
     private OnAppTaskItemClickListener onAppTaskItemClickListener;
 
     private OnAppTaskRewardRequestListener onAppTaskRewardRequestListener;
 
-    private OnAppTaskLoadListener onAppTaskLoadListener;
+    private boolean doNotRequestReward;
 
     private boolean loadingFlag;
 
@@ -70,6 +73,13 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
         });
         compositeDisposable = new CompositeDisposable();
         setLayoutManager(new LinearLayoutManager(getContext()));
+        smTrackOnScrollListener = new RecyclerView.OnScrollListener() {
+            @Override
+            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
+                super.onScrollStateChanged(recyclerView, newState);
+                SmAntiFraud.track("onScroll", String.valueOf(recyclerView.getId()), null);
+            }
+        };
     }
 
     private void loadData() {
@@ -78,7 +88,7 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
         }
         loadingFlag = true;
         NetworkClient.api().loadAppTask(new CommonBaseRequest())
-                .compose(RxSchedulersUtils.observableIO2Main())
+                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                 .subscribe(new BaseHttpObserver<AppTaskDataResponse>() {
 
                     @Override
@@ -90,32 +100,19 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
                     @Override
                     public void onSuccess(AppTaskDataResponse data) {
                         loadingFlag = false;
-                        if (data == null || data.getPtasks() == null || data.getPtasks().size() == 0) {
-                            if (onAppTaskLoadListener != null) {
-                                onAppTaskLoadListener.onLoaded(0);
-                            }
+                        if (data == null) {
                             return;
                         }
-                        int activeCount = 0;
-                        for (AppTaskBean ptask : data.getPtasks()) {
-                            if (ptask.getTaskStatus() != AppTaskBean.AppTaskStatus.Finish) {
-                                activeCount++;
-                            }
-                        }
                         AppTaskBean.CDN = data.getUrl();
                         if (data.getPtasks() != null) {
                             appTaskItemAdapter.update(data.getPtasks());
                         }
-                        if (onAppTaskLoadListener != null) {
-                            onAppTaskLoadListener.onLoaded(activeCount);
-                        }
                         AppTaskEvent.report(AppTaskEvent.ATE_LOAD_DATA_SUCCESS);
                     }
 
                     @Override
                     public void onFailed(int code, String msg) {
                         loadingFlag = false;
-                        HttpFailManager.handleHttpFail(code, msg);
                     }
                 });
     }
@@ -127,13 +124,22 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
         compositeDisposable.add(disposable);
     }
 
-    public <T extends AppTaskViewHolder> void init(@NonNull AppTaskAdapter<T> appTaskAdapter) {
-        appTaskItemAdapter = new AppTaskItemAdapter<>(this, appTaskAdapter, compositeDisposable);
+    public void init(@NonNull AppTaskItemAdapter.ViewHolderCreator viewHolderCreator) {
+        appTaskItemAdapter = new AppTaskItemAdapter(viewHolderCreator, compositeDisposable, getContext());
         appTaskItemAdapter.setOnItemActionCallback(this);
         super.setAdapter(appTaskItemAdapter);
     }
 
     /**
+     * @param onAppTaskRewardListener see{@link OnAppTaskRewardListener}
+     * @return this
+     */
+    public AppTaskView setOnAppTaskRewardListener(OnAppTaskRewardListener onAppTaskRewardListener) {
+        this.onAppTaskRewardListener = onAppTaskRewardListener;
+        return this;
+    }
+
+    /**
      * @param onAppTaskItemClickListener see{@link OnAppTaskItemClickListener}
      * @return this
      */
@@ -151,8 +157,13 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
         return this;
     }
 
-    public AppTaskView setOnAppTaskEmptyListener(OnAppTaskLoadListener onAppTaskLoadListener) {
-        this.onAppTaskLoadListener = onAppTaskLoadListener;
+    /**
+     * 禁用AppTaskFragment自带的奖励下发请求, 触发奖励下发时会回调{@link OnAppTaskRewardRequestListener}
+     *
+     * @return this
+     */
+    public AppTaskView doNotRequestReward() {
+        doNotRequestReward = true;
         return this;
     }
 
@@ -179,13 +190,7 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
      * 刷新积分墙任务
      */
     public void refreshTaskList() {
-        if (getVisibility() == VISIBLE) {
-            loadData();
-        }
-    }
-
-    public void setMaxLength(int length) {
-        appTaskItemAdapter.setMaxLength(length);
+        loadData();
     }
 
     @Override
@@ -199,20 +204,8 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
     }
 
     @Override
-    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
-        super.onVisibilityChanged(changedView, visibility);
-        if (visibility == VISIBLE) {
-            loadData();
-        }
-    }
-
-    @Override
     public void onVisibilityAggregated(boolean isVisible) {
         super.onVisibilityAggregated(isVisible);
-        onVisibilityAggregatedInternal(isVisible);
-    }
-
-    private void onVisibilityAggregatedInternal(boolean isVisible) {
         if (isVisible && appTaskItemAdapter != null) {
             if (handler.hasMessages(WHAT_CHECK_APP_EXIST)) {
                 handler.removeMessages(WHAT_CHECK_APP_EXIST);
@@ -230,6 +223,7 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
         if (appTaskItemAdapter != null) {
             appTaskItemAdapter.release();
         }
+        removeOnScrollListener(smTrackOnScrollListener);
     }
 
     @Override
@@ -237,17 +231,90 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
         if (onAppTaskItemClickListener != null) {
             onAppTaskItemClickListener.onClick(appTaskBean.getTaskStatus());
         }
+        switch (appTaskBean.getTaskStatus()) {
+
+            case AppTaskBean.AppTaskStatus.Finish:
+                break;
+            case AppTaskBean.AppTaskStatus.Initial:
+            case AppTaskBean.AppTaskStatus.Installed:
+                AppTaskEvent.report(AppTaskEvent.ATE_CLICK_ITEM_INITIAL);
+                break;
+            case AppTaskBean.AppTaskStatus.Opened:
+                AppTaskEvent.report(AppTaskEvent.ATE_CLICK_ITEM_REWARD);
+                break;
+        }
+    }
+
+    @Override
+    public void updateStatus(long id, int targetStatus) {
+        NetworkClient.api().updateAppTaskStatus(new AppTaskUpdateRequest(id, targetStatus))
+                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new BaseHttpObserver<AppTaskUpdateResponse>() {
+
+                    @Override
+                    public void onGotDisposable(Disposable disposable) {
+                        addDisposable(disposable);
+                    }
+
+                    @Override
+                    public void onSuccess(AppTaskUpdateResponse data) {
+                        loadData();
+                        Log.d(TAG, "app task status update success, id ==> " + id + ", target status ==> " + targetStatus);
+                    }
+
+                    @Override
+                    public void onFailed(int code, String msg) {
+                    }
+                });
     }
 
     @Override
     public void getReward(AppTaskBean appTaskBean) {
-        if (onAppTaskRewardRequestListener != null) {
-            onAppTaskRewardRequestListener.onReward(appTaskBean);
+        if (doNotRequestReward) {
+            if (onAppTaskRewardRequestListener != null) {
+                onAppTaskRewardRequestListener.onReward(appTaskBean);
+            }
+            return;
         }
+        NetworkClient.api().updateAppTaskStatus(new AppTaskUpdateRequest(appTaskBean.getId(), AppTaskBean.AppTaskStatus.Finish))
+                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new BaseHttpObserver<AppTaskUpdateResponse>() {
+
+                    @Override
+                    public void onGotDisposable(Disposable disposable) {
+                        addDisposable(disposable);
+                    }
+
+                    @Override
+                    public void onSuccess(AppTaskUpdateResponse data) {
+                        if (data == null) {
+                            return;
+                        }
+                        loadData();
+                        if (onAppTaskRewardListener != null) {
+                            onAppTaskRewardListener.onReward(data.getRdn());
+                        }
+                        Log.d(TAG, "get app task reward success, id ==> " + appTaskBean.getId() + ", reward key ==> " + data.getRdn());
+                    }
+
+                    @Override
+                    public void onFailed(int code, String msg) {
+                    }
+                });
     }
 
     /**
-     * 请求奖励回调
+     * 通用的奖励下发回调
+     */
+    public interface OnAppTaskRewardListener {
+        /**
+         * @param rewardKey 奖励key, 用于向相应的服务端请求奖励
+         */
+        void onReward(String rewardKey);
+    }
+
+    /**
+     * 调用过{@link AppTaskView#doNotRequestReward()}之后的请求奖励回调
      */
     public interface OnAppTaskRewardRequestListener {
         void onReward(AppTaskBean appTaskBean);
@@ -262,24 +329,4 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
          */
         void onClick(@AppTaskBean.AppTaskStatus int appTaskStatus);
     }
-
-    public interface OnAppTaskLoadListener {
-        void onLoaded(int size);
-    }
-
-    public abstract static class AppTaskViewHolder extends RecyclerView.ViewHolder {
-
-        public AppTaskViewHolder(@NonNull View itemView) {
-            super(itemView);
-        }
-
-        public void setText(@IdRes int id, CharSequence text) {
-            TextView textView = itemView.findViewById(id);
-            textView.setText(text);
-        }
-
-        public void setVisible(@IdRes int id, boolean visible) {
-            itemView.findViewById(id).setVisibility(visible ? View.VISIBLE : View.GONE);
-        }
-    }
 }

+ 1 - 1
src/main/java/com/atmob/task/bean/AppTaskBean.java

@@ -1,4 +1,4 @@
-package com.atmob.task.bean;
+package com.atmob.rewardtask.bean;
 
 import android.text.TextUtils;
 

+ 46 - 0
src/main/java/com/atmob/rewardtask/bean/AppTaskControlResponse.java

@@ -0,0 +1,46 @@
+package com.atmob.rewardtask.bean;
+
+public class AppTaskControlResponse {
+
+    private Info pp;
+
+    public Info getPp() {
+        return pp;
+    }
+
+    public void setPp(Info pp) {
+        this.pp = pp;
+    }
+
+    public static class Info {
+        private boolean pop;
+
+        private int popIndex;
+
+        private int popInterval;
+
+        public boolean isPop() {
+            return pop;
+        }
+
+        public void setPop(boolean pop) {
+            this.pop = pop;
+        }
+
+        public int getPopIndex() {
+            return popIndex;
+        }
+
+        public void setPopIndex(int popIndex) {
+            this.popIndex = popIndex;
+        }
+
+        public int getPopInterval() {
+            return popInterval;
+        }
+
+        public void setPopInterval(int popInterval) {
+            this.popInterval = popInterval;
+        }
+    }
+}

+ 1 - 5
src/main/java/com/atmob/task/bean/AppTaskDataResponse.java

@@ -1,14 +1,10 @@
-package com.atmob.task.bean;
-
-import com.google.gson.annotations.SerializedName;
+package com.atmob.rewardtask.bean;
 
 import java.util.ArrayList;
 
 public class AppTaskDataResponse {
-    @SerializedName("url")
     private String url;
 
-    @SerializedName("ptasks")
     private ArrayList<AppTaskBean> ptasks;
 
     public String getUrl() {

+ 1 - 1
src/main/java/com/atmob/task/bean/AppTaskDownloadWrapper.java

@@ -1,4 +1,4 @@
-package com.atmob.task.bean;
+package com.atmob.rewardtask.bean;
 
 public class AppTaskDownloadWrapper extends AppTaskBean {
     private boolean isDownloading;

+ 2 - 6
src/main/java/com/atmob/task/bean/AppTaskUpdateRequest.java

@@ -1,16 +1,12 @@
-package com.atmob.task.bean;
+package com.atmob.rewardtask.bean;
 
-import com.atmob.request.CommonBaseRequest;
-import com.google.gson.annotations.SerializedName;
+import atmob.request.CommonBaseRequest;
 
 public class AppTaskUpdateRequest extends CommonBaseRequest {
-    @SerializedName("id")
     private long id;
 
-    @SerializedName("taskStatus")
     private int taskStatus;
 
-    @SerializedName("taskType")
     private int taskType = 0;
 
     public AppTaskUpdateRequest(long id, int taskStatus) {

+ 1 - 4
src/main/java/com/atmob/task/bean/AppTaskUpdateResponse.java

@@ -1,9 +1,6 @@
-package com.atmob.task.bean;
-
-import com.google.gson.annotations.SerializedName;
+package com.atmob.rewardtask.bean;
 
 public class AppTaskUpdateResponse {
-    @SerializedName("rdn")
     private String rdn;
 
     public String getRdn() {

+ 12 - 0
src/main/java/com/atmob/rewardtask/bean/EventRequest.java

@@ -0,0 +1,12 @@
+package com.atmob.rewardtask.bean;
+
+import atmob.request.CommonBaseRequest;
+
+public class EventRequest extends CommonBaseRequest {
+
+    private final String eventId;
+
+    public EventRequest(String eventId) {
+        this.eventId = eventId;
+    }
+}

+ 8 - 8
src/main/java/com/atmob/task/data/Api.java

@@ -1,14 +1,14 @@
-package com.atmob.task.data;
+package com.atmob.rewardtask.network;
 
-import com.atmob.request.CommonBaseRequest;
-import com.atmob.request.EventRequest;
-import com.atmob.response.BaseResponse;
-import com.atmob.task.bean.AppTaskControlResponse;
-import com.atmob.task.bean.AppTaskDataResponse;
-import com.atmob.task.bean.AppTaskUpdateRequest;
-import com.atmob.task.bean.AppTaskUpdateResponse;
+import com.atmob.rewardtask.bean.AppTaskControlResponse;
+import com.atmob.rewardtask.bean.AppTaskDataResponse;
+import com.atmob.rewardtask.bean.AppTaskUpdateRequest;
+import com.atmob.rewardtask.bean.AppTaskUpdateResponse;
+import com.atmob.rewardtask.bean.EventRequest;
 
 import atmob.io.reactivex.rxjava3.core.Observable;
+import atmob.request.CommonBaseRequest;
+import atmob.response.BaseResponse;
 import atmob.retrofit2.http.Body;
 import atmob.retrofit2.http.POST;
 

+ 45 - 0
src/main/java/com/atmob/rewardtask/network/BaseHttpObserver.java

@@ -0,0 +1,45 @@
+package com.atmob.rewardtask.network;
+
+import androidx.annotation.NonNull;
+
+import atmob.io.reactivex.rxjava3.core.Observer;
+import atmob.io.reactivex.rxjava3.disposables.Disposable;
+import atmob.response.BaseResponse;
+
+public abstract class BaseHttpObserver<T> implements Observer<BaseResponse<T>> {
+
+    private static final int CODE_SUCCESS = 0;
+    private static final int CODE_ERROR = -1;
+
+    @Override
+    public void onSubscribe(@NonNull Disposable d) {
+        onGotDisposable(d);
+    }
+
+    @Override
+    public void onNext(@NonNull BaseResponse<T> baseResponse) {
+        int code = baseResponse.getCode();
+        if (code == CODE_SUCCESS) {
+            onSuccess(baseResponse.getData());
+        } else {
+            onFailed(baseResponse.getCode(), baseResponse.getMsg());
+        }
+    }
+
+    @Override
+    public void onError(@NonNull Throwable e) {
+        onFailed(CODE_ERROR, e.getMessage());
+        e.printStackTrace();
+    }
+
+    @Override
+    public void onComplete() {
+
+    }
+
+    public abstract void onGotDisposable(Disposable disposable);
+
+    public abstract void onSuccess(T data);
+
+    public abstract void onFailed(int code, String msg);
+}

+ 75 - 0
src/main/java/com/atmob/rewardtask/network/NetworkClient.java

@@ -0,0 +1,75 @@
+package com.atmob.rewardtask.network;
+
+import androidx.annotation.NonNull;
+
+import com.google.gson.Gson;
+
+import java.util.HashMap;
+
+import atmob.http.HttpsUtils;
+import atmob.okhttp3.OkHttpClient;
+import atmob.retrofit2.Retrofit;
+import atmob.retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
+import atmob.retrofit2.converter.gson.GsonConverterFactory;
+import atmob.utils.Translator;
+
+public class NetworkClient {
+
+    private static final String BASE_URL = Translator.decode("978b8b8f8cc5d0d096c6cf90948795d189c79b9e8c979a91d19c9092c5cbc9c6cc");
+
+    public static Api api() {
+        return RetrofitClient.getInstance().createApi(Api.class);
+    }
+
+    public static void resetBaseUrl(String baseUrl) {
+        RetrofitClient.getInstance().resetBaseUrl(baseUrl);
+    }
+
+    private static class RetrofitClient {
+
+        private final HashMap<Class<?>, Object> apiCache = new HashMap<>();
+
+        private final Retrofit retrofit;
+
+        private static class Holder {
+            private static final RetrofitClient INSTANCE = new RetrofitClient();
+        }
+
+        public RetrofitClient() {
+            retrofit = init(BASE_URL);
+        }
+
+        private Retrofit init(String baseUrl) {
+            final Retrofit retrofit;
+            HttpsUtils.SSLParams sslParams = HttpsUtils.getSSLParams(baseUrl);
+            OkHttpClient okHttpClient = new OkHttpClient.Builder()
+                    .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
+                    .hostnameVerifier((hostname, session) -> true)
+                    .build();
+            retrofit = new Retrofit.Builder()
+                    .client(okHttpClient)
+                    .addConverterFactory(GsonConverterFactory.create(new Gson()))
+                    .addCallAdapterFactory(RxJava3CallAdapterFactory.createSynchronous())
+                    .baseUrl(baseUrl)
+                    .build();
+            return retrofit;
+        }
+
+        private static RetrofitClient getInstance() {
+            return Holder.INSTANCE;
+        }
+
+        public <T> T createApi(@NonNull Class<T> apiClass) {
+            Object api = apiCache.get(apiClass);
+            if (api == null) {
+                api = Holder.INSTANCE.retrofit.create(apiClass);
+                apiCache.put(apiClass, api);
+            }
+            return (T) api;
+        }
+
+        public void resetBaseUrl(String baseUrl) {
+            init(baseUrl);
+        }
+    }
+}

+ 47 - 0
src/main/java/com/atmob/rewardtask/utils/AppInfoUtils.java

@@ -0,0 +1,47 @@
+package com.atmob.rewardtask.utils;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AppInfoUtils {
+
+    private static final String TAG = AppInfoUtils.class.getSimpleName();
+
+    /**
+     * 判断已安装app包名是否存在的方法
+     */
+    public static boolean isExistPackage(Context context, String packageName) {
+        // 获取packagemanager
+        final PackageManager packageManager = context.getPackageManager();
+        // 获取所有已安装程序的包信息
+        List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
+        // 用于存储所有已安装程序的包名
+        List<String> pName = new ArrayList<>();
+        // 从pinfo中将包名字取出
+        if (pinfo != null) {
+            for (int i = 0; i < pinfo.size(); i++) {
+                String pf = pinfo.get(i).packageName;
+                pName.add(pf);
+            }
+        }
+        // 判断pName中是否有目标程序的包名,有true,没有false
+        return pName.contains(packageName);
+    }
+
+    public static void launchApp(Context context, String packageName) {
+        PackageManager packageManager = context.getPackageManager();
+        Intent launchIntentForPackage = packageManager.getLaunchIntentForPackage(packageName);
+        if (launchIntentForPackage == null) {
+            Log.d("", String.format("package(%s) was not found", packageManager));
+        } else {
+            launchIntentForPackage.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            context.startActivity(launchIntentForPackage);
+        }
+    }
+}

+ 63 - 0
src/main/java/com/atmob/rewardtask/utils/AppTaskHandler.java

@@ -0,0 +1,63 @@
+package com.atmob.rewardtask.utils;
+
+import android.util.Log;
+
+import com.atmob.rewardtask.bean.AppTaskControlResponse;
+import com.atmob.rewardtask.network.BaseHttpObserver;
+import com.atmob.rewardtask.network.NetworkClient;
+
+import atmob.io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
+import atmob.io.reactivex.rxjava3.disposables.CompositeDisposable;
+import atmob.io.reactivex.rxjava3.disposables.Disposable;
+import atmob.io.reactivex.rxjava3.schedulers.Schedulers;
+import atmob.request.CommonBaseRequest;
+
+/**
+ * 提供一些关于积分墙的静态方法
+ */
+public class AppTaskHandler {
+
+    private static final String TAG = AppTaskHandler.class.getSimpleName();
+
+    /**
+     * 异步查询是否有积分墙任务
+     *
+     * @param onTaskResultListener 查询结果的回调
+     * @return 防止出现内存泄漏, 外部自行管理disposable, 这里偷懒了为了使用封装的 {@link BaseHttpObserver}, 应该返回Disposable最优 - -
+     */
+    public static CompositeDisposable hasTask(OnTaskResultListener onTaskResultListener) {
+        CompositeDisposable compositeDisposable = new CompositeDisposable();
+        if (onTaskResultListener == null) {
+            return compositeDisposable;
+        }
+        NetworkClient.api().appTaskControlInfo(new CommonBaseRequest())
+                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new BaseHttpObserver<AppTaskControlResponse>() {
+
+                    @Override
+                    public void onGotDisposable(Disposable disposable) {
+                        compositeDisposable.add(disposable);
+                    }
+
+                    @Override
+                    public void onSuccess(AppTaskControlResponse data) {
+                        if (data == null) {
+                            onTaskResultListener.onResult(false);
+                            return;
+                        }
+                        AppTaskControlResponse.Info pp = data.getPp();
+                        onTaskResultListener.onResult(pp.isPop());
+                    }
+
+                    @Override
+                    public void onFailed(int code, String msg) {
+                        Log.e(TAG, "onFailed: appTaskControlInfo api failed, code ==> " + code + ", msg ==> " + msg);
+                    }
+                });
+        return compositeDisposable;
+    }
+
+    public interface OnTaskResultListener {
+        void onResult(boolean hasTask);
+    }
+}

+ 3 - 3
src/main/java/com/atmob/task/utils/InstallFaultToleranceUtils.java

@@ -1,4 +1,4 @@
-package com.atmob.task.utils;
+package com.atmob.rewardtask.utils;
 
 import android.content.Context;
 import android.content.Intent;
@@ -7,7 +7,7 @@ import android.os.Build;
 
 import androidx.core.content.FileProvider;
 
-import com.atmob.utils.MMKVUtils;
+import com.atmob.rewardtask.AppTaskEvent;
 
 import java.io.File;
 
@@ -52,7 +52,7 @@ public class InstallFaultToleranceUtils {
         }
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
             Uri contentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", apkFile);
             intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
         } else {

+ 47 - 0
src/main/java/com/atmob/rewardtask/utils/MMKVUtils.java

@@ -0,0 +1,47 @@
+package com.atmob.rewardtask.utils;
+
+import android.content.Context;
+
+import androidx.annotation.Keep;
+
+import atmob.utils.ContextProvider;
+
+@Keep
+public class MMKVUtils {
+    private static final String KEY_MMKV_UTILS_TAG = "mttask_sp";
+
+    @Keep
+    public static int getInt(String key, int defaultValue) {
+        return ContextProvider.get().getContext().getSharedPreferences(KEY_MMKV_UTILS_TAG, Context.MODE_PRIVATE).getInt(key, defaultValue);
+    }
+
+    @Keep
+    public static void putInt(String key, int value) {
+        ContextProvider.get().getContext().getSharedPreferences(KEY_MMKV_UTILS_TAG, Context.MODE_PRIVATE).edit().putInt(key, value).apply();
+    }
+
+    @Keep
+    public static boolean getBoolean(String key, boolean defValue) {
+        return ContextProvider.get().getContext().getSharedPreferences(KEY_MMKV_UTILS_TAG, Context.MODE_PRIVATE).getBoolean(key, defValue);
+    }
+
+    @Keep
+    public static void putBoolean(String key, boolean value) {
+        ContextProvider.get().getContext().getSharedPreferences(KEY_MMKV_UTILS_TAG, Context.MODE_PRIVATE).edit().putBoolean(key, value).apply();
+    }
+
+    @Keep
+    public static String getString(String key, String defValue) {
+        return ContextProvider.get().getContext().getSharedPreferences(KEY_MMKV_UTILS_TAG, Context.MODE_PRIVATE).getString(key, defValue);
+    }
+
+    @Keep
+    public static void putString(String key, String value) {
+        ContextProvider.get().getContext().getSharedPreferences(KEY_MMKV_UTILS_TAG, Context.MODE_PRIVATE).edit().putString(key, value).apply();
+    }
+
+    @Keep
+    public static void remove(String key) {
+        ContextProvider.get().getContext().getSharedPreferences(KEY_MMKV_UTILS_TAG, Context.MODE_PRIVATE).edit().remove(key).apply();
+    }
+}

+ 5 - 5
src/main/java/com/atmob/task/utils/RetrofitDownloader.java

@@ -1,11 +1,9 @@
-package com.atmob.task.utils;
+package com.atmob.rewardtask.utils;
 
 import android.text.TextUtils;
 
 import androidx.annotation.IntDef;
 
-import com.atmob.utils.RxSchedulersUtils;
-
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -14,6 +12,7 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
+import atmob.io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
 import atmob.io.reactivex.rxjava3.annotations.NonNull;
 import atmob.io.reactivex.rxjava3.core.Observable;
 import atmob.io.reactivex.rxjava3.core.ObservableEmitter;
@@ -23,6 +22,7 @@ import atmob.io.reactivex.rxjava3.core.Observer;
 import atmob.io.reactivex.rxjava3.disposables.CompositeDisposable;
 import atmob.io.reactivex.rxjava3.disposables.Disposable;
 import atmob.io.reactivex.rxjava3.functions.Function;
+import atmob.io.reactivex.rxjava3.schedulers.Schedulers;
 import atmob.okhttp3.OkHttpClient;
 import atmob.okhttp3.ResponseBody;
 import atmob.retrofit2.Retrofit;
@@ -90,10 +90,10 @@ public class RetrofitDownloader {
 
         getRetrofit().create(ApiService.class)
                 .download(url)
-                .compose(RxSchedulersUtils.observableIOOnly())
+                .subscribeOn(Schedulers.io()).observeOn(Schedulers.io())
                 .flatMap((Function<ResponseBody, ObservableSource<DownloadProgress>>) responseBody ->
                         Observable.create((ObservableOnSubscribe<DownloadProgress>) emitter -> doSave(targetFilePath, emitter, responseBody)))
-                .compose(RxSchedulersUtils.observableIO2Main())
+                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                 .subscribe(new Observer<DownloadProgress>() {
                     @Override
                     public void onSubscribe(@NonNull Disposable d) {

+ 233 - 0
src/main/java/com/atmob/rewardtask/view/NormalProgressBar.java

@@ -0,0 +1,233 @@
+package com.atmob.rewardtask.view;
+
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Outline;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+import android.view.animation.DecelerateInterpolator;
+
+import androidx.annotation.ColorInt;
+import androidx.annotation.Nullable;
+
+import com.atmob.rewardtask.R;
+
+import java.util.Locale;
+
+/**
+ * a common version for progress bar
+ */
+public class NormalProgressBar extends View {
+
+    private Paint paint;
+
+    private RectF backgroundRectF;
+
+    private RectF progressRectF;
+
+    private int backgroundColor;
+
+    private int progressColor;
+
+    private int radius;
+
+    private ValueAnimator valueAnimator;
+
+    private OnProgressingListener onProgressingListener;
+    private boolean showPercent;
+    private int percentTextColor;
+    private int percentTextSize;
+
+    public NormalProgressBar(Context context) {
+        super(context);
+        init(null);
+    }
+
+    public NormalProgressBar(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+        init(attrs);
+    }
+
+    public NormalProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init(attrs);
+    }
+
+    private void init(AttributeSet attrs) {
+        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.NormalProgressBar);
+        backgroundColor = typedArray.getColor(R.styleable.NormalProgressBar_NormalProgressBar_backgroundColor, Color.parseColor("#B00C1C"));
+        progressColor = typedArray.getColor(R.styleable.NormalProgressBar_NormalProgressBar_progressColor, Color.parseColor("#FFAC52"));
+        radius = typedArray.getDimensionPixelSize(R.styleable.NormalProgressBar_NormalProgressBar_radius, 0);
+        showPercent = typedArray.getBoolean(R.styleable.NormalProgressBar_NormalProgressBar_showPercent, false);
+        if (showPercent) {
+            percentTextColor = typedArray.getColor(R.styleable.NormalProgressBar_NormalProgressBar_percentTextColor, Color.WHITE);
+            percentTextSize = typedArray.getDimensionPixelSize(R.styleable.NormalProgressBar_NormalProgressBar_percentTextSize, 45);
+        }
+        typedArray.recycle();
+
+        paint = new Paint();
+
+        backgroundRectF = new RectF();
+
+        progressRectF = new RectF();
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
+
+        backgroundRectF.right = getMeasuredWidth();
+        backgroundRectF.bottom = getMeasuredHeight();
+        progressRectF.bottom = getMeasuredHeight();
+
+        setClipToOutline(true);
+        setOutlineProvider(new ViewOutlineProvider() {
+            @Override
+            public void getOutline(View view, Outline outline) {
+                outline.setRoundRect((int) backgroundRectF.left,
+                        (int) backgroundRectF.top,
+                        (int) backgroundRectF.right,
+                        (int) backgroundRectF.bottom,
+                        radius);
+            }
+        });
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        drawBackground(canvas);
+        drawSeek(canvas);
+        if (showPercent) {
+            drawPercentTest(canvas);
+        }
+    }
+
+    private void drawPercentTest(Canvas canvas) {
+        paint.setColor(percentTextColor);
+        paint.setTextAlign(Paint.Align.CENTER);
+        paint.setTextSize(percentTextSize);
+        Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();
+        float baseline = (progressRectF.bottom + progressRectF.top - fontMetrics.bottom - fontMetrics.top) / 2;
+        String percent = backgroundRectF.right == 0 ? "0%" : String.format(Locale.getDefault(), "%.1f%%", (float) progressRectF.right * 100f / (float) backgroundRectF.right);
+        canvas.drawText(percent, (backgroundRectF.right + backgroundRectF.left) / 2, baseline, paint);
+    }
+
+    private void drawBackground(Canvas canvas) {
+        paint.setColor(backgroundColor);
+        paint.setStyle(Paint.Style.FILL);
+        canvas.drawRoundRect(backgroundRectF, radius, radius, paint);
+    }
+
+    private void drawSeek(Canvas canvas) {
+        paint.setColor(progressColor);
+        paint.setStyle(Paint.Style.FILL);
+        canvas.drawRoundRect(progressRectF, radius, radius, paint);
+    }
+
+    /**
+     * start animation from current progress to target progress
+     *
+     * @param max      max progress
+     * @param progress current progress
+     */
+    public void startProgress(final long max, final long progress) {
+        startProgress(max, progress, false);
+    }
+
+    /**
+     * start animation from 0 to target progress
+     *
+     * @param max      max progress
+     * @param progress current progress
+     */
+    public void startProgress(final long max, final long progress, final boolean restart) {
+        if (max <= 0 || progress <= 0) {
+            return;
+        }
+        if (valueAnimator == null) {
+            valueAnimator = new ValueAnimator();
+            valueAnimator.setInterpolator(new DecelerateInterpolator());
+            valueAnimator.addUpdateListener(animation -> {
+                progressRectF.right = (float) animation.getAnimatedValue();
+                if (onProgressingListener != null) {
+                    onProgressingListener.onProgressAnim(max, (long) ((progressRectF.right / backgroundRectF.right) * max));
+                }
+                invalidate();
+            });
+        } else {
+            if (valueAnimator.getValues() != null && valueAnimator.getValues().length > 0 && valueAnimator.isRunning()) {
+                valueAnimator.end();
+            }
+            valueAnimator.cancel();
+        }
+        post(() -> {
+            if (restart) {
+                progressRectF.right = 0;
+            }
+            long progressFinal = Math.min(max, progress);
+            float target = progressFinal * 1f / max * backgroundRectF.right;
+            target = Math.min(target, backgroundRectF.right);
+            valueAnimator.setDuration((long) (2000L * (Math.abs(target - progressRectF.right) / backgroundRectF.right)));
+            valueAnimator.setFloatValues(progressRectF.right, target);
+            valueAnimator.start();
+        });
+    }
+
+    /**
+     * set to target progress without animation
+     *
+     * @param max      max progress
+     * @param progress current progress
+     */
+    public void setProgress(long max, long progress) {
+        if (max <= 0 || progress <= 0) {
+            return;
+        }
+        long progressFinal = Math.min(max, progress);
+        progressRectF.right = progressFinal * 1f / max * backgroundRectF.right;
+        invalidate();
+    }
+
+    public void setBackgroundColor(@ColorInt int backgroundColor) {
+        this.backgroundColor = backgroundColor;
+        invalidate();
+    }
+
+    public void setProgressColor(@ColorInt int progressColor) {
+        this.progressColor = progressColor;
+        invalidate();
+    }
+
+    /**
+     * set progress radius in pixels
+     *
+     * @param radius progress radius
+     */
+    public void setRadius(int radius) {
+        this.radius = radius;
+        invalidate();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        if (valueAnimator != null) {
+            valueAnimator.cancel();
+        }
+    }
+
+    public void setOnProgressingListener(OnProgressingListener onProgressingListener) {
+        this.onProgressingListener = onProgressingListener;
+    }
+
+    public interface OnProgressingListener {
+        void onProgressAnim(long max, long progress);
+    }
+}

+ 1 - 1
src/main/java/com/atmob/task/view/TwinklingRecyclerView.java

@@ -1,4 +1,4 @@
-package com.atmob.task.view;
+package com.atmob.rewardtask.view;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;

+ 0 - 24
src/main/java/com/atmob/task/AppTaskAdapter.java

@@ -1,24 +0,0 @@
-package com.atmob.task;
-
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.atmob.task.AppTaskView.AppTaskViewHolder;
-import com.atmob.task.bean.AppTaskBean;
-
-public abstract class AppTaskAdapter<T extends AppTaskViewHolder> {
-    public abstract T onCreateViewHolder(LayoutInflater inflater, ViewGroup parent);
-
-    public abstract View[] getClickViews(T appTaskViewHolder);
-
-    public abstract void onRenderAppName(T appTaskViewHolder, AppTaskBean appTaskBean, String appName);
-
-    public abstract void onRenderAppIcon(T appTaskViewHolder, AppTaskBean appTaskBean, String appIconUrl);
-
-    public abstract void onRenderTaskStatus(T appTaskViewHolder, AppTaskBean appTaskBean, @AppTaskBean.AppTaskStatus int taskStatus);
-
-    public abstract void onRenderDownloadProgress(T appTaskViewHolder, long total, long progress);
-
-    public abstract void onDownloadStatusChanged(T appTaskViewHolder, boolean isDownloading);
-}

+ 0 - 46
src/main/java/com/atmob/task/bean/AdAppInfoData.java

@@ -1,46 +0,0 @@
-package com.atmob.task.bean;
-
-import androidx.annotation.NonNull;
-
-public class AdAppInfoData {
-
-    @NonNull
-    private String packageName;
-
-    private String apkPath;
-
-    private String appName;
-
-    public AdAppInfoData() {
-    }
-
-    public AdAppInfoData(@NonNull String packageName, String apkPath, String appName) {
-        this.packageName = packageName;
-        this.apkPath = apkPath;
-        this.appName = appName;
-    }
-
-    public String getPackageName() {
-        return packageName;
-    }
-
-    public void setPackageName(String packageName) {
-        this.packageName = packageName;
-    }
-
-    public String getApkPath() {
-        return apkPath;
-    }
-
-    public void setApkPath(String apkPath) {
-        this.apkPath = apkPath;
-    }
-
-    public String getAppName() {
-        return appName;
-    }
-
-    public void setAppName(String appName) {
-        this.appName = appName;
-    }
-}

+ 0 - 26
src/main/java/com/atmob/task/bean/AppTaskControlResponse.java

@@ -1,26 +0,0 @@
-package com.atmob.task.bean;
-
-import com.google.gson.annotations.SerializedName;
-
-public class AppTaskControlResponse {
-
-    @SerializedName("pp")
-    private Info pp;
-
-    public Info getPp() {
-        return pp;
-    }
-
-    public void setPp(Info pp) {
-        this.pp = pp;
-    }
-
-    public static class Info {
-        @SerializedName("pop")
-        private boolean pop;
-
-        public boolean isPop() {
-            return pop;
-        }
-    }
-}

+ 0 - 15
src/main/java/com/atmob/task/data/LocalData.java

@@ -1,15 +0,0 @@
-package com.atmob.task.data;
-
-import com.atmob.task.bean.AdAppInfoData;
-import com.atmob.utils.MMKVUtils;
-import com.google.gson.Gson;
-
-public class LocalData {
-
-    private static final Gson gson = new Gson();
-
-    public static AdAppInfoData queryAdAppInfoByPackageName(String packageName) {
-        String key = String.format("adAppInfoData_%s", packageName);
-        return gson.fromJson(MMKVUtils.getString(key, ""), AdAppInfoData.class);
-    }
-}

+ 0 - 9
src/main/java/com/atmob/task/data/NetworkClient.java

@@ -1,9 +0,0 @@
-package com.atmob.task.data;
-
-import com.atmob.http.RetrofitClient;
-
-public class NetworkClient {
-    public static Api api() {
-        return RetrofitClient.getInstance().create(Api.class);
-    }
-}

+ 0 - 151
src/main/java/com/atmob/task/utils/ATLog.java

@@ -1,151 +0,0 @@
-package com.atmob.task.utils;
-
-import android.util.Log;
-
-public class ATLog {
-    private static final boolean LogEnable = true;
-
-    public static void v(String TAG, String format, Object... args) {
-        if (LogEnable) {
-            Log.v(TAG, String.format(format, args));
-        }
-    }
-
-    public static void v(String TAG, String format, Throwable tr, Object... args) {
-        if (LogEnable) {
-            Log.v(TAG, String.format(format, args), tr);
-        }
-    }
-
-    public static void v(String TAG, String msg) {
-        if (LogEnable) {
-            Log.v(TAG, msg);
-        }
-    }
-
-    public static void v(String TAG, String msg, Throwable tr) {
-        if (LogEnable) {
-            Log.v(TAG, msg, tr);
-        }
-    }
-
-    public static void i(String TAG, String format, Object... args) {
-        if (LogEnable) {
-            Log.i(TAG, String.format(format, args));
-        }
-    }
-
-    public static void i(String TAG, String format, Throwable tr, Object... args) {
-        if (LogEnable) {
-            Log.i(TAG, String.format(format, args), tr);
-        }
-    }
-
-    public static void i(String TAG, String msg) {
-        if (LogEnable) {
-            Log.i(TAG, msg);
-        }
-    }
-
-    public static void i(String TAG, String msg, Throwable tr) {
-        if (LogEnable) {
-            Log.i(TAG, msg, tr);
-        }
-    }
-
-    public static void d(String TAG, String format, Object... args) {
-        if (LogEnable) {
-            d(TAG, String.format(format, args));
-        }
-    }
-
-    public static void d(String TAG, String format, Throwable tr, Object... args) {
-        if (LogEnable) {
-            d(TAG, String.format(format, args), tr);
-        }
-    }
-
-    public static void d(String TAG, String msg) {
-        if (LogEnable) {
-            Log.d(TAG, msg);
-        }
-    }
-
-    public static void d(String TAG, String msg, Throwable tr) {
-        if (LogEnable) {
-            Log.d(TAG, msg, tr);
-        }
-    }
-
-    public static void w(String TAG, String format, Object... args) {
-        if (LogEnable) {
-            Log.w(TAG, String.format(format, args));
-        }
-    }
-
-    public static void w(String TAG, String format, Throwable tr, Object... args) {
-        if (LogEnable) {
-            Log.w(TAG, String.format(format, args), tr);
-        }
-    }
-
-    public static void w(String TAG, String msg) {
-        if (LogEnable) {
-            Log.w(TAG, msg);
-        }
-    }
-
-    public static void w(String TAG, String msg, Throwable tr) {
-        if (LogEnable) {
-            Log.w(TAG, msg, tr);
-        }
-    }
-
-    public static void e(String TAG, String format, Object... args) {
-        if (LogEnable) {
-            Log.e(TAG, String.format(format, args));
-        }
-    }
-
-    public static void e(String TAG, String format, Throwable tr, Object... args) {
-        if (LogEnable) {
-            Log.e(TAG, String.format(format, args), tr);
-        }
-    }
-
-    public static void e(String TAG, String msg) {
-        if (LogEnable) {
-            Log.e(TAG, msg);
-        }
-    }
-
-    public static void e(String TAG, String msg, Throwable tr) {
-        if (LogEnable) {
-            Log.e(TAG, msg, tr);
-        }
-    }
-
-    public static void wtf(String TAG, String format, Object... args) {
-        if (LogEnable) {
-            Log.wtf(TAG, String.format(format, args));
-        }
-    }
-
-    public static void wtf(String TAG, String format, Throwable tr, Object... args) {
-        if (LogEnable) {
-            Log.wtf(TAG, String.format(format, args), tr);
-        }
-    }
-
-    public static void wtf(String TAG, String msg) {
-        if (LogEnable) {
-            Log.wtf(TAG, msg);
-        }
-    }
-
-    public static void wtf(String TAG, String msg, Throwable tr) {
-        if (LogEnable) {
-            Log.wtf(TAG, msg, tr);
-        }
-    }
-}

BIN
src/main/res/drawable-xxhdpi/atmob_default_icon.png


+ 11 - 0
src/main/res/values/attrs.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <declare-styleable name="NormalProgressBar">
+        <attr name="NormalProgressBar_backgroundColor" format="color" />
+        <attr name="NormalProgressBar_progressColor" format="color" />
+        <attr name="NormalProgressBar_radius" format="dimension" />
+        <attr name="NormalProgressBar_showPercent" format="boolean" />
+        <attr name="NormalProgressBar_percentTextSize" format="dimension" />
+        <attr name="NormalProgressBar_percentTextColor" format="color" />
+    </declare-styleable>
+</resources>