FileDocCategorySizeDatePackage
StreamLoader.javaAPI DocAndroid 1.5 API6897Wed May 06 22:41:56 BST 2009android.webkit

StreamLoader

public abstract class StreamLoader extends android.os.Handler
This abstract class is used for all content loaders that rely on streaming content into the rendering engine loading framework. The class implements a state machine to load the content into the frame in a similar manor to the way content arrives from the network. The class uses messages to move from one state to the next, which enables async. loading of the streamed content. Classes that inherit from this class must implement two methods, the first method is used to setup the InputStream and notify the loading framework if it can load it's content. The other method allows the derived class to add additional HTTP headers to the response. By default, content loaded with a StreamLoader is marked with a HTTP header that indicates the content should not be cached.

Fields Summary
public static final String
NO_STORE
private static final int
MSG_STATUS
private static final int
MSG_HEADERS
private static final int
MSG_DATA
private static final int
MSG_END
protected LoadListener
mHandler
protected InputStream
mDataStream
protected long
mContentLength
private byte[]
mData
Constructors Summary
StreamLoader(LoadListener loadlistener)
Constructor. Although this class calls the LoadListener, it only calls the EventHandler Interface methods. LoadListener concrete class is used to avoid the penality of calling an interface.

param
loadlistener The LoadListener to call with the data.

 // buffer to pass data to loader with.

                                             
      
        mHandler = loadlistener;
    
Methods Summary
protected abstract voidbuildHeaders(android.net.http.Headers headers)
This method is called when the headers are about to be sent to the load framework. The derived class has the opportunity to add addition headers.

param
headers Map of HTTP headers that will be sent to the loader.

private voidcloseStreamAndSendEndData()
Close the stream and inform the EventHandler that load is complete.

        if (mDataStream != null) {
            try {
                mDataStream.close();
            } catch (IOException ex) {
                // ignore.
            }
        }
        mHandler.endData();
    
public voidhandleMessage(android.os.Message msg)

        if (Config.DEBUG && mHandler.isSynchronous()) {
            throw new AssertionError();
        }
        switch(msg.what) {
            case MSG_STATUS:
                if (setupStreamAndSendStatus()) {
                    // We were able to open the stream, create the array
                    // to pass data to the loader
                    mData = new byte[8192];
                    sendMessage(obtainMessage(MSG_HEADERS));
                }
                break;
            case MSG_HEADERS:
                sendHeaders();
                sendMessage(obtainMessage(MSG_DATA));
                break;
            case MSG_DATA:
                if (sendData()) {
                    sendMessage(obtainMessage(MSG_END));
                } else {
                    sendMessage(obtainMessage(MSG_DATA));
                }
                break;
            case MSG_END:
                closeStreamAndSendEndData();
                break;
            default:
                super.handleMessage(msg);
                break;
        }
    
public voidload()
Calling this method starts the load of the content for this StreamLoader. This method simply posts a message to send the status and returns immediately.

        if (!mHandler.isSynchronous()) {
            sendMessage(obtainMessage(MSG_STATUS));
        } else {
            // Load the stream synchronously.
            if (setupStreamAndSendStatus()) {
                // We were able to open the stream, create the array
                // to pass data to the loader
                mData = new byte[8192];
                sendHeaders();
                while (!sendData());
                closeStreamAndSendEndData();
                mHandler.loadSynchronousMessages();
            }
        }
    
private booleansendData()
Read data from the stream and pass it to the EventHandler. If an error occurs reading the stream, then an error is sent to the EventHandler, and moves onto the next state - end of data.

return
True if all the data has been read. False if sendData should be called again.

        if (mDataStream != null) {
            try {
                int amount = mDataStream.read(mData);
                if (amount > 0) {
                    mHandler.data(mData, amount);
                    return false;
                }
            } catch (IOException ex) {
                mHandler.error(EventHandler.FILE_ERROR,
                               ex.getMessage());
            }
        }
        return true;
    
private voidsendHeaders()
Construct the headers and pass them to the EventHandler.

        Headers headers = new Headers();
        if (mContentLength > 0) {
            headers.setContentLength(mContentLength);
        }
        headers.setCacheControl(NO_STORE);
        buildHeaders(headers);
        mHandler.headers(headers);
    
protected abstract booleansetupStreamAndSendStatus()
This method is called when the derived class should setup mDataStream, and call mHandler.status() to indicate that the load can occur. If it fails to setup, it should still call status() with the error code.

return
true if stream was successfully setup