完成下载管理优化与下载异常修复的(1,2) https://gitlab.ghzs.com/pm/halo-app-issues/-/issues/873

This commit is contained in:
juntao
2020-05-26 16:33:13 +08:00
parent 27708da1bf
commit a286f51801
5 changed files with 179 additions and 57 deletions

View File

@ -11,6 +11,7 @@ import android.text.TextUtils;
import android.view.Window;
import android.view.WindowManager;
import com.gh.base.fragment.BaseFragment;
import com.gh.common.constant.Constants;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.MtaHelper;
@ -36,6 +37,7 @@ import java.lang.ref.WeakReference;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;
import butterknife.ButterKnife;
import pub.devrel.easypermissions.EasyPermissions;
@ -182,6 +184,11 @@ public abstract class BaseActivity extends BaseAppCompatActivity implements Easy
super.onPause();
if (isFinishing()) {
onFinish();
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
if (fragment.isAdded() && fragment instanceof BaseFragment) {
((BaseFragment) fragment).onParentActivityFinish();
}
}
}
}

View File

@ -9,14 +9,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.RecyclerView;
import com.gh.base.OnListClickListener;
import com.gh.base.OnRequestCallBackListener;
import com.gh.common.constant.Constants;
@ -37,6 +29,13 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.ButterKnife;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@ -304,6 +303,10 @@ public abstract class BaseFragment<T> extends Fragment implements OnRequestCallB
return this;
}
public void onParentActivityFinish() {
}
@Nullable
protected RecyclerView.Adapter provideSyncAdapter() {
return null;

View File

@ -62,7 +62,9 @@ public class DownloadManager implements DownloadStatusListener {
private static DownloadManager mInstance;
private static Gson gson = new Gson();
private static final String HINT_MARK = "hint_mark";
private static final String UPDATE_IS_READ_MARK = "update_is_read";
private static final String DOWNLOADING_IS_READ_MARK = "downloading_is_read";
private static final String DOWNLOADED_IS_READ_MARK = "downloaded_is_read";
private Context mContext;
private Handler mHandler;
@ -133,7 +135,7 @@ public class DownloadManager implements DownloadStatusListener {
mContext = context.getApplicationContext();
mDownloadDao = DownloadDao.getInstance(mContext);
mUpdateMarks = SPUtils.getStringSet(HINT_MARK);
mUpdateMarks = SPUtils.getStringSet(UPDATE_IS_READ_MARK);
//TODO unregister this
DownloadStatusManager.getInstance().registerTaskStatusListener(this);
@ -266,13 +268,13 @@ public class DownloadManager implements DownloadStatusListener {
}
downloadEntity.setPlugin(!TextUtils.isEmpty(apkEntity.getGhVersion()));
ExposureUtils.DownloadType downloadType = ExposureUtils.getDownloadType(apkEntity, gameEntity.getId());
ExposureEvent downloadExposureEvent = ExposureUtils.logADownloadExposureEvent(gameEntity, gameEntity.getPlatform(), traceEvent, downloadType);
// 将下载事件放入 downloadEntity 中供下载完成时取出使用
downloadEntity.setExposureTrace(gson.toJson(downloadExposureEvent));
if (isSubscribe) {
DownloadManager.getInstance(context).subscribe(downloadEntity);
} else {
@ -287,6 +289,7 @@ public class DownloadManager implements DownloadStatusListener {
//TODO remove
DownloadManager.getInstance(context).putStatus(downloadEntity.getUrl(), DownloadStatus.downloading);
DownloadManager.getInstance(context).markDownloadingTaskAsUnread();
// 收集下载数据
DataCollectionUtils.uploadDownload(context, downloadEntity, "开始");
GdtHelper.INSTANCE.logAction(ActionType.DOWNLOAD_APP,
@ -706,19 +709,26 @@ public class DownloadManager implements DownloadStatusListener {
*/
@Nullable
public String getDownloadOrUpdateCount(List<GameUpdateEntity> updateList) {
boolean containsReadDownloadingTask = false; // 存在已读的下载中任务
boolean showRedPoint = false;
int downloadingSize = 0;
for (DownloadEntity downloadEntity : getAll()) {
if (DownloadStatus.done.equals(downloadEntity.getStatus())) {
String mark = downloadEntity.getMeta().get(HINT_MARK);
String mark = downloadEntity.getMeta().get(DOWNLOADED_IS_READ_MARK);
if (TextUtils.isEmpty(mark)) showRedPoint = true;
} else {
// 存在已读的下载中任务就直接不返回下载中数量,因为在新建下载时就执行了将所有下载中任务的已读变为未读的操作
if (!TextUtils.isEmpty(downloadEntity.getMeta().get(DOWNLOADING_IS_READ_MARK))) {
containsReadDownloadingTask = true;
}
downloadingSize++;
}
}
if (downloadingSize != 0) return String.valueOf(downloadingSize);
if (downloadingSize != 0 && !containsReadDownloadingTask) {
return String.valueOf(downloadingSize);
}
if (showRedPoint) return "";
@ -733,6 +743,31 @@ public class DownloadManager implements DownloadStatusListener {
return null;
}
public int getUnreadUpdateCount(List<GameUpdateEntity> updateList) {
int unreadUpdateCount = 0;
if (updateList != null) {
for (GameUpdateEntity updateEntity : updateList) {
if (updateEntity.isShowPlugin(PluginLocation.only_index)
&& !mUpdateMarks.contains(updateEntity.getId() + updateEntity.getPackageName())) {
unreadUpdateCount++;
}
}
}
return unreadUpdateCount;
}
public boolean isContainsUnreadDownloadedTask() {
for (DownloadEntity downloadEntity : getAll()) {
if (DownloadStatus.done.equals(downloadEntity.getStatus())) {
String mark = downloadEntity.getMeta().get(DOWNLOADED_IS_READ_MARK);
if (TextUtils.isEmpty(mark)) {
return true;
}
}
}
return false;
}
/**
* 标记下载已完成的任务为已读 (用于下载管理页入口的 toolbar 红点显示)
*/
@ -744,9 +779,54 @@ public class DownloadManager implements DownloadStatusListener {
for (DownloadEntity downloadEntity : all) {
DownloadStatus status = downloadEntity.getStatus();
if (status == DownloadStatus.done) {
String mark = downloadEntity.getMeta().get(HINT_MARK);
String mark = downloadEntity.getMeta().get(DOWNLOADED_IS_READ_MARK);
if (TextUtils.isEmpty(mark)) {
downloadEntity.getMeta().put(HINT_MARK, HINT_MARK);
downloadEntity.getMeta().put(DOWNLOADED_IS_READ_MARK, DOWNLOADED_IS_READ_MARK);
mDownloadDao.newOrUpdate(downloadEntity);
if (!markHasChanged) markHasChanged = true;
}
}
}
if (markHasChanged) {
EventBus.getDefault().post(new EBDownloadStatus("download", "", "", "", "", ""));
}
});
}
/**
* 标记下载中任务为已读状态 (用于下载管理页入口的 toolbar 红点显示)
*/
public void markDownloadingTaskAsRead() {
markDownloadingTaskAsReadOrUnread(true);
}
/**
* 标记下载中任务为未读状态 (用于下载管理页入口的 toolbar 红点显示)
*/
public void markDownloadingTaskAsUnread() {
markDownloadingTaskAsReadOrUnread(false);
}
/**
* 更改下载中任务为已读状态 (用于下载管理页入口的 toolbar 红点显示)
*/
private void markDownloadingTaskAsReadOrUnread(boolean isRead) {
AppExecutor.getIoExecutor().execute(() -> {
boolean markHasChanged = false;
List<DownloadEntity> all = getAll();
for (DownloadEntity downloadEntity : all) {
if (downloadEntity.getStatus() != DownloadStatus.done) {
if (isRead) {
String mark = downloadEntity.getMeta().get(DOWNLOADING_IS_READ_MARK);
if (TextUtils.isEmpty(mark)) {
downloadEntity.getMeta().put(DOWNLOADING_IS_READ_MARK, DOWNLOADING_IS_READ_MARK);
mDownloadDao.newOrUpdate(downloadEntity);
if (!markHasChanged) markHasChanged = true;
}
} else {
downloadEntity.getMeta().put(DOWNLOADING_IS_READ_MARK, "");
mDownloadDao.newOrUpdate(downloadEntity);
if (!markHasChanged) markHasChanged = true;
}
@ -788,7 +868,7 @@ public class DownloadManager implements DownloadStatusListener {
public void saveUpdateMarkToStorage() {
ArrayList<GameUpdateEntity> updates = PackageRepository.INSTANCE.getGameUpdate();
if (updates.size() == mUpdateMarks.size()) {
SPUtils.setStringSet(HINT_MARK, mUpdateMarks);
SPUtils.setStringSet(UPDATE_IS_READ_MARK, mUpdateMarks);
return;
}
@ -797,7 +877,7 @@ public class DownloadManager implements DownloadStatusListener {
String mark = update.getId() + update.getPackageName();
marks.add(mark);
}
SPUtils.setStringSet(HINT_MARK, marks);
SPUtils.setStringSet(UPDATE_IS_READ_MARK, marks);
}
public void updateDownloadEntity(DownloadEntity downloadEntity) {

View File

@ -11,6 +11,7 @@ import androidx.fragment.app.Fragment
import com.gh.base.fragment.BaseFragment_TabLayout
import com.gh.common.util.MtaHelper
import com.gh.common.util.dip2px
import com.gh.common.util.visibleIf
import com.gh.download.DownloadManager
import com.gh.gamecenter.DownloadManagerActivity
import com.gh.gamecenter.R
@ -33,8 +34,19 @@ class DownloadFragment : BaseFragment_TabLayout() {
const val INDEX_UPDATE = 1
}
lateinit var mDownloadNumber: TextView
lateinit var mUpdateNumber: TextView
// 下载 tab 是否被手动选中过
private var mIsDownloadTabHasBeenSelected: Boolean = false
private var mIsUpdateTabHasBeenSelected: Boolean = false
private lateinit var mDownloadNumber: TextView
private lateinit var mUpdateNumber: TextView
private lateinit var mDownloadManager: DownloadManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mDownloadManager = DownloadManager.getInstance(HaloApp.getInstance().application)
}
override fun initFragmentList(fragments: MutableList<Fragment>) {
fragments.add(GameDownloadFragment())
@ -67,14 +79,17 @@ class DownloadFragment : BaseFragment_TabLayout() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setUpdateHint()
setDownloadHint()
updateUpdateHint()
updateDownloadHint()
if (mDownloadNumber.visibility != View.VISIBLE) {
if (mDownloadNumber.visibility != View.VISIBLE && mUpdateNumber.visibility == View.VISIBLE) {
mViewPager.currentItem = INDEX_UPDATE
} else {
// 进入并选中下载管理时立马标记已下载待安装为已读
DownloadManager.getInstance(HaloApp.getInstance().application).markDownloadedTaskAsRead()
mIsDownloadTabHasBeenSelected = true
updateDownloadHint()
mDownloadManager.markDownloadingTaskAsRead()
mDownloadManager.markDownloadedTaskAsRead()
}
}
@ -84,11 +99,14 @@ class DownloadFragment : BaseFragment_TabLayout() {
DownloadManager.getInstance(requireContext()).checkRetryDownload()
}
override fun onStop() {
super.onStop()
override fun onParentActivityFinish() {
super.onParentActivityFinish()
// onDestory 的回调有点晚,不能及时更新外部红点
DownloadManager.getInstance(HaloApp.getInstance().application).markDownloadedTaskAsRead()
// onDestroy 的回调有点晚,不能及时更新外部红点
if (mIsDownloadTabHasBeenSelected || mViewPager.currentItem == INDEX_DOWNLOAD) {
mDownloadManager.markDownloadingTaskAsRead()
mDownloadManager.markDownloadedTaskAsRead()
}
}
override fun onPageSelected(index: Int) {
@ -101,7 +119,13 @@ class DownloadFragment : BaseFragment_TabLayout() {
}
if (index == INDEX_UPDATE) {
DownloadManager.getInstance(HaloApp.getInstance().application).markUpdatableTaskAsRead()
mIsUpdateTabHasBeenSelected = true
updateUpdateHint()
mDownloadManager.markUpdatableTaskAsRead()
} else if (index == INDEX_DOWNLOAD) {
mIsDownloadTabHasBeenSelected = true
updateDownloadHint()
mDownloadManager.markDownloadingTaskAsRead()
}
MtaHelper.onEvent("下载管理", "Tab", tabName)
@ -117,13 +141,13 @@ class DownloadFragment : BaseFragment_TabLayout() {
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(changed: EBDownloadChanged) {
if ("download" == changed.type) {
setDownloadHint()
updateDownloadHint()
} else if ("update" == changed.type) {
setUpdateHint()
updateUpdateHint()
}
}
private fun setDownloadHint() {
private fun updateDownloadHint() {
val downloadData = DownloadManager.getInstance(context).all
if (downloadData.size > 0) {
mDownloadNumber.visibility = View.VISIBLE
@ -140,31 +164,35 @@ class DownloadFragment : BaseFragment_TabLayout() {
}
val layoutParams = mDownloadNumber.layoutParams as LinearLayout.LayoutParams
if (downloadingCount > 0) {
layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
layoutParams.setMargins(4F.dip2px(), 0, 0, 0F.dip2px())
mDownloadNumber.setBackgroundColor(Color.TRANSPARENT)
mDownloadNumber.text = downloadingCount.toString()
} else {
layoutParams.width = 6F.dip2px()
layoutParams.height = 6F.dip2px()
layoutParams.setMargins(2F.dip2px(), 0, 0, 3F.dip2px())
mDownloadNumber.setBackgroundResource(R.drawable.oval_hint_red_bg)
mDownloadNumber.text = ""
when {
downloadingCount > 0 -> {
layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
layoutParams.setMargins(4F.dip2px(), 0, 0, 0F.dip2px())
mDownloadNumber.setBackgroundColor(Color.TRANSPARENT)
mDownloadNumber.text = downloadingCount.toString()
}
mDownloadManager.isContainsUnreadDownloadedTask -> {
layoutParams.width = 6F.dip2px()
layoutParams.height = 6F.dip2px()
layoutParams.setMargins(2F.dip2px(), 0, 0, 3F.dip2px())
mDownloadNumber.setBackgroundResource(R.drawable.oval_hint_red_bg)
mDownloadNumber.text = ""
}
else -> mDownloadNumber.visibility = View.GONE
}
mDownloadNumber.layoutParams = layoutParams
}
private fun setUpdateHint() {
var updateSize = 0
for (updateEntity in PackagesManager.getUpdateList()) {
if (updateEntity.isShowPlugin(PluginLocation.only_index)) updateSize++
private fun updateUpdateHint() {
if (mIsUpdateTabHasBeenSelected) {
mUpdateNumber.visibility = View.INVISIBLE
return
}
mUpdateNumber.visibility = if (updateSize != 0) {
View.VISIBLE
} else View.INVISIBLE
val updateCount = mDownloadManager.getUnreadUpdateCount(PackagesManager.getUpdateList().filter { it.isShowPlugin(PluginLocation.only_index) })
mUpdateNumber.visibleIf(updateCount != 0)
}
@Subscribe(threadMode = ThreadMode.MAIN)

View File

@ -12,11 +12,6 @@ import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.gh.common.util.BitmapUtils;
import com.gh.common.util.DataUtils;
import com.gh.common.util.DialogUtils;
@ -50,6 +45,10 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
/**
* Created by LGT on 2016/8/15.
@ -155,6 +154,11 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter<ViewHolder> {
downloadTitle = downloadEntity.getName() + " - " + platform;
}
}
if (!TextUtils.isEmpty(downloadEntity.getVersionName())) {
downloadTitle = downloadTitle + " - V" + downloadEntity.getVersionName();
}
if (!viewHolder.dmTitle.getText().equals(downloadTitle)) {
viewHolder.dmTitle.setText(downloadTitle);
}