美文网首页
Android巨量字符串输出

Android巨量字符串输出

作者: Gxinyu | 来源:发表于2018-12-12 16:41 被阅读0次

    前言

    最近公司接入一个项目,红外遥控,就是用手机去控制机顶盒播放节目,截图所示。领导让我去对接歌华有线机顶盒一个红外数据。


    歌华有线.jpg

    问题

    我拿着SDK对比api,很快找到获取特定id下的机顶盒红外数据方法,返回值里面的data封装在SDK里面无法直接tosring的形式直接输出数据,最后只能用Gson去转格式。如下gson换换公式,当时转过之后我想先Log看一下数据,然后我复制Log日志放在在线json格式化上查看,结果显示格式化错误。我想着是不是因为接口返回的json数据过大的原因导致无法使用Gson去解析的原因,后来又使用fastjson,然后还有超大json解析,最后打印的日志都是不全的,最后上网查到AS里面日志一行最多显示4000个字符。

    解决问题

    1.日志字符拼接

    在网上找到关于过长日志打印限制问题,超过4000个字符之后通过换行的形式,然后把所有的日志再进行拼接起来输出。

    public static void LoggerE(String tag, String bodyMsg) {  //信息太长,分段打印
            //因为String的length是字符数量不是字节数量所以为了防止中文字符过多,
            //  把4*1024的MAX字节打印长度改为2001字符数
            if (bodyMsg.length() > 4000) {
                for (int i = 0; i < bodyMsg.length(); i += 4000) {
                    //当前截取的长度<总长度则继续截取最大的长度来打印
                    if (i + 4000 < bodyMsg.length()) {
                        Log.e(tag + i, bodyMsg.substring(i, i + 4000));
                    } else {
                        //当前截取的长度已经超过了总长度,则打印出剩下的全部信息
                        Log.e(tag + i, bodyMsg.substring(i, bodyMsg.length()));
                    }
                }
            } else {
                //直接打印
                Log.e(tag, bodyMsg);
            }
        }
    

    通过日志换行显示,然后又通过字符的拼接,但是通过在线json发现还是出现格式化问题。

    2.Textview复制粘贴

    昨天晚上不知道什么时候想到用日志输出数据太麻烦还容易出错,那就用TextView来显示数据,然后通过复制粘贴的形式输出。TextView复制粘贴的方式有如下两种:

    第一种

    在xml中直接设置属性:android:textIsSelectable=”true”

    • 这种方式要求sdk>11
    第二种

    直接使用TextView, 然后在代码里给TextView添加OnLongClickListener事件,长按时弹出自定义 “复制” 菜单(比如结合 PopupWindow做弹出菜单). 点击”复制” 就去获取TextView的内容.

    ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
    cmb.setText(content.trim()); //将内容放入粘贴管理器,在别的地方长按选择"粘贴"即可
    cm.getText();//获取粘贴信息
    

    还有一个问题就是系统自带的Textview不会自动换行,我从网上找到一个关于自定义TextView自动换行的,如下:

    public class JustifyTextView extends TextView {
    
        private int mLineY;
        private int mViewWidth;
        public static final String TWO_CHINESE_BLANK = "  ";
    
        public JustifyTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
            super.onLayout(changed, left, top, right, bottom);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            TextPaint paint = getPaint();
            paint.setColor(getCurrentTextColor());
            paint.drawableState = getDrawableState();
            mViewWidth = getMeasuredWidth();
            String text = getText().toString();
            mLineY = 0;
            mLineY += getTextSize();
            Layout layout = getLayout();
            // layout.getLayout()在4.4.3出现NullPointerException
            if (layout == null) {
                return;
            }
            Paint.FontMetrics fm = paint.getFontMetrics();
            int textHeight = (int) (Math.ceil(fm.descent - fm.ascent));
            textHeight = (int) (textHeight * layout.getSpacingMultiplier() + layout.getSpacingAdd());
            for (int i = 0; i < layout.getLineCount(); i++) {
                int lineStart = layout.getLineStart(i);
                int lineEnd = layout.getLineEnd(i);
                float width = StaticLayout.getDesiredWidth(text, lineStart, lineEnd, getPaint());
                String line = text.substring(lineStart, lineEnd);
                if (needScale(line) && i < layout.getLineCount() - 1) {
                    drawScaledText(canvas, lineStart, line, width);
                } else {
                    canvas.drawText(line, 0, mLineY, paint);
                }
                mLineY += textHeight;
            }
        }
    
        private void drawScaledText(Canvas canvas, int lineStart, String line, float lineWidth) {
            float x = 0;
            if (isFirstLineOfParagraph(lineStart, line)) {
                String blanks = "  ";
                canvas.drawText(blanks, x, mLineY, getPaint());
                float bw = StaticLayout.getDesiredWidth(blanks, getPaint());
                x += bw;
                line = line.substring(3);
            }
            int gapCount = line.length() - 1;
            int i = 0;
            if (line.length() > 2 && line.charAt(0) == 12288 && line.charAt(1) == 12288) {
                String substring = line.substring(0, 2);
                float cw = StaticLayout.getDesiredWidth(substring, getPaint());
                canvas.drawText(substring, x, mLineY, getPaint());
                x += cw;
                i += 2;
            }
            float d = (mViewWidth - lineWidth) / gapCount;
            for (; i < line.length(); i++) {
                String c = String.valueOf(line.charAt(i));
                float cw = StaticLayout.getDesiredWidth(c, getPaint());
                canvas.drawText(c, x, mLineY, getPaint());
                x += cw + d;
            }
        }
    
        private boolean isFirstLineOfParagraph(int lineStart, String line) {
            return line.length() > 3 && line.charAt(0) == ' ' && line.charAt(1) == ' ';
        }
    
        private boolean needScale(String line) {
            if (line == null || line.length() == 0) {
                return false;
            } else {
                return line.charAt(line.length() - 1) != '\n';
            }
        }
    }
    

    通过TextView方式获取的string数据,还需要粘贴操作配合输出数据,我试过几种方式,在此分享一下,因为数据过长,普通QQ还有其他软件都不能粘贴全部数据,如果手机里面有wps的可以直接把数据粘贴输出,第二种是office,我手机的office不支持粘贴,不过因为小米手机的搜狗输入法自带粘贴板,通过粘贴板粘贴数据输出。

    3.Txt文件写入

    思前想后,总感觉前面的方式都不是特别好,过程都比较繁琐,因为我本来是要输出txt文件,所以想到能不能直接把string字符串直接转为txt文本。如下有两种写入方式:

    第一种写入:
    /**
         * string转换txt
         *
         * @param filePath 文件路径
         * @param fileName 文件名
         * @param str      输出文本
         */
        public void stringToTxt(String filePath, String fileName, String str) {
            try {
                //首先要去创建文件
                makeFilePath(filePath, fileName);
    
                FileWriter fw = new FileWriter(filePath + fileName);
                //SD卡中的路径
                fw.flush();
                fw.write(str);
                fw.close();
                Log.e("TAG", "写入成功");
            } catch (Exception e) {
                Log.e("TAG", "异常:" + e.getMessage());
                e.printStackTrace();
            }
        }
    
    
    第二种写入:
    /**
         * 写入文件
         *
         * @param strcontent 字符串
         * @param filePath   路径
         * @param fileName   文件名
         */
        public void writeTxtToFile(String strcontent, String filePath, String fileName) {
            //生成文件夹之后,再生成文件,不然会出错
            makeFilePath(filePath, fileName);
    
            String strFilePath = filePath + fileName;
            // 每次写入时,都换行写
            String strContent = strcontent + "\r\n";
            try {
                File file = new File(strFilePath);
                if (!file.exists()) {
                    Log.d("TestFile", "Create the file:" + strFilePath);
                    file.getParentFile().mkdirs();
                    file.createNewFile();
                }
                RandomAccessFile raf = new RandomAccessFile(file, "rwd");
                raf.seek(file.length());
                raf.write(strContent.getBytes());
                raf.close();
            } catch (Exception e) {
                Log.e("TestFile", "Error on write File:" + e);
            }
        }
    

    下面是创建文件夹以及文件的方法:

    • 创建文件夹
    /**
         * 创建文件夹
         *
         * @param filePath
         */
        public static void makeRootDirectory(String filePath) {
            File file = null;
            try {
                file = new File(filePath);
                if (!file.exists()) {
                    file.mkdir();
                }
            } catch (Exception e) {
                Log.i("error:", e + "");
            }
        }
    
    
    • 创建文件
    /**
         * 创建文件
         *
         * @param filePath
         * @param fileName
         * @return
         */
        public File makeFilePath(String filePath, String fileName) {
            File file = null;
            makeRootDirectory(filePath);
            try {
                file = new File(filePath + fileName);
                if (!file.exists()) {
                    file.createNewFile();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return file;
        }
    
    还有一点需要主要,对于json特殊字符的转换,有时候会出现转换错误问题,建议使用fastjson去转换。*

    相关文章

      网友评论

          本文标题:Android巨量字符串输出

          本文链接:https://www.haomeiwen.com/subject/arcphqtx.html