Android:SAX解析器进程监控

Android:SAX解析器进程监控,android,xml,sax,saxparser,Android,Xml,Sax,Saxparser,我有一个解析输入流的SAX。我不知道XML中有多少个元素,因此无法在endElement或similar中计算它们。我不知道InputStream(从http头读取)的字节长度,但我找不到一种方法来获取解析过程的当前字节进度 是否有办法获得解析过程的当前进度(即比特处理) 以下是调用DefaultHandler的方式: SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.new

我有一个解析输入流的
SAX
。我不知道XML中有多少个元素,因此无法在
endElement
或similar中计算它们。我不知道
InputStream
(从http头读取)的字节长度,但我找不到一种方法来获取解析过程的当前字节进度

是否有办法获得解析过程的当前进度(即比特处理)

以下是调用
DefaultHandler
的方式:

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(inputStream, myDefaultHandler);

您可以通过编写包装现有inputStream的。在过滤器的
read()
方法中,增加一个计数器,并提供一个getter,以便其他东西可以跟踪当前计数


由于解析器可能会提前阅读,这将是近似值,但这可能是您所能做的最好的了。

对于仍在搜索答案的任何人, 尝试在派生FilterInputStream的构造函数中传递ProgressBar:

ProgressFilterInputStream.java

import java.io.FilterInputStream;
import java.io.InputStream;
import java.io.IOException;

import android.widget.ProgressBar;
import android.util.Log;


public class ProgressFilterInputStream extends FilterInputStream {

int counter = 0;
ProgressBar progressBar;

public ProgressFilterInputStream(InputStream in, ProgressBar progressBar) {
    super(in);
    this.progressBar = progressBar;
    this.progressBar.setMax(69);  // SET MAX ACCORDIN TO THE DDMS LOGGING MESSAGE
}

@Override
public int read(byte[] buffer, int offset, int count) throws IOException {
    progressBar.setProgress(counter++);
    Log.i("PFIS" , "Counter: " + counter);
    return super.read(buffer, offset, count);
}
}
我在我的工作中的一个异步任务中使用了它

MyActivity.java

final ProgressBar bar_progress = (ProgressBar) findViewById(R.id.bar_progress);
ProgressFilterInputStream pfis = new ProgressFilterInputStream(getAssets().open("DATA.xml") , bar_progress );           
Reader reader = new InputStreamReader(pfis, "UTF-8");
InputSource is = new InputSource(reader);

// create the factory
SAXParserFactory factory = SAXParserFactory.newInstance();

// create a parser
SAXParser parser = factory.newSAXParser();

// create the reader (scanner)
XMLReader xmlreader = parser.getXMLReader();

// instantiate our handler
SaxHandler myHandler = new SaxHandler();

// assign our handler
xmlreader.setContentHandler(myHandler);

// perform the synchronous parse
xmlreader.parse(is);

从lx222应答扩展而来,我实现了异步任务ProgressDialog。很晚了,但我希望它对某些人有用

public class OpenXMLFileOperator extends AsyncTask<Void, Integer, Void>{
    private ProgressDialog progressDialog;
    private String filePath;
    private Context context;
    public OpenFileOperator(Context context,String filePath){
        this.context = context;
        this.filePath = filePath;
    }

    @Override
    protected Void doInBackground(Void... arg0) {                               
        try {                               
            if (filePath != null) {

                File file = new File(filePath);
                if (file.exists()) {    
                    InputStream stream = new FileInputStream(file);
                    ProgressFilterInputStream pfis = new ProgressFilterInputStream(stream,file.length());
                    Reader reader = new InputStreamReader(pfis, "UTF-8");

                    YourXMLHandle yourHandle = new YourXMLHandle();                 
                    android.util.Xml.parse(reader,yourHandle);

                    stream.close();
                    reader.close();
                    pfis.close();          
                }                
            }
        }catch (Exception e) {
            if (BuildConfig.DEBUG) Log.e(TAG, "Exception", e);
        }
        return null;
    }

    @Override
    protected void onPreExecute() {
        try{
            progressDialog = new ProgressDialog(context);
            progressDialog.setMessage("Loading file");
            progressDialog.setCancelable(false);
            progressDialog.setIndeterminate(false);
            progressDialog.setMax(100);
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);           
            progressDialog.show();
        }catch(Exception e){
            if (BuildConfig.DEBUG) Log.e(TAG,"onPostExecute",e);
        }

        super.onPreExecute();
    }

    @Override
    protected void onCancelled() {
        try{
            if (progressDialog!=null && progressDialog.isShowing()){
                progressDialog.dismiss();
            }
        }catch(Exception e){
            if (BuildConfig.DEBUG) Log.e(TAG,"onPostExecute",e);
        }
        super.onCancelled();
    }

    @Override
    protected void onPostExecute(Void result) { 
        try{
            if (progressDialog!=null && progressDialog.isShowing()){
                progressDialog.dismiss();
            }
        }catch(Exception e){
            if (BuildConfig.DEBUG) Log.e(TAG,"onPostExecute",e);
        }

        //TODO: to do something after file loaded
        super.onPostExecute(result);
    }

    @Override
    protected void onProgressUpdate(Integer... values) {        
        int progress = values[0];
        if (progressDialog!=null) {            
            progressDialog.setProgress(progress);
        }
        super.onProgressUpdate(values);
    }

    private class ProgressFilterInputStream extends FilterInputStream {
        private int counter = 0;
        private long fileLength;
        private int maximum = 100;
        public ProgressFilterInputStream(InputStream in, long fileLength) {
            super(in);
            this.fileLength = fileLength;
        }

        @Override
        public int read(byte[] buffer, int offset, int count) throws IOException {
            if (counter==0){
                maximum = (int)(fileLength/buffer.length);
            }
            publishProgress((counter++)*100/maximum);
            return super.read(buffer, offset, count);
        }
    }
}
public类OpenXMLFileOperator扩展异步任务{
私有进程对话;
私有字符串文件路径;
私人语境;
公共OpenFileOperator(上下文、字符串文件路径){
this.context=上下文;
this.filePath=filePath;
}
@凌驾
受保护的Void doInBackground(Void…arg0){
试试{
if(filePath!=null){
文件文件=新文件(文件路径);
如果(file.exists()){
InputStream=新文件InputStream(文件);
ProgressFilterInputStream pfis=新的ProgressFilterInputStream(stream,file.length());
读卡器=新的InputStreamReader(pfis,“UTF-8”);
YourXMLHandle yourHandle=newyourXmlHandle();
parse(reader,yourHandle);
stream.close();
reader.close();
pfis.close();
}                
}
}捕获(例外e){
if(BuildConfig.DEBUG)Log.e(标记“Exception”,e);
}
返回null;
}
@凌驾
受保护的void onPreExecute(){
试一试{
progressDialog=新建progressDialog(上下文);
progressDialog.setMessage(“加载文件”);
progressDialog.setCancelable(假);
progressDialog.setUndeterminate(false);
progressDialog.setMax(100);
progressDialog.setProgressStyle(progressDialog.STYLE_水平);
progressDialog.show();
}捕获(例外e){
if(BuildConfig.DEBUG)Log.e(标记“onPostExecute”,e);
}
super.onPreExecute();
}
@凌驾
受保护的void onCancelled(){
试一试{
if(progressDialog!=null&&progressDialog.isShowing()){
progressDialog.disclose();
}
}捕获(例外e){
if(BuildConfig.DEBUG)Log.e(标记“onPostExecute”,e);
}
super.onCancelled();
}
@凌驾
受保护的void onPostExecute(void结果){
试一试{
if(progressDialog!=null&&progressDialog.isShowing()){
progressDialog.disclose();
}
}捕获(例外e){
if(BuildConfig.DEBUG)Log.e(标记“onPostExecute”,e);
}
//TODO:在加载文件后执行某些操作
super.onPostExecute(结果);
}
@凌驾
受保护的void onProgressUpdate(整型…值){
int progress=值[0];
如果(progressDialog!=null){
progressDialog.setProgress(progress);
}
super.onProgressUpdate(值);
}
私有类ProgressFilterInputStream扩展FilterInputStream{
专用整数计数器=0;
私有长文件长度;
私有整数最大值=100;
public ProgressFilterInputStream(输入流输入,长文件长度){
超级(in),;
this.fileLength=文件长度;
}
@凌驾
公共整数读取(字节[]缓冲区、整数偏移量、整数计数)引发IOException{
如果(计数器==0){
最大值=(int)(fileLength/buffer.length);
}
出版进度(计数器++)*100/最大值);
返回super.read(缓冲区、偏移量、计数);
}
}
}

这是个不错的主意,但是如何从解析器中访问我的
FilterInputStream
?或者我应该创建一个计时器,从somwhere外部调用getter并相应地更新状态?从外部执行此操作,以使其独立于解析本身。我尝试了这种方法,但解析程序在相当长的一段时间内没有增加计数器,然后突然一次消耗所有的
InputStream
。还有什么其他的想法可以实现吗?我想在等待了很长时间之后,解析器会继续阅读!除了尝试调试正在发生的事情之外,现在想不出任何更好的方法。在过滤器和处理程序中添加一些调试打印?