Android开发问题记录

将一些遇到的问题整理起来,记录到这里

ListView

ListView setSelection失效

有时需要在初始状态下自动选中(点击)某一项,比如two-pane的布局,左边是一个list,右边是具体的detail。在测试时发现,使用setSelection并不能满足需求。查看该方法的文档,发现原因如下

If in touch mode, the item will not be selected but it will still be positioned appropriately.

根据android listview setselection 失效解决办法 所说的,进行测试,发现其可以选中,但不能触发onListItemClicked方法。

最后通过调用performItemClick方法实现list的某一项自动被点击,如果要表示选中的话,在onListItemClicked回调里边调用setItemChecked方法即可。

notifyDataSetChanged不刷新数据的原因

关于这个问题,有些文章已经做了解释,如

  1. android listview notifyDataSetChange(),不起作用的可能原因
  2. Android中ListView利用自定义Adapter及时更新数据

将他们总结一下,大致如下:

“总结:在这里的重点就是要注意在开始时传给ListView的list指向不能被改变,需要从始至终指向同一个内存,这样调用notifyDataSetChanged后就能够检测到list的数据变化,从而触发ListView的重新绘制了!”

这个观点有2个错误:

  1. 不是”数据源指向的对象不能变,必须是同一个对象”,而是Adapter中的数据源是否真正发生了变化,如果只是在Activity里更改了原始的数据源对象的指向,而没有将其重新赋值给Adapter中的数据源对象,这时notifyDataSetChanged肯定不起作用,因为Adapter中的数据(无论是否为空)并没有发生变化。
    而根据上面的错误思路给出的解决办法是,将Activity里产生变化的数据源对象的值全部add到Adapter中的数据源对象中(可能还要先clear一下),不能说这种方法是错的,只是强调要明白问题产生的真正原因。
  2. 说得并不细致,我想他想说的应该是Adapter内部的AdapterDataSetObserver在我们调用notifyDataSetChanged后能够检测到list的数据变化。
    不幸的是,真实情况是,它并不能”检测到list的数据变化”,这个Observer只是一个回调,在回调里边它会记录一些状态,最后调用requestLayout()重绘ListView。具体的执行细节,大家可以去看源代码。

WebView

网页自动缩放以适应屏幕大小

解决方法如下:

WebSettings settings = webView.getSettings();
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);

参考:Webview auto zoom IN to fit screen

延伸:上面的两个方法到底做了什么,可参考
What do setUseWideViewPort() and setLoadWithOverviewMode() precisely do?

解决网页横向滚动的问题

研究之后发现,自己一开始的想法的错误的,并不是”禁止横向滚动”,如果这样去想,会重点去看WebView的各种设置。但是真正的问题出在html上。
P.S. 网上针对设置WebView的各种解决方案我都试过,但是依然无法解决问题。

造成网页出现横向滚动条的原因是图片宽度过大,超过了屏幕宽度。
了解了这一点,解决问题就很容易了。

首先设置html的viewport的宽度为设备宽度并且禁止缩放

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

其次将所有的<img>的宽度设置成100%,可以这样设置

<img style="max-width:100%" ...>
Web与JS交互及相关漏洞的解决

关于这一点,我在之前的文章中有专门分析,见android WebView与JS交互小结

body元素被自动加上多余的margin

最近调试时注意到本来应该在html中居中的元素,都会向右向下偏移一些,使用chrome://inspect远程调试发现,body元素被自动加上了margin,4个方向均为8

原因是android的WebView在渲染html时,当body没有现式地指定margin时,它会自动加上margin: 8,其实这个问题一开始就存在,但是不知google为何没有修复,可能他们认为这是一个特性而不是一个bug。

了解了问题的原因,解决自然很简单,加入以下css代码即可:

body {
        margin: 0;
        padding: 0;
    }

参考:Remove unwanted White Space in WebView Android , Remove default margin inside WebView

禁止链接跳转到浏览器

默认情况下,WebView载入的网页如果有链接,会跳转至系统的浏览器中。如果需要继续在WebView中显示,则可以自定义WebViewClient,如下:

webview.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                // 不跳到系统浏览器,继续在当前WebView里跳转
                view.loadUrl(url);  
                return true;
            }
        });
Uncaught TypeError: Cannot call method ‘getItem’ of null at XXX

当使用WebView加载某些网页时,有可能会出现这个错误:

02-07 23:23:59.230: ERROR/Web Console(3721): Uncaught TypeError: Cannot call method 'getItem' of null at http://www.google.com/:342

问题的原因在于加载的网页使用了HTML 5 Dom Storage的API - getItem方法,其中Dom Storage的接口如下:

interface Storage {
    readonly attribute unsigned long length;
    getter DOMString key(in unsigned long index);
    getter any getItem(in DOMString key);
    setter creator void setItem(in DOMString key, in any data);
    deleter void removeItem(in DOMString key);
    void clear();
};

解决方法很简单,只需要开启WebView的Dom Storage即可:

settings.setDomStorageEnabled(true);
WebView.loadData 乱码

有时,使用WebView.loadData时会出现乱码情况,使用网上常见的方法问题照旧

webView.loadData(htmlData, "text/html", "UTF-8");

其实仔细查看一些文档就会发现,最后一个参数encoding指的是传入的data是base64编码还是使用的URL编码,如果值不等于’base64’(包括null),WebView会按照ASCII编码来处理,所以就出现了乱码的情况。

正常情况下,浏览器是根据HTML的meta属性 - Content-Type来选择处理Web页面的编码,目前大部分网站都使用UTF-8来进行编码,如下:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

所以我们可以更改第二个参数的值来解决这个乱码问题:

webView.loadData(htmlData, "text/html; charset=UTF-8", null);

参考:
WebView causing Uncaught TypeError when loading www.google.com
浅谈 HTML5 的 DOM Storage 机制

MISC

安装失败 - INSTALL_FAILED_CONFLICTING_PROVIDER 错误

安装一个app的时候发现了这个问题,调试发现了原因及解决方案,具体详见这篇文章 惠惠购物助手android版3.8.2无法安装的原因及解决方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值