1. ClickSpan导致长按崩溃
2. webView踩过的坑
3. webView JS方法 正式版本不能使用,混淆问题
- ClickSpan导致的长按崩溃(关于TextView中使用ClickSpan后, 长按该TextView会导致崩溃) 代码如下:这是一个textViewk点击部分内容响应事件。
public class Clickable extends ClickableSpan implements View.OnClickListener {
private final View.OnClickListener mListener;
public Clickable(View.OnClickListener l) {
mListener = l;
}
@Override
public void onClick(View v) {
mListener.onClick(v);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(Color.parseColor("#FF6771"));
}
}
//使用
spanableInfo.setSpan(new Clickable(fromUserListener), start, end,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
此代码, 在对TextView 进行长按操作的时候, 会导致崩溃, 崩溃的log如下:
ava.lang.NullPointerException
Attempt to invoke virtual method 'int android.widget.Editor$SelectionModifierCursorController.getMinTouchOffset()' on a null object reference
崩溃原因是当使用了ClickableSpan的textview被触发长按就会出现此bug,解决办法就是屏蔽长按事件,
(1) 调用 TextView.setLongClickable(false); 禁用长按事件
(2) 调用
TextView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return true;
}
});
消费掉长按事件即可;
最近项目里面需要使用到webview和JS做交互的功能,(webView和JS交互不会同学可以翻看下我之前写的文章里面有教程,源码太久远遗失了┗|`O′|┛ 嗷~~) 我们数数webView和JS的坑吧, 我们先来看源码 1.首先前端需要提供如下代码事件。(名称一定要跟后面的方法名称对应坑)
<div id='b'><a onclick="window.demo.clickOnAndroid(2)">b.c</a></div>
这里window是必须要的,demo这个对应的webview注册名称好记,clickOnAndroid这个就是JS调用Android客户端方法名称。可以带参数,参数好像有限制,忘记了。 在看看客户端源码
//设置支持js代码 首先要支持JS设置
mWebView.getSettings().setJavaScriptEnabled(true);
//此注释也需要添加上否则好像也是没有反应,报错内容就是xxx.function不存在什么的。
@SuppressLint("AddJavascriptInterface")
//重点方法如下,
//增加接口方法,让html页面调用
mWebView.addJavascriptInterface(new Object(){
@JavascriptInterface //这里这个注释一定不能掉, 是一个巨坑我找了一个多时辰。
public void clickOnAndroid(){
finish();
}
},"demo");
// 这个方法好像也是要加的吧 主要是用来处理网页上面的弹窗
//setWebChromeClient主要处理解析,渲染网页等浏览器做的事情
/*** WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等比如 **/
mWebView.setWebChromeClient(new WebChromeClient())
3.webView JS方法 正式版本不能使用,混淆问题。
以上是小部分坑,最后一个坑,是debug版本根本没有什么问题,主要是正式版本之后就会发现原先的返回尽然不能用了。了。 坑了个爹,(╯‵□′)╯︵┻━┻。为什么能这样,但是就是这样,做了以上操作只能保证功能是没有问题。但是混淆之后就不能用了呵呵了。 来看看如何解决 *一般情况下js交互,代码混淆的时候需要配置规则,以下是通用的混淆规则
#保留annotation, 例如 @JavascriptInterface 等 annotation
-keepattributes *Annotation*
#保留跟 javascript相关的属性
-keepattributes JavascriptInterface
#保留JavascriptInterface中的方法
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
public *;
}
#这个根据自己的project来设置,这个类用来与js交互,所以这个类中的 字段 ,方法, 等尽量保持
-keepclassmembers public class com.packgename.WebViewClient{
<fields>;
<methods>;
public *;
private *;
}
通过设置这些通用的规则之后,发现一些js调用还是出现了问题。最终根据 log 日志,以及mapping文件的查看,找出了原因。
#这个类 必须保留,这个类在ViewClient中传递数据,如果被混淆 会导致一些callback无法调用
-keep class com.packgename.WebViewClient$addJavascriptInterface
#类中成员的变量名也不能混淆,这些变量名被作为json中的字段,不能改变。
-keepclassmembers class com.packgename.WebViewClient$addJavascriptInterface{
<fields>;
}
总结:webview中的js交互混淆时,注意事项 混淆规则加入 js公用的规则 并且找出与js交互有关的bean类,进行保护 混淆规则所匹配的类,必须加入该类的 全部路径 对于内部类,应该使用 $ 符号,而不是用 . 对于混淆出现的问题,可以通过log和mapping文件进行追踪。
来源:oschina
链接:https://my.oschina.net/u/1270405/blog/777379