2011-02-16 49 views
2

我有一个SAXDefaultHandler,它解析一个InputStream。我不知道有多少元素在XML,所以我不能指望他们在endElement或simmilar。我知道InputStream(从http头中读取)的字节长度,但我找不到一种方法来获取解析过程的当前字节进度。安卓:SAX解析器进度监控

有没有办法让目前的进展分析过程中(即比特处理)?

这是DefaultHandler被怎么称呼:

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

回答

0

您可以通过编写一个FilterInputStream来包装现有的inputStream做到这一点。在你的过滤器的方法read(),增加一个计数器,并提供一个getter,使别的东西可以跟踪当前计数。

因为解析器可以读取提前,这将是近似的,但它可能是你能做的最好的。

+0

很好的想法,但我如何访问我的`FilterInputStream`从解析器内?或者我应该创建一个**定时器**,它从外部somwhere调用getter并根据情况更新状态? – Mannaz 2011-02-16 17:51:07

3

对于任何人谁是仍在寻找答案, 尝试通过进度条在派生FilterInputStream的构造函数:

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); 
} 
} 

我用它在的AsyncTask我

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); 
1

从lx222扩展回答,我实现了AsyncTask,ProgressDialog。后期,但我希望它可能有用一个:D

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); 
     } 
    } 
}