Android: SAX анализатор хода выполнения - PullRequest
2 голосов
/ 16 февраля 2011

У меня есть SAX DefaultHandler , который анализирует InputStream.Я не знаю, сколько элементов в XML, поэтому я не могу рассчитывать их на endElement или simmilar.Я делаю знаю длину байта InputStream (считанную из заголовка http), но не могу найти метод для получения текущего побитового прогресса процесса синтаксического анализа.Есть ли способ получить текущий прогресс (то есть обработанные биты) процесса синтаксического анализа?

Вот как вызывается DefaultHandler:

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

Ответы [ 3 ]

3 голосов
/ 23 марта 2013

Для тех, кто все еще ищет ответ, попробуйте передать ProgressBar в конструктор вашего производного 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 голос
/ 02 декабря 2014

Расширен от 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);
        }
    }
}
0 голосов
/ 16 февраля 2011

Вы можете сделать это, написав FilterInputStream , чтобы обернуть существующий inputStream.В методе read() вашего фильтра увеличьте счетчик и предоставьте получатель, чтобы что-то еще могло отследить текущий счет.лучшее, что ты можешь сделать.

...