From 8a54c47d9eec57730ce9b193d9fba859fca8abc8 Mon Sep 17 00:00:00 2001
From: juntao <chenjuntao@ghzhushou.com>
Date: Thu, 28 Jan 2021 15:44:26 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=97=AA=E9=80=80=E9=97=AE?=
 =?UTF-8?q?=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

1. 捕抓个别 vivo 设备初始化下载证书时拿不到文件的闪退
2. 捕抓 ViewPager 和 ScrollView 在部分设备上多指操作的闪退
3. 捕抓接收商店应用跳转时链接格式不支持造成的闪退
4. 修复光环应用内更新弹窗关闭弹窗后偶发的闪退
5. 修复游戏评分列表数据更新时偶发的闪退
6. 修复下载管理已安装列表更新排序时偶发的闪退
7. 捕抓搜索历史数据库/日志上报数据库因为磁盘空间不足引起的闪退
8. 捕抓内存回收对象时因为系统缺陷导致的超时闪退
---
 .../java/com/gh/base/AppUncaughtHandler.java  | 23 +++++++++++--------
 .../java/com/gh/common/loghub/LoghubUtils.kt  |  6 +++--
 .../com/gh/common/view/FixedScrollView.kt     | 13 ++++++++---
 .../java/com/gh/gamecenter/SkipActivity.java  |  7 +++++-
 .../gh/gamecenter/db/DataCollectionDao.java   | 19 +++++++--------
 .../java/com/gh/gamecenter/db/FilterDao.java  | 18 +++++++--------
 .../gh/gamecenter/db/SearchHistoryDao.java    | 11 ++++-----
 .../InstalledGameFragmentAdapter.java         |  6 ++++-
 .../gamedetail/rating/RatingAdapter.kt        |  2 +-
 .../gh/gamecenter/manager/UpdateManager.java  |  6 ++++-
 libraries/LGLibrary                           |  2 +-
 11 files changed, 69 insertions(+), 44 deletions(-)

diff --git a/app/src/main/java/com/gh/base/AppUncaughtHandler.java b/app/src/main/java/com/gh/base/AppUncaughtHandler.java
index 16dc54f472..3163205954 100644
--- a/app/src/main/java/com/gh/base/AppUncaughtHandler.java
+++ b/app/src/main/java/com/gh/base/AppUncaughtHandler.java
@@ -25,6 +25,7 @@ import java.lang.Thread.UncaughtExceptionHandler;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
+import java.util.concurrent.TimeoutException;
 
 import io.sentry.core.Sentry;
 
@@ -38,19 +39,21 @@ public class AppUncaughtHandler implements UncaughtExceptionHandler {
     }
 
     @Override
-    public void uncaughtException(Thread thread, Throwable ex) {
-        new Thread(new Runnable() {
-            @Override
-            public void run() {
+    public void uncaughtException(Thread t, Throwable e) {
+        if (("FinalizerWatchdogDaemon").equals(t.getName())
+            && e instanceof TimeoutException) {
+            // ignore timeoutException
+            // detail can be found in this didi tech blog post https://mp.weixin.qq.com/s?__biz=MzU1ODEzNjI2NA==&mid=2247487185&idx=2&sn=cf2d9e10053f625bde0f61d246f14870&source=41#wechat_redirect
+        } else {
+            new Thread(() -> {
                 Looper.prepare();
                 Utils.toast(mContext.getApplicationContext(), "\"光环助手\"发生错误");
                 Looper.loop();
-            }
-        });
-
-        saveLocalLog(mContext, ex);
-        Sentry.captureException(ex);
-        restart(mContext);
+            });
+            saveLocalLog(mContext, e);
+            restart(mContext);
+            Sentry.captureException(e);
+        }
     }
 
     public static void restart(final Context context) {
diff --git a/app/src/main/java/com/gh/common/loghub/LoghubUtils.kt b/app/src/main/java/com/gh/common/loghub/LoghubUtils.kt
index 89d5f317be..e113fb2b1d 100644
--- a/app/src/main/java/com/gh/common/loghub/LoghubUtils.kt
+++ b/app/src/main/java/com/gh/common/loghub/LoghubUtils.kt
@@ -25,8 +25,10 @@ object LoghubUtils {
         mApplication = application
 
         loghubEventExecutor.execute {
-            val eventList = loghubEventDao.getAll()
-            loghubEventSet.addAll(eventList)
+            tryWithDefaultCatch {
+                val eventList = loghubEventDao.getAll()
+                loghubEventSet.addAll(eventList)
+            }
         }
     }
 
diff --git a/app/src/main/java/com/gh/common/view/FixedScrollView.kt b/app/src/main/java/com/gh/common/view/FixedScrollView.kt
index dbcfdb2525..0627f3ffd1 100644
--- a/app/src/main/java/com/gh/common/view/FixedScrollView.kt
+++ b/app/src/main/java/com/gh/common/view/FixedScrollView.kt
@@ -4,6 +4,7 @@ import android.content.Context
 import android.util.AttributeSet
 import android.view.MotionEvent
 import android.widget.ScrollView
+import java.lang.IllegalArgumentException
 
 /**
  * 不能滑动的 ScrollView
@@ -11,10 +12,16 @@ import android.widget.ScrollView
 class FixedScrollView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : ScrollView(context, attrs) {
 
     override fun onTouchEvent(ev: MotionEvent?): Boolean {
-        return when (ev?.action) {
-            MotionEvent.ACTION_DOWN -> true
-            else -> super.onTouchEvent(ev)
+        // super.onTouchEvent may cause IllegalArgumentException which is crazy!
+        try {
+            return when (ev?.action) {
+                MotionEvent.ACTION_DOWN -> true
+                else -> super.onTouchEvent(ev)
+            }
+        } catch (e: IllegalArgumentException) {
+            e.printStackTrace()
         }
+        return false
     }
 
     override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
diff --git a/app/src/main/java/com/gh/gamecenter/SkipActivity.java b/app/src/main/java/com/gh/gamecenter/SkipActivity.java
index 0f7231a3e1..b31efe1081 100644
--- a/app/src/main/java/com/gh/gamecenter/SkipActivity.java
+++ b/app/src/main/java/com/gh/gamecenter/SkipActivity.java
@@ -389,7 +389,12 @@ public class SkipActivity extends BaseActivity {
                 }
             } else if ("market".equals(uri.getScheme())) {
                 String host = uri.getHost();
-                String id = uri.getQueryParameter("id");
+                String id = "";
+                try {
+                    id = uri.getQueryParameter("id");
+                } catch (UnsupportedOperationException e) {
+                    e.printStackTrace();
+                }
                 if (host != null) {
                     if ("details".equals(host)) {
                         bundle = new Bundle();
diff --git a/app/src/main/java/com/gh/gamecenter/db/DataCollectionDao.java b/app/src/main/java/com/gh/gamecenter/db/DataCollectionDao.java
index d0a9fc4b26..91e8751e94 100644
--- a/app/src/main/java/com/gh/gamecenter/db/DataCollectionDao.java
+++ b/app/src/main/java/com/gh/gamecenter/db/DataCollectionDao.java
@@ -8,6 +8,7 @@ import com.j256.ormlite.dao.Dao;
 import java.sql.SQLException;
 import java.util.List;
 
+// TODO 这个数据库其实没有用了，上传到 loghub 已经有相关的逻辑处理，有空删掉它
 public class DataCollectionDao {
 
     private DatabaseHelper helper;
@@ -17,7 +18,7 @@ public class DataCollectionDao {
         try {
             helper = DatabaseHelper.getHelper(context);
             dao = helper.getDao(DataCollectionInfo.class);
-        } catch (SQLException | IllegalStateException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
@@ -28,7 +29,7 @@ public class DataCollectionDao {
     public List<DataCollectionInfo> findByType(String type) {
         try {
             return dao.queryForEq("type", type);
-        } catch (SQLException | IllegalStateException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
         return null;
@@ -40,7 +41,7 @@ public class DataCollectionDao {
     public void add(DataCollectionInfo entity) {
         try {
             dao.create(entity);
-        } catch (SQLException | IllegalStateException e) {
+        } catch (Exception e) {
             // java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:
             e.printStackTrace();
         }
@@ -52,7 +53,7 @@ public class DataCollectionDao {
     public void delete(String id) {
         try {
             dao.deleteById(id);
-        } catch (SQLException | IllegalStateException e) {
+        } catch (Exception e) {
             // java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:
             e.printStackTrace();
         }
@@ -64,7 +65,7 @@ public class DataCollectionDao {
     public void delete(List<String> ids) {
         try {
             dao.deleteIds(ids);
-        } catch (SQLException | IllegalStateException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
@@ -75,7 +76,7 @@ public class DataCollectionDao {
     public DataCollectionInfo find(String id) {
         try {
             return dao.queryForId(id);
-        } catch (SQLException | IllegalStateException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
         return null;
@@ -87,7 +88,7 @@ public class DataCollectionDao {
     public List<DataCollectionInfo> getAll() {
         try {
             return dao.queryForAll();
-        } catch (SQLException | IllegalStateException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
         return null;
@@ -99,7 +100,7 @@ public class DataCollectionDao {
     public List<DataCollectionInfo> getClickData() {
         try {
             return dao.queryForEq("type", "click-item");
-        } catch (SQLException | IllegalStateException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
         return null;
@@ -111,7 +112,7 @@ public class DataCollectionDao {
     public void update(DataCollectionInfo entity) {
         try {
             dao.update(entity);
-        } catch (SQLException | IllegalStateException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
diff --git a/app/src/main/java/com/gh/gamecenter/db/FilterDao.java b/app/src/main/java/com/gh/gamecenter/db/FilterDao.java
index 6b4579782f..746cd73fad 100644
--- a/app/src/main/java/com/gh/gamecenter/db/FilterDao.java
+++ b/app/src/main/java/com/gh/gamecenter/db/FilterDao.java
@@ -19,7 +19,7 @@ public class FilterDao {
         try {
             helper = DatabaseHelper.getHelper(context);
             dao = helper.getDao(PackageInfo.class);
-        } catch (SQLiteException | SQLException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
@@ -32,7 +32,7 @@ public class FilterDao {
             if (list != null && list.size() != 0) {
                 return list.get(0).getTime();
             }
-        } catch (SQLiteException | SQLException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
         return 0;
@@ -44,7 +44,7 @@ public class FilterDao {
             if (filterEntity != null) {
                 return true;
             }
-        } catch (SQLiteException | SQLException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
         return false;
@@ -56,7 +56,7 @@ public class FilterDao {
     public void add(PackageInfo entity) {
         try {
             dao.create(entity);
-        } catch (SQLiteException | SQLException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
@@ -68,7 +68,7 @@ public class FilterDao {
     public void addAll(List<PackageInfo> list) {
         try {
             dao.create(list);
-        } catch (SQLiteException | SQLException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
@@ -76,7 +76,7 @@ public class FilterDao {
     public void deleteAll(List<PackageInfo> list) {
         try {
             dao.delete(list);
-        } catch (SQLiteException | SQLException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
@@ -87,7 +87,7 @@ public class FilterDao {
     public void delete(String packageName) {
         try {
             dao.deleteById(packageName);
-        } catch (SQLiteException | SQLException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
@@ -98,7 +98,7 @@ public class FilterDao {
     public List<PackageInfo> getAll() {
         try {
             return dao.queryForAll();
-        } catch (SQLiteException | SQLException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
         return null;
@@ -110,7 +110,7 @@ public class FilterDao {
     public long getCount() {
         try {
             return dao.countOf();
-        } catch (SQLiteException | SQLException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
         return 0;
diff --git a/app/src/main/java/com/gh/gamecenter/db/SearchHistoryDao.java b/app/src/main/java/com/gh/gamecenter/db/SearchHistoryDao.java
index 3b191c2ae9..7625a2ce28 100644
--- a/app/src/main/java/com/gh/gamecenter/db/SearchHistoryDao.java
+++ b/app/src/main/java/com/gh/gamecenter/db/SearchHistoryDao.java
@@ -6,7 +6,6 @@ import com.gh.gamecenter.db.info.SearchHistoryInfo;
 import com.j256.ormlite.dao.CloseableIterator;
 import com.j256.ormlite.dao.Dao;
 
-import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -20,7 +19,7 @@ public class SearchHistoryDao {
         try {
             helper = DatabaseHelper.getHelper(context);
             dao = helper.getDao(SearchHistoryInfo.class);
-        } catch (SQLException e) {
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
@@ -28,7 +27,7 @@ public class SearchHistoryDao {
     public void add(String item) {
         try {
             dao.createOrUpdate(new SearchHistoryInfo(item));
-        } catch (SQLException e) {
+        } catch (Exception e) {
 
             e.printStackTrace();
         }
@@ -37,7 +36,7 @@ public class SearchHistoryDao {
     public void delete(String item) {
         try {
             dao.deleteById(item);
-        } catch (SQLException e) {
+        } catch (Exception e) {
 
             e.printStackTrace();
         }
@@ -49,7 +48,7 @@ public class SearchHistoryDao {
         while (iterator.hasNext()) {
             try {
                 dao.delete(iterator.next());
-            } catch (SQLException e) {
+            } catch (Exception e) {
 
                 e.printStackTrace();
             }
@@ -66,7 +65,7 @@ public class SearchHistoryDao {
             while (hisIterator.hasNext()) {
                 history.add(hisIterator.next().getItem());
             }
-        } catch (SQLException e) {
+        } catch (Exception e) {
 
             e.printStackTrace();
         }
diff --git a/app/src/main/java/com/gh/gamecenter/download/InstalledGameFragmentAdapter.java b/app/src/main/java/com/gh/gamecenter/download/InstalledGameFragmentAdapter.java
index 326ce99ba7..f12b1080af 100644
--- a/app/src/main/java/com/gh/gamecenter/download/InstalledGameFragmentAdapter.java
+++ b/app/src/main/java/com/gh/gamecenter/download/InstalledGameFragmentAdapter.java
@@ -112,7 +112,11 @@ public class InstalledGameFragmentAdapter extends BaseRecyclerAdapter<ViewHolder
             mFragment.loadEmpty();
         } else {
             List<String> ids = new ArrayList<>();
-            Collections.sort(sortedList, (lhs, rhs) -> {  // 按安装时间排序
+            Collections.sort(sortedList, (lhs, rhs) -> {
+                if (rhs == null || lhs == null) {
+                    return 0;
+                }
+                // 按安装时间排序
                 if (rhs.getInstallTime() > lhs.getInstallTime()) {
                     return 1;
                 } else if (rhs.getInstallTime() < lhs.getInstallTime()) {
diff --git a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingAdapter.kt b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingAdapter.kt
index 2934b8c554..b13c351ac8 100644
--- a/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingAdapter.kt
+++ b/app/src/main/java/com/gh/gamecenter/gamedetail/rating/RatingAdapter.kt
@@ -302,7 +302,7 @@ class RatingAdapter(context: Context,
                         null
                     }
                     else -> {
-                        mEntityList[dataPosition]
+                        mEntityList.safelyGetInRelease(dataPosition)
                     }
                 }
                 if (requestCode == RatingFragment.RATING_PATCH_REQUEST) {
diff --git a/app/src/main/java/com/gh/gamecenter/manager/UpdateManager.java b/app/src/main/java/com/gh/gamecenter/manager/UpdateManager.java
index 3faa10e0b8..eb6e11901a 100644
--- a/app/src/main/java/com/gh/gamecenter/manager/UpdateManager.java
+++ b/app/src/main/java/com/gh/gamecenter/manager/UpdateManager.java
@@ -130,7 +130,11 @@ public class UpdateManager {
                     if (DownloadStatus.done.equals(downloadEntity.getStatus())) {
                         DownloadManager.getInstance(mContext).cancel(downloadEntity.getUrl(), false, true);
                         if (downloadDialog != null) {
-                            downloadDialog.dismiss();
+                            try {
+                                downloadDialog.dismiss();
+                            } catch (IllegalArgumentException ignored) {
+                                // do nothing
+                            }
                         }
                         if (appEntity != null && appEntity.isForce()) {
                             AppExecutor.getUiExecutor().executeWithDelay(() -> exitApp(), 1000);
diff --git a/libraries/LGLibrary b/libraries/LGLibrary
index 8381904c6a..f6b6c6c5ac 160000
--- a/libraries/LGLibrary
+++ b/libraries/LGLibrary
@@ -1 +1 @@
-Subproject commit 8381904c6a1b3ab435bf8a4e5d362b9788c3ead7
+Subproject commit f6b6c6c5acacb296bb895aecdfc9268cc08f18b4
