Android巨量字符串輸出

前言

最近公司接入一個項目,紅外遙控,就是用手機去控制機頂盒播放節目,截圖所示。領導讓我去對接歌華有線機頂盒一個紅外數據。


問題

我拿着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去轉換。*
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章