`
hecal
  • 浏览: 74722 次
社区版块
存档分类
最新评论

《转载》Android大TXT文本文档读取(续)

阅读更多

原文地址:http://wangliping.net/read-big-txt-2

 

上次写了个Android大TXT文本文档读取 , 但是提到不能往回读,这两天就顺手写了一下回翻的效果,当然回翻的时候鉴于手机CPU或者内存的缘故会觉得卡或者不卡,不过还好,自己测试的效果还行。倒 是一直在后台如果有个读取的备份的话,此处是指InputStreamReader对象的备份,而不是读取Buffer的备份。

 

  以下这段代码已经放到开源项目Filexpert 里了,在那个项目中,可以读取网络文件。大家如果感兴趣的话,也可以试试Filexpert,挺不错的一个项目,请大家多多支持。

  闲话少说,依旧上代码。

package net . wangliping . filemanager ;

import java.io.FileInputStream ;
import java.io.IOException ;
import java.io.InputStreamReader ;
import java.nio.CharBuffer ;

import android.app.Activity ;
import android.net.Uri ;
import android.os.AsyncTask ;
import android.os.Bundle ;
import android.os.Handler ;
import android.os.Message ;
import android.text.TextUtils ;
import android.util.Log ;
import android.widget.ScrollView ;

import com.swan.test.R ;

public class TxtReader extends Activity implements
        SwanTextView . OnPreDrawListener {

    private static final String LOG_TAG = "TxtReader" ;
    private static final int BUF_SIZE = 1024 * 2 ;
    private static final int BUF_SHOW = 3 ;
   
    private static final int ARROW_UP = 1 ;
    private static final int ARROW_DOWN = 2 ;

    private static String ENCODING = "GB2312" ;
   
    private InputStreamReader mIsReader = null ;
    private Uri mUri = null ;
    private SwanTextView mTextShow ;
    private ScrollView mScrollView ;
    private String mStringShow = null ;
    private StringBuilder mStringBuilder = null ;

    private boolean mReadNext     = true ;
    private boolean mReadBack     = false ;
    private boolean mStopThread   = false ;
   
    private int mPreBottom   = - 1 ;
    private int mCurBottom   = - 1 ;
    private int mReadBufNum = 0 ;
    private int mBuffHeight = - 1 ;
    private int mPreScrollY = - 1 ;

    private final Handler mHandler = new Handler () {
        @Override
        public void handleMessage (Message msg ) {
            switch (msg . what ) {
            case ARROW_DOWN:
                mTextShow . setText ((CharBuffer ) msg . obj );
                break ;
            case ARROW_UP:
                mTextShow . setText ((CharBuffer ) msg . obj );
                mScrollView . scrollTo (0 , mBuffHeight );
                break ;
            default :
                super . handleMessage (msg );
            }
        }
    };

    public void onCreate (Bundle savedInstanceState ) {
        super . onCreate (savedInstanceState );
        setContentView (R . layout . txt_reader );

        mUri = getIntent (). getData ();
       
        mScrollView = (ScrollView ) findViewById (R . id . text_show_scroll );

        mTextShow = (SwanTextView ) findViewById (R . id . text_show );   
        mTextShow . setOnPreDrawListener (this );

        new TextShowTask (). execute (mUri );
    }

    private void showText (Uri uri ) throws IOException , InterruptedException {
       
        mIsReader = new InputStreamReader (new FileInputStream (
                uri . getPath ()), ENCODING );
       
        mStringBuilder = new StringBuilder ();
        int initBufSize = BUF_SIZE * (BUF_SHOW - 1 );
        char [] buf = new char [ BUF_SIZE ];
       
        while (! mStopThread ) {
            int scrollY = mScrollView . getScrollY ();
            if (mCurBottom == scrollY && mPreScrollY < scrollY ) {
                mReadNext = true ;
                mReadBack = false ;
            } else if (mReadBufNum > BUF_SHOW && 0 == scrollY && mPreScrollY != scrollY ) {
                mReadNext = false ;
                mReadBack = true ;
            }
           
            mPreScrollY = scrollY ;

            int len = - 1 ;
            if (mReadNext && (len = mIsReader . read (buf )) > 0 ) {
                mReadNext = false ;
                mReadBufNum ++;

                if (mStringBuilder . length () > initBufSize ) {
                    mStringBuilder . delete (0 , BUF_SIZE );
                    mPreBottom = mCurBottom ;

                    Message msg = mHandler . obtainMessage (ARROW_DOWN );               
                    msg . obj = CharBuffer . wrap (mStringBuilder . toString ());
                    mHandler . sendMessage (msg );

                    mStringShow = mStringBuilder . append (buf , 0 , len ). toString ();
                } else {
                    while (mStringBuilder . length () < initBufSize ) {
                        mStringBuilder . append (buf );
                        mIsReader . read (buf );
                        mReadBufNum ++;
                    }

                    mStringBuilder . append (buf );
                    Message msg = mHandler . obtainMessage (ARROW_DOWN );
                    msg . obj = CharBuffer . wrap (mStringBuilder . toString ());
                    mHandler . sendMessage (msg );
                }
            } else if (mReadBack && mReadBufNum > BUF_SHOW ) {
                Log . d (LOG_TAG , "Prepare to read back" );
                mReadBack = false ;
                mIsReader . close ();
                new BackBufReadThread (mStringBuilder ). start ();
            }
        }
    }

    private class TextShowTask extends AsyncTask < Object , Object , Object > {
        @Override
        protected void onPostExecute (Object param ) {
            Log . d (LOG_TAG , "Send broadcast" );
        }

        @Override
        protected Object doInBackground (Object ... params ) {
            Uri uri = (Uri ) params [ 0 ];

            try {
                showText (uri );
            } catch (Exception e ) {
                Log . d (LOG_TAG , "Exception" , e );
            }

            return null ;
        }
    }
   
    private class BackBufReadThread extends Thread {
        StringBuilder mSbPre = null ;
       
        public BackBufReadThread (StringBuilder sb) {
            mSbPre = sb. delete (0 , sb. length ());
        }
       
        @Override
        public void run () {
            try {
                mIsReader = new InputStreamReader (new FileInputStream (
                        mUri . getPath ()), ENCODING );
               
                char [] buf = new char [ BUF_SIZE ];
                int i = 0 ;
                while ((mReadBufNum - BUF_SHOW ) > ++ i && mIsReader . read (buf ) > 0 ) {
                    // Just to skip the inputstream. Any better methods?
                }
                mReadBufNum --;
               
                for (i = 0 ; i < BUF_SHOW ; i ++) {
                    mIsReader . read (buf );                   
                    mSbPre . append (buf );
                }
               
               
//                mSbPre.delete(mSbPre.length() - BUF_SIZE, mSbPre.length()).insert(0, buf);
                Message msg = mHandler . obtainMessage (ARROW_UP );
                msg . obj = CharBuffer . wrap (mSbPre . toString ());
                mHandler . sendMessage (msg );
            } catch (Exception e ) {
                Log . d (LOG_TAG , "Exception" , e );
            }
        }
    }

    @Override
    public void onPreDraw (int bottom ) {
        mCurBottom = bottom - mScrollView . getHeight ();
       
        if (! TextUtils . isEmpty (mStringShow )) {
            // Use the last deleted buff to evaluate the height
            mBuffHeight = mPreBottom - mScrollView . getScrollY ();
           
            // Set the text to add new content without flash the view
            Message msg = mHandler . obtainMessage (ARROW_DOWN );
            msg . obj = CharBuffer . wrap (mStringShow );           
            mHandler . sendMessage (msg );
           
            mStringShow = null ;
        }
    }
   
    @Override
    public void finish () {
        mStopThread = true ;
        super . finish ();
    }
}

  资源文件和SwanTextView跟上次的文章一样,只不过为了名字命名好看点,把SwanTextView里的响应函数改成如下了:

@Override
protected void onDraw (Canvas canvas ) {
   
    if (mPreBottom != getBottom ()) {
        mPreBottom = getBottom ();

        if (preDrawListener != null )
            preDrawListener . onPreDraw (mPreBottom );
    }

    super . onDraw (canvas );
}

public static interface OnPreDrawListener {
    public void onPreDraw (int bottom );
}

public void setOnPreDrawListener (OnPreDrawListener listener ) {
    preDrawListener = listener ;
}

  代码不成熟,见笑了。

分享到:
评论

相关推荐

    android txt文件保存读取操作

    android 写了一个工具类实现txt文件保存和读取

    彻底解决android读取中文txt的乱码(自动判断文档类型并转码

    彻底解决android读取中文txt的乱码(自动判断文档类型并转码)

    Android系统下处理PDF文档的Java库-Spire.PDF for Android via Java_2.11.0.zip

    该控件一款专业的 Android PDF 控件,用于在 Android 手机应用程序中创建、读取、操作和转换 PDF 文档,运行环境无需安装 Adobe Acrobat 或其他任何第三方组件。支持的功能如下: PDF 文档安全性设置,画文本、图片...

    免费Android系统处理PDF文本的Java类库工具-Free Spire.PDF for Android via Java-2.12.0.zip

    免费Android PDF 控件,用于在 Android 手机应用程序中创建、读取、操作和转换 PDF 文档,运行环境无需安装 Adobe Acrobat 或其他任何第三方组件。支持的功能如下: PDF 文档安全性设置,画文本、图片、形状、条形码...

    android中文文档

    android sdk中文文档 资源是Android应用程序不可或缺的部分。一般而言,资源是你想包含和引入到应用程序里面的一些外部元素,比如图片、音频、视频、文本字符串、布局、主题等。每个Android应用程序包含一个资源...

    可以用于android手机的文本阅读器

    这是一个简单的书本阅读器,优势在于可以读取大容量的txt文档

    txt文档阅读器

    import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Align; public class BookPageFactory { //...

    Android版植物大战僵尸源码+设计文档

    Android版植物大战僵尸源文件,内含技术文档,说明了实现细节。各个包的说明:  com.tarena.monster 主要是用于游戏流程控制包  com.tarena.monster.actor 主要存放所有角色(精灵)初始化的类  ...

    Android 常用六大框架

    (2) ioc模块:android中的ioc模块,完全注解方式就可以进行UI绑定、res中的资源的读取、以及对象的初始化。 (3) 数据库模块:android中的orm框架,使用了线程池对sqlite进行操作。 (4) http模块:通过...

    新版Android开发教程.rar

    � Android 的平台基本上是免费的,虽然有部份原生链接库会要求费用,但大部份是免权利金; Android 的 程序可以采用 JAVA 开发,但是因为它的虚拟机 (Virtual Machine) Dalvik ,是将 JAVA 的 bytecode 转成 自 己...

    android开发入门与实战(下)

    7.3.8 自动完成文本(AutoCompleteTextView) 7.3.9 日期选择器(DatePicker)介绍与应用 7.3.10 时间选择器(TimePicker)介绍与应用 7.3.11 滚动视图(ScrollView)介绍与应用 7.3.12 进度条(ProgressBar)介绍与应用 7.3....

    《Google Android开发入门与实战》.pdf

     本书内容上涵盖了用android开发的大部分场景,从android基础介绍、环境搭建、sdk介绍、market使用,到应用剖析、组件介绍、实例演示等方面。从技术实现上,讲解了5个android平台下的完整综合实例及源代码分析,...

    android开发入门与实战(上)

    7.3.8 自动完成文本(AutoCompleteTextView) 7.3.9 日期选择器(DatePicker)介绍与应用 7.3.10 时间选择器(TimePicker)介绍与应用 7.3.11 滚动视图(ScrollView)介绍与应用 7.3.12 进度条(ProgressBar)介绍与应用 7.3....

    Google.Android开发入门与实战

     《Android开发入门与实战》内容上涵盖了用Android开发的大部分场景,从Android基础介绍、环境搭建、SDK介绍、Market使用,到应用剖析、组件介绍、实例演示等方面。从技术实现上,讲解了5个Android平台下的完整综合...

    Android版植物大战僵尸

    Java源码,Android源码,植物大战僵尸  Android版植物大战僵尸源文件,内含技术文档,说明了实现细节。各个包的说明: ... ... 定义了很多boolean值用来开关游戏中各种流程;... 读取文本文件,确定怪物出场顺序。

    Aspose.PDF-for-Android-via-java:适用于Android的Aspose.PDF(通过Java示例)

    是PDF文档创建和处理组件,它使您的Android应用程序无需使用任何其他第三方应用程序即可读取,编写和处理PDF文档。 它还允许您创建表单并管理嵌入PDF文档中的表单字段。 目录 描述 一系列Java示例,可帮助您学习...

    WX-master.zip

    实现根据TXT文本存储的微信账号,无需...手机新建一个phone.txt文档放在text文件夹下,文档里面每一行对应一个微信号就可以,你在WXAutoClickAccessibilityService里面第39行就是读取文档内容的代码,你可以自己修改的

    Folioreader-Android

    FolioReader-Android是用Java和Kotlin编写的EPUB阅读器。 特征 自定义字体 自定义文字大小 主题/白天模式/夜间模式 文字突出显示 列出/编辑/删除突出显示 处理内部和外部链接 风景素描 剩余阅读时间/剩余...

    Google Android开发入门与实战的代码

    Google Android开发入门与实战的代码 1章 掀起你的盖头来——初识Android. 1 1.1 认识Android 1 1.2 Android的背景 2 1.2.1 Android的历史 2 1.2.2 Android的发展 2 1.3 我的Android我做主 2 ...

Global site tag (gtag.js) - Google Analytics