Bläddra i källkod

修复了多个错误, 优化性能

zhipeng 3 år sedan
förälder
incheckning
502d8b545a

+ 10 - 1
build.gradle

@@ -11,7 +11,6 @@ android {
         versionCode 100
         versionName "1.0.0"
 
-        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
         consumerProguardFiles "consumer-rules.pro"
     }
 
@@ -25,6 +24,16 @@ 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 {

+ 4 - 1
consumer-rules.pro

@@ -2,4 +2,7 @@
 -keep class com.atmob.task.AppTaskView{
     public <methods>;
 }
--keep class com.atmob.task.utils.AppTaskHandler{*;}
+-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$*{*;}

+ 4 - 1
proguard-rules.pro

@@ -44,4 +44,7 @@
 -keep class com.atmob.task.AppTaskView{
     public <methods>;
 }
--keep class com.atmob.task.utils.AppTaskHandler{*;}
+-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$*{*;}

+ 9 - 9
src/main/java/com/atmob/task/AppTaskAdapter.java

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

+ 22 - 30
src/main/java/com/atmob/task/AppTaskView.java

@@ -4,8 +4,10 @@ import android.content.Context;
 import android.os.Handler;
 import android.os.Looper;
 import android.util.AttributeSet;
-import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
 
+import androidx.annotation.IdRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.recyclerview.widget.LinearLayoutManager;
@@ -17,8 +19,6 @@ 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.bean.AppTaskUpdateRequest;
-import com.atmob.task.bean.AppTaskUpdateResponse;
 import com.atmob.task.data.NetworkClient;
 import com.atmob.task.utils.AppTaskEvent;
 import com.atmob.task.view.TwinklingRecyclerView;
@@ -35,7 +35,7 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
 
     private CompositeDisposable compositeDisposable;
 
-    private AppTaskItemAdapter appTaskItemAdapter;
+    private AppTaskItemAdapter<? extends AppTaskViewHolder> appTaskItemAdapter;
 
     private OnAppTaskItemClickListener onAppTaskItemClickListener;
 
@@ -113,8 +113,8 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
         compositeDisposable.add(disposable);
     }
 
-    public void init(@NonNull AppTaskAdapter appTaskAdapter) {
-        appTaskItemAdapter = new AppTaskItemAdapter(appTaskAdapter, compositeDisposable);
+    public <T extends AppTaskViewHolder> void init(@NonNull AppTaskAdapter<T> appTaskAdapter) {
+        appTaskItemAdapter = new AppTaskItemAdapter<>(this, appTaskAdapter, compositeDisposable);
         appTaskItemAdapter.setOnItemActionCallback(this);
         super.setAdapter(appTaskItemAdapter);
     }
@@ -207,30 +207,6 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
     }
 
     @Override
-    public void updateStatus(long id, int targetStatus) {
-        NetworkClient.api().updateAppTaskStatus(new AppTaskUpdateRequest(id, targetStatus))
-                .compose(RxSchedulersUtils.observableIO2Main())
-                .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) {
-                        HttpFailManager.handleHttpFail(code, msg);
-                    }
-                });
-    }
-
-    @Override
     public void getReward(AppTaskBean appTaskBean) {
         if (onAppTaskRewardRequestListener != null) {
             onAppTaskRewardRequestListener.onReward(appTaskBean);
@@ -253,4 +229,20 @@ public class AppTaskView extends TwinklingRecyclerView implements AppTaskItemAda
          */
         void onClick(@AppTaskBean.AppTaskStatus int appTaskStatus);
     }
+
+    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);
+        }
+    }
 }

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

@@ -3,25 +3,29 @@ package com.atmob.task.adapter;
 import android.annotation.SuppressLint;
 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.TextView;
 import android.widget.Toast;
 
-import androidx.annotation.IdRes;
 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;
@@ -45,7 +49,7 @@ import atmob.io.reactivex.rxjava3.disposables.CompositeDisposable;
 import atmob.io.reactivex.rxjava3.disposables.Disposable;
 import atmob.io.reactivex.rxjava3.schedulers.Schedulers;
 
-public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.AppTaskItemViewHolder> {
+public class AppTaskItemAdapter<T extends AppTaskViewHolder> extends RecyclerView.Adapter<T> {
 
     private static final String TAG = AppTaskItemAdapter.class.getSimpleName();
 
@@ -62,32 +66,34 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
 
     private final CompositeDisposable compositeDisposable;
 
+    private RecyclerView recyclerView;
+
     private OnItemActionCallback onItemActionCallback;
 
-    private AppTaskAdapter appTaskAdapter;
+    private AppTaskAdapter<T> appTaskAdapter;
 
-    public AppTaskItemAdapter(AppTaskAdapter appTaskAdapter, CompositeDisposable compositeDisposable) {
+    public AppTaskItemAdapter(RecyclerView recyclerView, AppTaskAdapter<T> appTaskAdapter, CompositeDisposable compositeDisposable) {
         this.compositeDisposable = compositeDisposable;
         this.appTaskAdapter = appTaskAdapter;
+        this.recyclerView = recyclerView;
     }
 
     @NonNull
     @Override
-    public AppTaskItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+    public T onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
         if (appTaskAdapter == null) {
             throw new IllegalStateException("appTaskAdapter can't not be null.");
         }
-        View view = appTaskAdapter.onCreateView(LayoutInflater.from(parent.getContext()), parent);
-        AppTaskItemViewHolder appTaskItemViewHolder = new AppTaskItemViewHolder(view);
-        bindClickListener();
-        return appTaskItemViewHolder;
+        T appTaskViewHolder = appTaskAdapter.onCreateViewHolder(LayoutInflater.from(parent.getContext()), parent);
+        bindClickListener(appTaskViewHolder);
+        return appTaskViewHolder;
     }
 
-    private void bindClickListener() {
+    private void bindClickListener(T appTaskViewHolder) {
         if (appTaskAdapter == null) {
             throw new IllegalStateException("appTaskAdapter can't not be null.");
         }
-        View[] clickViews = appTaskAdapter.getClickViews();
+        View[] clickViews = appTaskAdapter.getClickViews(appTaskViewHolder);
         if (clickViews == null || clickViews.length == 0) {
             return;
         }
@@ -99,7 +105,7 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
 
     @SuppressLint("ResourceType")
     @Override
-    public void onBindViewHolder(@NonNull AppTaskItemViewHolder holder, int position) {
+    public void onBindViewHolder(@NonNull T holder, int position) {
         if (appTaskAdapter == null) {
             throw new IllegalStateException("appTaskAdapter can't not be null.");
         }
@@ -111,18 +117,18 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
         // app icon
         appTaskAdapter.onRenderAppIcon(holder, appTaskDownloadWrapper, appTaskDownloadWrapper.getAppIcon());
         // click view
-        setTag2ClickViews(appTaskDownloadWrapper);
+        setTag2ClickViews(holder, appTaskDownloadWrapper);
         // task status
         appTaskAdapter.onRenderTaskStatus(holder, appTaskDownloadWrapper, appTaskDownloadWrapper.getTaskStatus());
         // download progress
         appTaskAdapter.onRenderDownloadProgress(holder, appTaskDownloadWrapper.getTotal(), appTaskDownloadWrapper.getProgress());
     }
 
-    private void setTag2ClickViews(AppTaskDownloadWrapper appTaskDownloadWrapper) {
+    private void setTag2ClickViews(T holder, AppTaskDownloadWrapper appTaskDownloadWrapper) {
         if (appTaskAdapter == null) {
             throw new IllegalStateException("appTaskAdapter can't not be null.");
         }
-        View[] clickViews = appTaskAdapter.getClickViews();
+        View[] clickViews = appTaskAdapter.getClickViews(holder);
         if (clickViews != null && clickViews.length > 0) {
             for (View clickView : clickViews) {
                 clickView.setTag(appTaskDownloadWrapper);
@@ -131,18 +137,20 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
     }
 
     @Override
-    public void onBindViewHolder(@NonNull AppTaskItemViewHolder holder, int position, @NonNull List<Object> payloads) {
+    public void onBindViewHolder(@NonNull T holder, int position, @NonNull List<Object> payloads) {
         if (appTaskAdapter == null) {
             throw new IllegalStateException("appTaskAdapter can't not be null.");
         }
         AppTaskDownloadWrapper appTaskDownloadWrapper = asyncListDiffer.getCurrentList().get(position);
-        setTag2ClickViews(appTaskDownloadWrapper);
+        setTag2ClickViews(holder, appTaskDownloadWrapper);
         if (payloads.size() == 0) {
             onBindViewHolder(holder, position);
         } else {
             for (Object payload : payloads) {
                 Bundle bundle = (Bundle) payload;
-                for (String key : bundle.keySet()) {
+                Iterator<String> iterator = bundle.keySet().iterator();
+                while (iterator.hasNext()) {
+                    String key = iterator.next();
                     switch (key) {
                         case "payload_app_name":
                             appTaskAdapter.onRenderAppName(holder, appTaskDownloadWrapper, bundle.getString(key));
@@ -154,11 +162,11 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
                             appTaskAdapter.onDownloadStatusChanged(holder, bundle.getBoolean(key));
                             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"));
+                            iterator.remove();
                             break;
                     }
                 }
@@ -177,18 +185,15 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
         }
         switch (appTaskDownloadWrapper.getTaskStatus()) {
             case AppTaskBean.AppTaskStatus.Initial:
-                Log.d(TAG, "onAppTaskItemClick: toInstall.");
-                toInstall(appTaskDownloadWrapper);
-                break;
             case AppTaskBean.AppTaskStatus.Installed:
                 toOpen(appTaskDownloadWrapper);
-                Log.d(TAG, "onAppTaskItemClick: toOpen.");
+                ATLog.d(TAG, "onAppTaskItemClick: toOpen.");
                 break;
             case AppTaskBean.AppTaskStatus.Opened:
                 if (onItemActionCallback != null) {
                     onItemActionCallback.getReward(appTaskDownloadWrapper);
                 }
-                Log.d(TAG, "onAppTaskItemClick: getReward.");
+                ATLog.d(TAG, "onAppTaskItemClick: getReward.");
                 break;
             case AppTaskBean.AppTaskStatus.Finish:
                 //ignore
@@ -219,15 +224,13 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
         if (AppInfoUtils.isExistPackage(Utils.getContext(), appPkgName)) {
             AppTaskEvent.report(AppTaskEvent.ATE_LAUNCH);
             AppInfoUtils.launchApp(appPkgName);
-            if (onItemActionCallback != null) {
-                onItemActionCallback.updateStatus(appTaskDownloadWrapper.getId(), AppTaskBean.AppTaskStatus.Opened);
-            }
+            updateStatus(appTaskDownloadWrapper.getId(), AppTaskBean.AppTaskStatus.Opened);
             removeFromCheckList(appTaskDownloadWrapper.getId());
-            Log.d(TAG, "toOpen: app exist, open it.");
+            ATLog.d(TAG, "toOpen: app exist, open it.");
         } else {
             AppTaskEvent.report(AppTaskEvent.ATE_DOWNLOAD);
             toDownload(appTaskDownloadWrapper);
-            Log.d(TAG, "toOpen: app not exist, try to download.");
+            ATLog.d(TAG, "toOpen: app not exist, try to download.");
         }
     }
 
@@ -243,7 +246,7 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
                     String apkPath = adAppInfoData.getApkPath();
                     File file = new File(apkPath);
                     file = file.exists() && file.isFile() ? file : new File("");
-                    Log.d(TAG, "toInstall: sdk apk path ==> " + apkPath + ", file available ==> " + (!"".equals(file.getPath())));
+                    ATLog.d(TAG, "toInstall: sdk apk path ==> " + apkPath + ", file available ==> " + (!"".equals(file.getPath())));
                     return file;
                 })
                 .map(apkFile -> {
@@ -254,7 +257,7 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
                         if (downloadFile.exists() && downloadFile.isFile() && !checkFileOccupy(downloadFile)) {
                             apkFile = downloadFile;
                         }
-                        Log.d(TAG, "toInstall: download apk path ==> " + downloadFile.getPath() + ", file available ==> " + (!"".equals(apkFile.getPath())));
+                        ATLog.d(TAG, "toInstall: download apk path ==> " + downloadFile.getPath() + ", file available ==> " + (!"".equals(apkFile.getPath())));
                     }
                     if ("".equals(apkFile.getPath())) {
                         throw new Exception("none available apk file");
@@ -275,7 +278,7 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
                         InstallFaultToleranceUtils.installApk(Utils.getContext(), file, () -> {
                             AppTaskEvent.report(AppTaskEvent.ATE_DOWNLOAD);
                             toDownload(appTaskDownloadWrapper);
-                            Log.d(TAG, "toInstall: apk install failed, try to download");
+                            ATLog.d(TAG, "toInstall: apk install failed, try to download");
                         });
                         addToCheckList(appTaskDownloadWrapper);
                     }
@@ -285,7 +288,7 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
                         // local file not exist, try to download
                         AppTaskEvent.report(AppTaskEvent.ATE_DOWNLOAD);
                         toDownload(appTaskDownloadWrapper);
-                        Log.d(TAG, "toInstall: None available apk file, try to download, msg ==> " + e.getMessage());
+                        ATLog.d(TAG, "toInstall: None available apk file, try to download, msg ==> " + e.getMessage());
                     }
 
                     @Override
@@ -303,8 +306,8 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
                 appTaskDownloadWrapper.setDownloading(true);
                 Bundle bundle = new Bundle();
                 bundle.putBoolean("payload_downloading", true);
-                notifyItemChanged(asyncListDiffer.getCurrentList().indexOf(appTaskDownloadWrapper), bundle);
-                Log.d(TAG, "toDownload onStart: download start, task ==> " + appTaskDownloadWrapper);
+                notifyItem(appTaskDownloadWrapper, bundle);
+                ATLog.d(TAG, "toDownload onStart: download start, task ==> " + appTaskDownloadWrapper);
             }
 
             @Override
@@ -316,7 +319,7 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
                 bundle.putBoolean("payload_downloading", true);
                 bundle.putLong("payload_progress", progress);
                 bundle.putLong("payload_total", total);
-                notifyItemChanged(asyncListDiffer.getCurrentList().indexOf(appTaskDownloadWrapper), bundle);
+                notifyItem(appTaskDownloadWrapper, bundle);
             }
 
             @Override
@@ -326,8 +329,8 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
                 addToCheckList(appTaskDownloadWrapper);
                 Bundle bundle = new Bundle();
                 bundle.putBoolean("payload_downloading", false);
-                notifyItemChanged(asyncListDiffer.getCurrentList().indexOf(appTaskDownloadWrapper), bundle);
-                Log.d(TAG, "toDownload onComplete: download complete, task ==> " + appTaskDownloadWrapper);
+                notifyItem(appTaskDownloadWrapper, bundle);
+                ATLog.d(TAG, "toDownload onComplete: download complete, task ==> " + appTaskDownloadWrapper);
                 AppTaskEvent.report(AppTaskEvent.ATE_DOWNLOAD_SUCCESS);
             }
 
@@ -337,17 +340,24 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
                 Toast.makeText(Utils.getContext(), "下载失败,请重试", Toast.LENGTH_SHORT).show();
                 Bundle bundle = new Bundle();
                 bundle.putBoolean("payload_downloading", false);
-                notifyItemChanged(asyncListDiffer.getCurrentList().indexOf(appTaskDownloadWrapper), bundle);
-                Log.d(TAG, "toDownload onError: download error, msg ==> " + message + ", task ==> " + appTaskDownloadWrapper);
+                notifyItem(appTaskDownloadWrapper, bundle);
+                ATLog.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)
@@ -357,10 +367,12 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
                     @Override
                     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 onNext(@atmob.io.reactivex.rxjava3.annotations.NonNull AppTaskDownloadWrapper appTaskDownloadWrapper) {
+                        ATLog.d(TAG, "onNext() called with: appTaskDownloadWrapper = [" + appTaskDownloadWrapper + "]");
                         if (RetrofitDownloader.isActiveTaskExist(appTaskDownloadWrapper.getAppLink())) {
                             toDownload(appTaskDownloadWrapper);
                         }
@@ -369,20 +381,23 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
 
                     @Override
                     public void onError(@atmob.io.reactivex.rxjava3.annotations.NonNull Throwable e) {
-                        Log.e(TAG, "onError: AppTaskBean transform to AppTaskDownloadWrapper error", e);
+                        ATLog.e(TAG, "onError: AppTaskBean transform to AppTaskDownloadWrapper error", e);
                     }
 
                     @Override
                     public void onComplete() {
-                        Log.d(TAG, "onComplete: app task list update success, total length ==> " + appTaskDownloadWrappers.size());
+                        ATLog.d(TAG, "onComplete: app task list update success, total length ==> " + appTaskDownloadWrappers.size());
                         Collections.reverse(appTaskDownloadWrappers);
+                        if (appTaskDownloadWrappers.size() != asyncListDiffer.getCurrentList().size()) {
+                            recyclerView.setHasFixedSize(false);
+                        }
                         asyncListDiffer.submitList(appTaskDownloadWrappers);
                     }
                 });
     }
 
     public void checkAppExist() {
-        Log.d(TAG, "app resume, start checkAppExist()");
+        ATLog.d(TAG, "app resume, start checkAppExist()");
         Completable.fromAction(() -> {
             Iterator<Map.Entry<Long, String>> iterator = potentialInstalledList.entrySet().iterator();
             while (iterator.hasNext()) {
@@ -396,21 +411,17 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
                 boolean existPackage = AppInfoUtils.isExistPackage(Utils.getContext(), appTaskPackageName);
                 if (existPackage) {
                     if (FORCE_OPEN) {
-                        Log.d(TAG, "checkAppExist: app exist, open it. (id ==> " + appTaskId + ", packageName ==> " + appTaskPackageName + ")");
+                        ATLog.d(TAG, "checkAppExist: app exist, open it. (id ==> " + appTaskId + ", packageName ==> " + appTaskPackageName + ")");
                         AppTaskEvent.report(AppTaskEvent.ATE_CONFIRM_INSTALLED_LAUNCH);
                         AppInfoUtils.launchApp(appTaskPackageName);
-                        if (onItemActionCallback != null) {
-                            onItemActionCallback.updateStatus(appTaskId, AppTaskBean.AppTaskStatus.Opened);
-                        }
+                        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);
-                        }
+                        ATLog.d(TAG, "checkAppExist: app exist, just report. (id ==> " + appTaskId + ", packageName ==> " + appTaskPackageName + ")");
+                        updateStatus(appTaskId, AppTaskBean.AppTaskStatus.Installed);
                     }
                     iterator.remove();
                 } else {
-                    Log.d(TAG, "checkAppExist: app not exist. (id ==> " + appTaskId + ", packageName ==> " + appTaskPackageName + ")");
+                    ATLog.d(TAG, "checkAppExist: app not exist. (id ==> " + appTaskId + ", packageName ==> " + appTaskPackageName + ")");
                 }
             }
         })
@@ -439,12 +450,12 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
             return;
         }
         potentialInstalledList.put(appTaskBeanGet.getId(), appTaskBeanGet.getAppPkgName());
-        Log.d(TAG, "addToCheckList() called with: appTaskBeanGet = [" + appTaskBeanGet + "]");
+        ATLog.d(TAG, "addToCheckList() called with: appTaskBeanGet = [" + appTaskBeanGet + "]");
     }
 
     private void removeFromCheckList(long id) {
         potentialInstalledList.remove(id);
-        Log.d(TAG, "removeFromCheckList() called with: id = [" + id + "]");
+        ATLog.d(TAG, "removeFromCheckList() called with: id = [" + id + "]");
     }
 
     public void setOnItemActionCallback(OnItemActionCallback onItemActionCallback) {
@@ -453,8 +464,9 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
 
     public void release() {
         RetrofitDownloader.clearAllObserver();
+        recyclerView = null;
         appTaskAdapter = null;
-        Log.d(TAG, "release: clear all observer.");
+        ATLog.d(TAG, "release: clear all observer.");
     }
 
     public void triggerFirstTask() {
@@ -465,27 +477,48 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
             }
             if (appTaskDownloadWrapper.getTaskStatus() != AppTaskBean.AppTaskStatus.Opened && !appTaskDownloadWrapper.isDownloading()) {
                 onAppTaskItemClick(appTaskDownloadWrapper);
-                Log.d(TAG, "triggerFirstTask: task ==> " + appTaskDownloadWrapper);
+                ATLog.d(TAG, "triggerFirstTask: task ==> " + appTaskDownloadWrapper);
                 return;
             }
         }
-        Log.d(TAG, "triggerFirstTask: not has available task.");
+        ATLog.d(TAG, "triggerFirstTask: not has available task.");
     }
 
-    public static class AppTaskItemViewHolder extends RecyclerView.ViewHolder {
+    private void updateStatus(long id, int targetStatus) {
+        NetworkClient.api().updateAppTaskStatus(new AppTaskUpdateRequest(id, targetStatus))
+                .compose(RxSchedulersUtils.observableIO2Main())
+                .subscribe(new BaseHttpObserver<AppTaskUpdateResponse>() {
 
-        public AppTaskItemViewHolder(@NonNull View itemView) {
-            super(itemView);
-        }
+                    @Override
+                    public void onGotDisposable(Disposable disposable) {
+                        compositeDisposable.add(disposable);
+                    }
 
-        public void setText(@IdRes int id, CharSequence text) {
-            TextView textView = itemView.findViewById(id);
-            textView.setText(text);
-        }
+                    @Override
+                    public void onSuccess(AppTaskUpdateResponse data) {
+                        List<AppTaskDownloadWrapper> currentList = asyncListDiffer.getCurrentList();
+                        Iterator<AppTaskDownloadWrapper> iterator = currentList.iterator();
+                        while (iterator.hasNext()) {
+                            AppTaskDownloadWrapper next = iterator.next();
+                            if (next == null) {
+                                continue;
+                            }
+                            if (next.getId() == id) {
+                                int i = currentList.indexOf(next);
+                                iterator.remove();
+                                notifyItemRemoved(i);
+                                return;
+                            }
+                        }
+                        ATLog.d(TAG, "app task status update success, id ==> " + id + ", target status ==> " + targetStatus);
+                    }
 
-        public void setVisible(@IdRes int id, boolean visible) {
-            itemView.findViewById(id).setVisibility(visible ? View.VISIBLE : View.GONE);
-        }
+                    @Override
+                    public void onFailed(int code, String msg) {
+                        HttpFailManager.handleHttpFail(code, msg);
+                        ATLog.e(TAG, "app task status update failed, code ==> " + code + ", msg ==> " + msg);
+                    }
+                });
     }
 
     private static class DiffCallback extends DiffUtil.ItemCallback<AppTaskDownloadWrapper> {
@@ -540,8 +573,6 @@ public class AppTaskItemAdapter extends RecyclerView.Adapter<AppTaskItemAdapter.
     public interface OnItemActionCallback {
         void onClick(AppTaskBean appTaskBean);
 
-        void updateStatus(long id, int targetStatus);
-
         void getReward(AppTaskBean appTaskBean);
     }
 }

+ 4 - 24
src/main/java/com/atmob/task/bean/AppTaskControlResponse.java

@@ -1,7 +1,10 @@
 package com.atmob.task.bean;
 
+import com.google.gson.annotations.SerializedName;
+
 public class AppTaskControlResponse {
 
+    @SerializedName("pp")
     private Info pp;
 
     public Info getPp() {
@@ -13,34 +16,11 @@ public class AppTaskControlResponse {
     }
 
     public static class Info {
+        @SerializedName("pop")
         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;
-        }
     }
 }

+ 4 - 0
src/main/java/com/atmob/task/bean/AppTaskDataResponse.java

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

+ 4 - 0
src/main/java/com/atmob/task/bean/AppTaskUpdateRequest.java

@@ -1,12 +1,16 @@
 package com.atmob.task.bean;
 
 import com.atmob.request.CommonBaseRequest;
+import com.google.gson.annotations.SerializedName;
 
 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) {

+ 3 - 0
src/main/java/com/atmob/task/bean/AppTaskUpdateResponse.java

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

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

@@ -10,6 +10,6 @@ public class LocalData {
 
     public static AdAppInfoData queryAdAppInfoByPackageName(String packageName) {
         String key = String.format("adAppInfoData_%s", packageName);
-        return new Gson().fromJson(MMKVUtils.getString(key, ""), AdAppInfoData.class);
+        return gson.fromJson(MMKVUtils.getString(key, ""), AdAppInfoData.class);
     }
 }

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

@@ -0,0 +1,153 @@
+package com.atmob.task.utils;
+
+import android.util.Log;
+
+import com.atmob.task.BuildConfig;
+
+public class ATLog {
+    private static final boolean LogEnable = BuildConfig.DEBUG;
+
+    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);
+        }
+    }
+}

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

@@ -5,7 +5,6 @@ import androidx.annotation.IntDef;
 import com.atmob.http.BaseHttpObserver;
 import com.atmob.request.EventRequest;
 import com.atmob.task.data.NetworkClient;
-import com.atmob.utils.AdLog;
 import com.atmob.utils.RxSchedulersUtils;
 
 import atmob.io.reactivex.rxjava3.disposables.Disposable;
@@ -57,12 +56,12 @@ public class AppTaskEvent {
 
                     @Override
                     public void onSuccess(Object data) {
-                        AdLog.d("AppTaskEvent", "report success, eventId ==> " + eventId);
+                        ATLog.d("AppTaskEvent", "report success, eventId ==> " + eventId);
                     }
 
                     @Override
                     public void onFailed(int code, String msg) {
-                        AdLog.d("AppTaskEvent", "report failed, eventId ==> " + eventId);
+                        ATLog.d("AppTaskEvent", "report failed, eventId ==> " + eventId);
                     }
                 });
     }

+ 0 - 62
src/main/java/com/atmob/task/utils/AppTaskHandler.java

@@ -1,62 +0,0 @@
-package com.atmob.task.utils;
-
-import android.util.Log;
-
-import com.atmob.data.AdInjection;
-import com.atmob.http.BaseHttpObserver;
-import com.atmob.request.CommonBaseRequest;
-import com.atmob.response.AppTaskControlResponse;
-import com.atmob.utils.RxSchedulersUtils;
-
-import atmob.io.reactivex.rxjava3.disposables.CompositeDisposable;
-import atmob.io.reactivex.rxjava3.disposables.Disposable;
-
-/**
- * 提供一些关于积分墙的静态方法
- */
-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;
-        }
-        AdInjection.provideRepository().appTaskControlInfo(new CommonBaseRequest())
-                .compose(RxSchedulersUtils.observableIO2Main())
-                .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);
-    }
-}

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

@@ -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.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK);
             Uri contentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", apkFile);
             intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
         } else {