前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记录两个神奇的android bug

记录两个神奇的android bug

作者头像
fengzhizi715
发布2018-08-24 16:19:41
6380
发布2018-08-24 16:19:41
举报

最近,收到两家大客户反馈的bug,都是我们android版本sdk报的bug。既然大客户给我们报bug了,那必须十分重视对待。

大客户必须重点关照.jpg

第一个bug,SecurityException: Permission denied (missing INTERNET permission?)

初看一下以为是网络权限的问题,难道客户没有添加网络的权限,这显然不可能。

从stackoverflow上搜到这篇文章很有帮助。大致了解出现这个bug的原因。

首先,android.permission.INTERNET并不是唯一的网络相关权限,还需要声明一下android.permission.ACCESS_NETWORK_STATE这个权限。这个权限对于sdk而言,我还是很纠结地,因为很多客户不一定会使用到这个权限。如果我多添加了这个权限的判断会导致一些客户无法使用sdk。

其次,在root过的设备上,用户可以通过工具来修改在运行时授予已安装应用的权限。同时,在某些定制的rom上也可以这么做的。

再次,Android 6.0以后引入了全新的权限管理机制,称为运行时权限。它允许用户更多地控制授予的权限(也允许选择性授予),或允许一个撤销已授予的权限,无需应用程序删除。

知道这个bug产生的原因之后,那我们来解决问题吧。

解决方案:

在调用网络框架之前,把请求网络的request放入框架中http请求的队列之前,先判断一下权限是否已经添加: <uses-permission android:name="android.permission.INTERNET" />

    public void addToRequestQueue(Request req) {

        if (!Util.checkPermission(MWConfiguration.getContext(), "android.permission.INTERNET")) {
            return;
        }

        getRequestQueue().addRequest(req);
    }

添加了完权限的判断之后,可以把影响降到最低。

第两个bug,java.lang.RuntimeException: Package manager has died

这个bug也很奇葩,是这段代码造成的

    /**
     * 获得当前应用的版本号
     *
     * @param context context
     * @return App Version
     */
    public static String getAppVersion(Context context) {
        String result = "1.0";
        PackageInfo info = null;
        try {
            info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
        } catch (NameNotFoundException ignored) {
        }
        if (info != null) {
            result = info.versionName;
        }
        return result;
    }

初看一下,没有任何问题。但为何会引起了异常呢? 它是一个Binder调用,造成这个的原因是因为发生了RemoteException。 如果Binder的使用超出了一个进程的限制就会抛TransactionTooLargeException这个异常。

通过查看源码发现,在一个进程中Binder的大小大约是1M。如果这时候恰巧在用getPackageManager()做其他事情,就会提示Package manager has died。

解决方案:

第一种办法,在getAppVersion()方法前加上synchronized。其他用到context.getPackageManager()的地方也尽量加上synchronized

第二种办法,第一次获取完appVersion这种数据后放在一个地方缓存起来。以后每次直接读取缓存中的数据。

总结

写sdk的上辈子都是折翼天使,希望以后再也不要写sdk了,让我先去哭一会儿去。当然这些是不可能的,写代码还是必须严谨再严谨啊。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.01.19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第一个bug,SecurityException: Permission denied (missing INTERNET permission?)
    • 解决方案:
    • 第两个bug,java.lang.RuntimeException: Package manager has died
      • 解决方案:
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档