happyaday

导航

关于安卓中经常用到的表情开发中的一点小问题

安卓中经常用到表情,通常是用spannablestring +imagespan实现的,这次开发中也是这样做,有一个类,例如ParseEmojiUtil,用正则表达式来解析表情,展示到聊天页面。

代码类似这样private static final String REGEX_STR = "\\[1f\\w{3}\\]|\\[\\w{4}\\]";
    private static int end=0;
    public static int width1;
    private static Matrix matrix;
    private static String key;
    private static Map<String,Bitmap> emojiMap=new HashMap<String,Bitmap>();

 public static void dealExpression(Context context, SpannableString spannableString, Pattern patten, int start)
   throws Exception {
  Matcher matcher = patten.matcher(spannableString.toString());
  while (matcher.find()) {
            try
           {
             
   //String key = matcher.group();
            key = matcher.group(); 
   Log.d("Key", key);
   //if (matcher.start() < start) {
    //continue;
   //}
   if(emojiMap.containsKey(key)){
    Bitmap bitmap2=emojiMap.get(key);
    ImageSpan imageSpan = new ImageSpan(bitmap2);
    int startPos=end+matcher.start();
    end =end+ matcher.start() + key.length();
    spannableString.setSpan(imageSpan, startPos, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
    //if (end < spannableString.length()) {
     //dealExpression(context, spannableString, patten, end);
    //}
    //break;
    matcher.reset();
    matcher = patten.matcher(spannableString.toString().substring(end));
   }else{
    Field field = R.drawable.class.getDeclaredField("emoji_"
      + key.substring(key.indexOf("[") + 1, key.lastIndexOf("]")));
    int resId = Integer.parseInt(field.get(null).toString());
    if (resId != 0) {
     Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resId);
     matrix=new Matrix();
    //鐠嬪啯鏆g悰銊﹀剰鐎逛粙鏆�
    if(Math.abs(width1-480)<=Math.abs(width1-720)){
      matrix.postScale(dip2px(context,28)/(float)bitmap.getWidth(), dip2px(context,28)/(float)bitmap.getHeight());//闁俺绻�
    }else if(Math.abs(width1-720)<=Math.abs(width1-768)){
     matrix.postScale(dip2px(context,28)/(float)bitmap.getWidth(), dip2px(context,28)/(float)bitmap.getHeight());//闁俺绻�
    }else if(Math.abs(width1-768)<=Math.abs(width1-800)){
     matrix.postScale(dip2px(context,28)/(float)bitmap.getWidth(), dip2px(context,28)/(float)bitmap.getHeight());//闁俺绻�
    }else if(Math.abs(width1-800)<=Math.abs(width1-1080)){
     matrix.postScale(dip2px(context,28)/(float)bitmap.getWidth(), dip2px(context,28)/(float)bitmap.getHeight());//闁俺绻�
    }else if(Math.abs(width1-1080)<=Math.abs(width1-1200)){
     matrix.postScale(dip2px(context,45)/(float)bitmap.getWidth(), dip2px(context,45)/(float)bitmap.getHeight());//闁俺绻�
    }else{
     matrix.postScale(dip2px(context,80)/(float)bitmap.getWidth(), dip2px(context,80)/(float)bitmap.getHeight());//闁俺绻�
    }
     
       Bitmap bitmap2=Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),matrix,true);
       if(!emojiMap.containsKey(key)){
        emojiMap.put(key,bitmap2);
       }
     ImageSpan imageSpan = new ImageSpan(bitmap2);
     if(!bitmap.isRecycled()){
      bitmap.recycle();
     }
     int startPos=end+matcher.start();
     end =end+ matcher.start() + key.length();
     spannableString.setSpan(imageSpan, startPos, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
     //if (end < spannableString.length()) {
      //dealExpression(context, spannableString, patten, end);
     //}
     //break;
     matcher.reset();
     matcher = patten.matcher(spannableString.toString().substring(end));
    };
   }
        }catch(OutOfMemoryError err){
         try{
          if(key!=null){                                          
           Log.d("Key", key);
           //if (matcher.start() < start) {
            //continue;
           //}
           Field field = R.drawable.class.getDeclaredField("emoji_"
             + key.substring(key.indexOf("[") + 1, key.lastIndexOf("]")));
           int resId = Integer.parseInt(field.get(null).toString());
           if (resId != 0) {
            Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resId);
            matrix=new Matrix();
        
           if(Math.abs(width1-480)<=Math.abs(width1-720)){
             matrix.postScale(dip2px(context,28)/(float)bitmap.getWidth(), dip2px(context,28)/(float)bitmap.getHeight());//闁俺绻�
           }else if(Math.abs(width1-720)<=Math.abs(width1-768)){
            matrix.postScale(dip2px(context,28)/(float)bitmap.getWidth(), dip2px(context,28)/(float)bitmap.getHeight());//闁俺绻�
           }else if(Math.abs(width1-768)<=Math.abs(width1-800)){
            matrix.postScale(dip2px(context,28)/(float)bitmap.getWidth(), dip2px(context,28)/(float)bitmap.getHeight());//闁俺绻�
           }else if(Math.abs(width1-800)<=Math.abs(width1-1080)){
            matrix.postScale(dip2px(context,28)/(float)bitmap.getWidth(), dip2px(context,28)/(float)bitmap.getHeight());//闁俺绻�
           }else if(Math.abs(width1-1080)<=Math.abs(width1-1200)){
            matrix.postScale(dip2px(context,45)/(float)bitmap.getWidth(), dip2px(context,45)/(float)bitmap.getHeight());//闁俺绻�
           }else{
            matrix.postScale(dip2px(context,80)/(float)bitmap.getWidth(), dip2px(context,80)/(float)bitmap.getHeight());//闁俺绻�
           }
            
              Bitmap bitmap2=Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),matrix,true);
            ImageSpan imageSpan = new ImageSpan(bitmap2);
            if(!bitmap.isRecycled()){
             bitmap.recycle();
            }
            int startPos=end+matcher.start();
            end =end+ matcher.start() + key.length();
            spannableString.setSpan(imageSpan, startPos, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
            //if (end < spannableString.length()) {
             //dealExpression(context, spannableString, patten, end);
            //}
            //break;
            matcher.reset();
            matcher = patten.matcher(spannableString.toString().substring(end));
           };
          }
         }catch(OutOfMemoryError err1){
          
         }
       } 
  }
  end=0;
 }

当然catch outofmemoryerror里面的代码可以不去关注

值得记录有几点

1.matcher

matcher.find 找出一个匹配后,要reset,继续找下一个,

2.有些bitmap确认没用后,要记得显示回收,显示调用recycle

3.另外,当时做的时候如果解析很多表情,在个别机子上会报OOM的异常,

可以用一个全局变量map,保存资源id 以及对应的bitmap。

OOM的问题在安卓开发中,不小心就会遇到,碰到了要查内存溢出的原因,总结经验。

posted on 2016-03-11 16:29  happyaday  阅读(400)  评论(0编辑  收藏  举报