Android Open Source - Volley-Ball Ball Request






From Project

Back to project page Volley-Ball.

License

The source code is released under:

MIT License

If you think the Android project Volley-Ball listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.siu.android.volleyball;
//  w  w  w  .j  a  va  2s  .c  om
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;

import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.siu.android.volleyball.exception.BallException;
import com.siu.android.volleyball.local.LocalRequestProcessor;
import com.siu.android.volleyball.network.NetworkRequestProcessor;
import com.siu.android.volleyball.response.ResponseListener;

/**
 * Created by lukas on 8/29/13.
 */
public abstract class BallRequest<T> extends Request<T> {

    /* Private fields from Request class */
    protected static final long SLOW_REQUEST_THRESHOLD_MS = 3000;
    protected final BallMarkerLog mEventLog = BallMarkerLog.ENABLED ? new BallMarkerLog() : null;
    protected long mRequestBirthTime = 0;
    protected BallRequestQueue mRequestQueue;


    /* Additionnal logic from Ball */
    protected LocalRequestProcessor<T> mLocalRequestProcessor;
    protected NetworkRequestProcessor<T> mNetworkRequestProcessor;
    protected ResponseListener mResponseListener;

    /**
     * Error from final response, stored and used later if intermediate response is still to be delivered:
     * If intermediate response is delivered after with no response, deliver the final error
     */
    private VolleyError mFinalResponseError;

    protected boolean mFinalResponseDelivered = false;

    /**
     * Intermediate response of the request has been delivered.
     * <p/>
     * Several use cases:
     * - In the executor delivery to consider only the 1st intermediate request and ignore the 2nd one.
     * - REMOVED FOR NOW, NOT VOLATILE -- In the network dispatcher to return identical response in case of 304 not modified response
     * and if a valid intermediate response was returned. Must be volatile because it can apply between
     * local and network thread.
     */
    protected boolean mIntermediateResponseDelivered = false;

    /**
     * Request is finished and no more response should be delivered
     * Volatile because it is used to determine if a marker should be added to the log,
     * and value need to be synchronized between all worker threads
     */
    protected volatile boolean mFinished = false;

    private boolean mLocalIntermediateResponseDelivered = false;
    private boolean mCacheIntermediateResponseDelivered = false;
    private boolean mIntermediateResponseDeliveredWithSuccess = false;


    protected BallRequest(int method, String url, Response.ErrorListener errorListener) {
        super(method, url, errorListener);

        if (shouldProcessLocal()) {
            mLocalRequestProcessor = createLocalRequestProcessor();

            if (mLocalRequestProcessor == null) {
                throw new BallException("Request should process local but local request processor is not provided");
            }
        }

        if (shouldProcessNetwork()) {
            mNetworkRequestProcessor = createNetworkRequestProcessor();

            if (mNetworkRequestProcessor == null) {
                throw new BallException("Request should process network but network request processor is not provided");
            }
        }

    }

    protected BallRequest(int method, String url, ResponseListener<T> responseListener, Response.ErrorListener errorListener) {
        this(method, url, errorListener);
        mResponseListener = responseListener;
    }

    @Override
    public void deliverResponse(T response) {
        throw new BallException("Illegal call to #deliverResponse(), you need to call the new #deliverIntermediate and #deliverFinal methods");
    }


    /* Override from parent because of return type or proctected scope */

    @Override
    protected final Response<T> parseNetworkResponse(NetworkResponse response) {
        throw new BallException("Illegal call to #parseBallNetworkResponse, you need to call the new #parseBallNetworkResponse() method");
    }

    //abstract protected BallResponse<T> parseBallNetworkResponse(NetworkResponse response);


    protected VolleyError parseNetworkError(VolleyError volleyError) {
        return super.parseNetworkError(volleyError);
    }

    public void addMarker(String tag) {
        // ignore adding marker to finished log because it can happen when markers are added from several parallel threads
        if (mFinished) {
            return;
        }

        if (BallMarkerLog.ENABLED) {
            try {
                mEventLog.add(tag, Thread.currentThread().getId());
            } catch (IllegalStateException e) {
                // ignore exception from adding marker to finished log because it can happen when
                // markers are added from several parallel threads
            }
        } else if (mRequestBirthTime == 0) {
            mRequestBirthTime = SystemClock.elapsedRealtime();
        }
    }

    public void finish(final String tag) {
        if (mFinished) {
            throw new BallException("Trying to finish an already finished request");
        }

        mFinished = true;

        if (mRequestQueue != null) {
            mRequestQueue.finish(this);
        }

        if (BallMarkerLog.ENABLED) {
            final long threadId = Thread.currentThread().getId();
            if (Looper.myLooper() != Looper.getMainLooper()) {
                // If we finish marking off of the main thread, we need to
                // actually do it on the main thread to ensure correct ordering.
                Handler mainThread = new Handler(Looper.getMainLooper());
                mainThread.post(new Runnable() {
                    @Override
                    public void run() {
                        mEventLog.add(tag, threadId);
                        mEventLog.finish(this.toString());
                    }
                });
                return;
            }

            mEventLog.add(tag, threadId);
            mEventLog.finish(this.toString());
        } else {
            long requestTime = SystemClock.elapsedRealtime() - mRequestBirthTime;
            if (requestTime >= SLOW_REQUEST_THRESHOLD_MS) {
                VolleyLog.d("%d ms: %s", requestTime, this.toString());
            }
        }
    }

    public void setRequestQueue(BallRequestQueue requestQueue) {
        mRequestQueue = requestQueue;
    }


    /* Override to get local processing */

    public boolean shouldProcessLocal() {
        return false;
    }

    protected LocalRequestProcessor<T> createLocalRequestProcessor() {
        return null;
    }


    /* Override to get network processing */

    public boolean shouldProcessNetwork() {
        return false;
    }

    protected NetworkRequestProcessor createNetworkRequestProcessor() {
        return null;
    }


    /* Complete request */

    public void deliverIntermediateResponse(T response, BallResponse.ResponseSource responseSource) {
        assertListenerExists();
        mResponseListener.onIntermediateResponse(response, responseSource);
    }

    public void deliverFinalResponse(T response, BallResponse.ResponseSource responseSource) {
        assertListenerExists();
        mResponseListener.onFinalResponse(response, responseSource);
    }

    public void deliverIdenticalFinalResponse(BallResponse.ResponseSource responseSource) {
        assertListenerExists();
        mResponseListener.onFinalResponseIdenticalToIntermediate(responseSource);
    }

    protected void assertListenerExists() {
        if (mResponseListener == null) {
            throw new BallException("Listener is null, you need to provide one or override deliverIntermediateResponse and deliverFinalResponse");
        }
    }

    public boolean isCompleteRequest() {
        return shouldProcessLocal() && shouldProcessNetwork();
    }

    /**
     * Only request with both local and networking processing have intermediate response aspect
     *
     * @return true if the request can have intermediate response, false otherwise
     */
    public boolean canHaveIntermediateResponse() {
        return shouldProcessLocal() && shouldProcessNetwork();
    }



    /* Gets and sets */

    public LocalRequestProcessor<T> getLocalRequestProcessor() {
        return mLocalRequestProcessor;
    }

    public NetworkRequestProcessor<T> getNetworkRequestProcessor() {
        return mNetworkRequestProcessor;
    }

    public boolean isFinalResponseDelivered() {
        return mFinalResponseDelivered;
    }

    public void setFinalResponseDelivered(boolean finalResponseDelivered) {
        this.mFinalResponseDelivered = finalResponseDelivered;
    }

    public boolean isIntermediateResponseDelivered() {
        return mIntermediateResponseDelivered;
    }

    public void setIntermediateResponseDelivered(boolean intermediateResponseDelivered) {
        this.mIntermediateResponseDelivered = intermediateResponseDelivered;
    }

    public boolean isFinished() {
        return mFinished;
    }

    public void setFinished(boolean finished) {
        this.mFinished = finished;
    }

    public VolleyError getFinalResponseError() {
        return mFinalResponseError;
    }

    public void setFinalResponseError(VolleyError finalResponseError) {
        mFinalResponseError = finalResponseError;
    }

//    public boolean areAllIntermediateResponsesDelivered() {
//        return mLocalIntermediateResponseDelivered && mCacheIntermediateResponseDelivered;
//    }
//
//    public void markIntermediateResponseDelivered(BallResponse.ResponseSource source) {
//        switch (source) {
//            case LOCAL:
//                if (mLocalIntermediateResponseDelivered) {
//                    throw new BallException("local intermediate response already delivered");
//                }
//
//                mLocalIntermediateResponseDelivered = true;
//                break;
//            case CACHE:
//                if (mCacheIntermediateResponseDelivered) {
//                    throw new BallException("cache intermediate response already delivered");
//                }
//
//                mCacheIntermediateResponseDelivered = true;
//                break;
//            default:
//                throw new BallException("mark intermediate response delivered from invalid source");
//        }
//    }
//
//    public boolean isIntermediateResponseDeliveredWithSuccess() {
//        return mIntermediateResponseDeliveredWithSuccess;
//    }
//
//    public void setIntermediateResponseDeliveredWithSuccess(boolean intermediateResponseDeliveredWithSuccess) {
//        mIntermediateResponseDeliveredWithSuccess = intermediateResponseDeliveredWithSuccess;
//    }
}




Java Source Code List

.BallExecutorDelivery.java
.LocalRequest.java
com.android.volley.CompatRequest.java
com.siu.android.volleyball.BallCacheDispatcher.java
com.siu.android.volleyball.BallMarkerLog.java
com.siu.android.volleyball.BallNetworkDispatcher.java
com.siu.android.volleyball.BallRequestQueue.java
com.siu.android.volleyball.BallRequest.java
com.siu.android.volleyball.BallResponseDelivery.java
com.siu.android.volleyball.BallResponse.java
com.siu.android.volleyball.ball.BallExecutorDelivery.java
com.siu.android.volleyball.exception.BallException.java
com.siu.android.volleyball.local.LocalDispatcher.java
com.siu.android.volleyball.local.LocalRequestProcessor.java
com.siu.android.volleyball.mock.FileMockNetwork.java
com.siu.android.volleyball.network.NetworkRequestProcessor.java
com.siu.android.volleyball.request.CompleteRequest.java
com.siu.android.volleyball.request.LocalRequest.java
com.siu.android.volleyball.request.NetworkRequest.java
com.siu.android.volleyball.response.ResponseListener.java
com.siu.android.volleyball.response.SingleResponseListener.java
com.siu.android.volleyball.samples.Application.java
com.siu.android.volleyball.samples.Constants.java
com.siu.android.volleyball.samples.activity.CompleteRequestActivity.java
com.siu.android.volleyball.samples.activity.LocalRequestActivity.java
com.siu.android.volleyball.samples.activity.NetworkRequestActivity.java
com.siu.android.volleyball.samples.activity.ScenariosActivity.java
com.siu.android.volleyball.samples.activity.scenarios.Scenario10Activity.java
com.siu.android.volleyball.samples.activity.scenarios.Scenario1Activity.java
com.siu.android.volleyball.samples.activity.scenarios.Scenario2Activity.java
com.siu.android.volleyball.samples.activity.scenarios.Scenario3Activity.java
com.siu.android.volleyball.samples.activity.scenarios.Scenario4Activity.java
com.siu.android.volleyball.samples.activity.scenarios.Scenario5Activity.java
com.siu.android.volleyball.samples.activity.scenarios.Scenario6Activity.java
com.siu.android.volleyball.samples.activity.scenarios.Scenario7Activity.java
com.siu.android.volleyball.samples.activity.scenarios.Scenario8Activity.java
com.siu.android.volleyball.samples.activity.scenarios.Scenario9Activity.java
com.siu.android.volleyball.samples.activity.scenarios.ScenarioActivity.java
com.siu.android.volleyball.samples.adapter.BindableAdapter.java
com.siu.android.volleyball.samples.adapter.EntriesAdapter.java
com.siu.android.volleyball.samples.adapter.LogsAdapter.java
com.siu.android.volleyball.samples.database.DatabaseHelper.java
com.siu.android.volleyball.samples.database.EntryDao.java
com.siu.android.volleyball.samples.database.mapping.EntryMapping.java
com.siu.android.volleyball.samples.fragment.LocalOnlyRequestFragment.java
com.siu.android.volleyball.samples.model.Entry.java
com.siu.android.volleyball.samples.model.Log.java
com.siu.android.volleyball.samples.util.ScenarioUtils.java
com.siu.android.volleyball.samples.util.SimpleLogger.java
com.siu.android.volleyball.samples.volley.OkHttpStack.java
com.siu.android.volleyball.samples.volley.ScenarioListener.java
com.siu.android.volleyball.samples.volley.fake.FakeCache.java
com.siu.android.volleyball.samples.volley.fake.FakeNetwork.java
com.siu.android.volleyball.samples.volley.request.CompleteEntryRequest.java
com.siu.android.volleyball.samples.volley.request.SampleErrorNetworkRequest.java
com.siu.android.volleyball.samples.volley.request.SampleLocalNoResultRequest.java
com.siu.android.volleyball.samples.volley.request.SampleLocalRequest.java
com.siu.android.volleyball.samples.volley.request.SampleNetworkRequest.java
com.siu.android.volleyball.samples.volley.request.SampleRequest.java
com.siu.android.volleyball.samples.volley.request.ScenarioRequest.java
com.siu.android.volleyball.toolbox.BallImageLoader.java
com.siu.android.volleyball.toolbox.BallImageRequest.java
com.siu.android.volleyball.toolbox.BallNetworkImageView.java
com.siu.android.volleyball.toolbox.BallRequestFuture.java
com.siu.android.volleyball.toolbox.VolleyBallConfig.java
com.siu.android.volleyball.toolbox.VolleyBall.java
com.siu.android.volleyball.util.BallLogger.java
com.siu.android.volleyball.util.ConfigUtils.java
com.siu.android.volleyball.util.RequestUtils.java