Android开发容易忽略的错误(持续更新中)

原创
2016/10/28 15:19
阅读数 297

1. ClickSpan导致长按崩溃

2. webView踩过的坑

3. webView JS方法 正式版本不能使用,混淆问题

  1. 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文件进行追踪。

展开阅读全文
打赏
0
1 收藏
分享
加载中
期待后续
2016/10/28 17:28
回复
举报
更多评论
打赏
1 评论
1 收藏
0
分享
返回顶部
顶部