飞了起来 发布的文章

最近支持项目的时候,发现一个问题,打开webview的时候,一直弹出自定义的页面,提示网页错误,未响应的问题。因为写了自定义webview加载超时也是显示这个页面,所以在处理bug时,不由的跑歪了方向,最后发现是标题500导致的错误。

本来这个问题,当初搭建webview的时候,在onReceivedError处理过一次,那时候傻傻的在onReceivedError中,以为能获取到相关的错误状态码。就简单的handler处理下,搞了错误的自定义界面。再实际的测试中,却惊喜的发现,实际上不能获取到错误。这是为啥呢。经过一番搜索,发现奥6.0不支持啊。然后查到blog作者提供两种通用的解决方案,一种实在title中获取到404,500等关键字,判断当前是错误了(我就是采取这种。。。说出来都是泪)。因为简单粗暴,且有效,但是未考虑实际开发过程中的错误。第二种就是每次请求时,去通过httpClient,okHttp等等网络框架去发起一次请求,获取其中的状态码。(但实际中 要考虑速度问题)这种方案一开始被我舍弃了。

于是乎,我是万万没有想到,有个webview页面的getTitle获取的标题叫做“500强xxxxxx”,瞬间爆炸,而且坑爹的是,因为采用混合开发,这一开始的标题不一定是最终标题,最终标题需要通过自定义js框架中获取的标题,最终显示的页面是没有“500强xxxx”标题。导致问题的。解决方案,在6.0设备是很容易解决的,因为官方修复了问题,但是4.4 5.0设备就有问题了,看到还有一个做法就是服务器端做处理,他去做页面找不到的问题的解决方案。

这里仅是记录下,遇到这个坑,简单粗暴解决后的遇到的问题经过,以次警示下自己。。。

参考文章:
Android webview处理404、500、断网、timeout页面的问题

建造者,开源框架中感觉应用非常常见的一种设计模式。常见的例如okhttp、retrofit,其中的配置都是通过Builder去添加的。
所以这是一种很方便的设计模式。
按照我们之前的模板设计方法举得例子。如果我作为一个消费者,通过模板方法去买外星人电脑,那么我会知道,这台电脑是如何组装的,是怎么拼接cpu,怎么拼接键盘,怎么拼接外壳。而且顺序也定死了。但是,如果是建造者模式的话,那么就会发现,其实我作为消费者,我不关心,如果制造的,我只是输入一些cpu型号,键盘样式,外壳材质就可以得到一台笔记本。我可以通过一个导演(这里指类似可以有限度组装笔记本的那种厂商---准系统)去实现制造一台笔记本(其实这里举例子不太好,应该相应的改为金拱门之类的好点,你作为顾客去点餐,不管是要巨无霸还是麦吉士,你可以再有限范围内挑选是否要黄瓜,是否要cheese等操作,而不需要知道汉堡如何制作出来,等着吃就是了。)那么建造者模式是如何实现的呢?

先来看看uml图
请输入图片描述

作为建造者模式,最重要的就是封装下层细节,有些繁琐的,无需着重实现的实现。
优点:封装性良好,无需关心每一个汉堡是如何生成的,最终生成相应的汉堡吃就完事了;建造者相对独立,容易扩展,需要啥汉堡流程,再添加一个就是了;便于控制细节风险(我的理解就是独立的一个建造模块,是可以自己把控的,不会对别的建造者产生问题和影响)。
使用场景:
产品类很复杂,但是调用顺序不同产生不同的东西,采取使用建造者模式比较适合。

他跟工厂模式有什么区别呢?建造者模式关注的是零件类型和装配工艺(顺序)。翻译过来就是说,工厂模式注重的还是产品本身,他所生产出来的产品都应该是类似的,好比工厂模式生产出来的笔记本,更加注重笔记本本身,有可能你是啥啥笔记本,但是你们功能没啥区别。建造者模式如果生产笔记本,那么他更加关心产品本身创造出来的过程。但是对于最终的消费者来说,他们获取其实没啥区别。

我以前只知道项目代码集成这个模块,实现UncaughtExceptionHandler就可以处理一些运行时错误,但是代码方面我并没有具体去看。现在有些需求需要重新更改下模块,于是掏出来复习下。

现在崩溃收集一般要么采用腾讯Bugly第三方平台管理,要么自建收集日志工具进行管理。腾讯bugly集成在此不在叙述,集成还是很方便的。自建的话,就是需要在捕获异常的时候,记录下来,上传服务器进行处理。

伪代码如下:

public class CrashHandler implements Thread.UncaughtExceptionHandler {

    private Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
    private Context mContext;


    private  static CrashHandler mCrashHandler = new CrashHandler();
    private CrashHandler(){

    }

    public static CrashHandler getInstance(){
        return mCrashHandler;
    }

    public void init(Context context){
        uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
        mContext = context.getApplicationContext();
    }

    /**
     * 这里就是未捕获的异常,进行统一处理
     * @param t
     * @param e
     */
    @Override
    public void uncaughtException(Thread t, Throwable e) {

        if (handleException(e)){
            //交给系统处理
            mCrashHandler.uncaughtException(t,e);
        }else {
            //自己处理异常
            
            //杀死进程
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(0);
        }


    }

    /**
     *先进行处理异常,return false表明未处理
     * @param throwable
     * @return
     */
    private boolean handleException(Throwable throwable){
        if (throwable == null){
            return false;
        }

        new Thread(){
            @Override
            public void run() {
                Looper.prepare();
                    //提示错误信息
                Looper.loop();
            }
        }.start();
        saveExceptionToSD(throwable);//保存日志到sd卡
        postExceptionToWeb(throwable);//提交到自己服务器
        return true;
    }

    private void saveExceptionToSD(Throwable throwable){

    }

    private void postExceptionToWeb(Throwable throwable){

    }

网上封装好的代码太多了,相关具体可以去爬别人好的代码。但是核心思想都是去自己处理HnadlerException方法里的异常,保证应用给用户好的体验。

前几天谷歌开发者大会又开始大力推荐他的Flutter了。唉,作为一个懒惰的码畜。错过了RxJava,错过了kotlin,看到Flutter本想学学的,也被新创建的Drat语言伤透了心。但是谷歌爸爸自研新系统的消息愈演愈烈,没办法,还是稍微接触下先,准备学习吧。
首先安装环境就发现一个蛋疼的问题,Flutter有个中文网站,里面的中文教程windows安装的第一篇是0.2.8的环境,最新貌似变成0.3.2了,果然测试版开发就是快。这不是重点,重点是,git下载的话,你会后悔的,如果不想变换国内节点配置,直接下载官方的压缩包就是了。然后还是常规的加入环境变量。
碰到问题如下:

  1. 0.2.8环境不知道和3.1.2的android studio产生了什么奇妙的化学反应,在我这台笔记本死活卡在创建flutter应用中。换成0.3.2就好了。
  2. flutter doctor --android-licenses 在cmd中是正常的,且同意过了,但是在android studio的初始工程中,死活报错,我开始怀疑是环境变量Android sdk配错了,但是不是,这个bug找了半天,才在stackoverflow看到。android的sdk.dir莫名是上一个工程的sdk目录。切换就好了。
    运行成功截图如下。

请输入图片描述
改成符合标题的

请输入图片描述
本文只是记录下,运行flutter的hello world的坑。2333.学习等慢慢啃吧

因为人员变动,我也需要去解决Eclipse的相关问题。一个上古时代的工程在我电脑版本死活跑不起来。一起报Dx unsupported class file version 52.0 xxxxxx错误。
查看网上的解决方法,大部分都是因为原工程编译的android版本太低了,需要把1.8版本降低到1.7版本。

右键工程-->Properties-->Java Compiler -->选择你安装的jdk版本.

但是我试了,在我机子上无用,且同步Installed JREs里面匹配也是无用的。甚至换到1.6版本仍然无用。查询了相关的资料,发现都是老的,且基本都是这个方法,陷入绝望,想到4.4可以1.7jdk。但项目是android4.0.4版本。于是死马当活马医,在project.properties中更改 target=android-14 为 target=android-19 。成功运行。

参考资料Dx unsupported class file version 52.0