├── res ├── drawable-hdpi │ └── ic_launcher.png ├── drawable-mdpi │ └── ic_launcher.png ├── drawable-xhdpi │ └── ic_launcher.png ├── values │ ├── strings.xml │ └── styles.xml ├── values-v11 │ └── styles.xml └── values-v14 │ └── styles.xml ├── src └── com │ └── android │ └── volley │ ├── ext │ ├── HttpCallback.java │ ├── display │ │ └── IDisplayer.java │ ├── PauseOnScrollListener.java │ ├── ContentLengthInputStream.java │ └── RequestInfo.java │ ├── toolbox │ ├── multipart │ │ ├── Part.java │ │ ├── UrlEncodingHelper.java │ │ ├── BasePart.java │ │ ├── Boundary.java │ │ ├── MultipartEntity.java │ │ ├── FilePart.java │ │ └── StringPart.java │ ├── InflatingEntity.java │ ├── Authenticator.java │ ├── NoCache.java │ ├── HttpStack.java │ ├── DownloadRequest.java │ ├── UploadMultipartEntity.java │ ├── JsonArrayRequest.java │ ├── ClearCacheRequest.java │ ├── BitmapCache.java │ ├── ContentLengthInputStream.java │ ├── disklrucache │ │ └── Util.java │ ├── StringRequest.java │ ├── JsonObjectRequest.java │ ├── PoolingByteArrayOutputStream.java │ ├── JsonRequest.java │ ├── MultiPartRequest.java │ ├── AndroidAuthenticator.java │ ├── RequestFuture.java │ ├── Volley.java │ ├── HttpHeaderParser.java │ └── ByteArrayPool.java │ ├── db │ ├── sqlite │ │ ├── ColumnDbType.java │ │ ├── FinderLazyLoader.java │ │ ├── ForeignLazyLoader.java │ │ ├── SqlInfo.java │ │ ├── Selector.java │ │ ├── DbModelSelector.java │ │ └── CursorUtils.java │ ├── annotation │ │ ├── NoAutoIncrement.java │ │ ├── Finder.java │ │ ├── Transient.java │ │ ├── Id.java │ │ ├── Foreign.java │ │ ├── NotNull.java │ │ ├── Unique.java │ │ ├── Column.java │ │ ├── Table.java │ │ └── Check.java │ ├── converter │ │ ├── ColumnConverter.java │ │ ├── ByteArrayColumnConverter.java │ │ ├── StringColumnConverter.java │ │ ├── LongColumnConverter.java │ │ ├── FloatColumnConverter.java │ │ ├── ByteColumnConverter.java │ │ ├── ShortColumnConverter.java │ │ ├── DoubleColumnConverter.java │ │ ├── IntegerColumnConverter.java │ │ ├── CharColumnConverter.java │ │ ├── DateColumnConverter.java │ │ ├── SqlDateColumnConverter.java │ │ ├── BooleanColumnConverter.java │ │ └── ColumnConverterFactory.java │ ├── table │ │ ├── KeyValue.java │ │ ├── DbModel.java │ │ ├── Finder.java │ │ ├── Id.java │ │ ├── Table.java │ │ ├── Column.java │ │ └── Foreign.java │ └── DbException.java │ ├── TimeoutError.java │ ├── NoConnectionError.java │ ├── ServerError.java │ ├── Network.java │ ├── ParseError.java │ ├── NetworkError.java │ ├── ResponseDelivery.java │ ├── RetryPolicy.java │ ├── VolleyError.java │ ├── AuthFailureError.java │ ├── NetworkResponse.java │ ├── Response.java │ ├── DefaultRetryPolicy.java │ ├── Cache.java │ ├── ExecutorDelivery.java │ └── NetworkDispatcher.java ├── .gitignore ├── .classpath ├── AndroidManifest.xml ├── project.properties ├── proguard-project.txt ├── .project └── README.md /res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bacy/volley/HEAD/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bacy/volley/HEAD/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bacy/volley/HEAD/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Volleyball_dev 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/com/android/volley/ext/HttpCallback.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.ext; 2 | 3 | public interface HttpCallback { 4 | public void onStart(); 5 | public void onFinish(); 6 | public void onResult(String string); 7 | public void onError(Exception e); 8 | public void onCancelled(); 9 | public void onLoading(long count, long current); 10 | } 11 | -------------------------------------------------------------------------------- /res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | 15 | # Gradle files 16 | .gradle/ 17 | build/ 18 | 19 | # Local configuration file (sdk path, etc) 20 | local.properties 21 | 22 | # Proguard folder generated by Eclipse 23 | proguard/ 24 | 25 | # Log Files 26 | *.log 27 | .settings/ 28 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/multipart/Part.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.toolbox.multipart; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | 6 | /** 7 | * @author Vitaliy Khudenko 8 | */ 9 | public interface Part { 10 | public long getContentLength(Boundary boundary); 11 | public void writeTo(final OutputStream out, Boundary boundary) throws IOException; 12 | } 13 | -------------------------------------------------------------------------------- /res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/com/android/volley/db/sqlite/ColumnDbType.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.sqlite; 2 | 3 | /** 4 | * Created by wyouflf on 14-2-20. 5 | */ 6 | public enum ColumnDbType { 7 | 8 | INTEGER("INTEGER"), REAL("REAL"), TEXT("TEXT"), BLOB("BLOB"); 9 | 10 | private String value; 11 | 12 | ColumnDbType(String value) { 13 | this.value = value; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/com/android/volley/db/annotation/NoAutoIncrement.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Author: wyouflf 10 | * Date: 13-9-24 11 | * Time: 上午9:33 12 | */ 13 | @Target(ElementType.FIELD) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface NoAutoIncrement { 16 | } 17 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/com/android/volley/db/annotation/Finder.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Author: wyouflf 10 | * Date: 13-9-10 11 | * Time: 下午6:44 12 | */ 13 | @Target(ElementType.FIELD) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface Finder { 16 | 17 | String valueColumn(); 18 | 19 | String targetColumn(); 20 | } 21 | -------------------------------------------------------------------------------- /src/com/android/volley/ext/display/IDisplayer.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.ext.display; 2 | 3 | import android.graphics.Bitmap; 4 | import android.view.View; 5 | 6 | import com.android.volley.ext.tools.BitmapTools.BitmapDisplayConfig; 7 | 8 | public interface IDisplayer { 9 | void loadCompletedisplay(View imageView, Bitmap bitmap, BitmapDisplayConfig config); 10 | 11 | void loadFailDisplay(View view, BitmapDisplayConfig config); 12 | 13 | void loadDefaultDisplay(View view, BitmapDisplayConfig config); 14 | } 15 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 9 | 10 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/com/android/volley/db/converter/ColumnConverter.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import com.android.volley.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午8:57 11 | */ 12 | public interface ColumnConverter { 13 | 14 | T getFieldValue(final Cursor cursor, int index); 15 | 16 | T getFieldValue(String fieldStringValue); 17 | 18 | Object fieldValue2ColumnValue(T fieldValue); 19 | 20 | ColumnDbType getColumnDbType(); 21 | } 22 | -------------------------------------------------------------------------------- /project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-19 15 | android.library=true 16 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/multipart/UrlEncodingHelper.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.toolbox.multipart; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.net.URLEncoder; 5 | 6 | import org.apache.http.protocol.HTTP; 7 | 8 | public class UrlEncodingHelper { 9 | 10 | public static String encode(final String content, final String encoding) { 11 | try { 12 | return URLEncoder.encode( 13 | content, 14 | encoding != null ? encoding : HTTP.DEFAULT_CONTENT_CHARSET 15 | ); 16 | } catch (UnsupportedEncodingException problem) { 17 | throw new IllegalArgumentException(problem); 18 | } 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/InflatingEntity.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.toolbox; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.util.zip.GZIPInputStream; 6 | 7 | import org.apache.http.HttpEntity; 8 | import org.apache.http.entity.HttpEntityWrapper; 9 | 10 | public class InflatingEntity extends HttpEntityWrapper { 11 | public InflatingEntity(HttpEntity wrapped) { 12 | super(wrapped); 13 | } 14 | 15 | @Override 16 | public InputStream getContent() throws IOException { 17 | return new GZIPInputStream(wrappedEntity.getContent()); 18 | } 19 | 20 | @Override 21 | public long getContentLength() { 22 | return wrappedEntity.getContentLength(); 23 | } 24 | } -------------------------------------------------------------------------------- /res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /src/com/android/volley/TimeoutError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | /** 20 | * Indicates that the connection or the socket timed out. 21 | */ 22 | @SuppressWarnings("serial") 23 | public class TimeoutError extends VolleyError { } 24 | -------------------------------------------------------------------------------- /src/com/android/volley/db/converter/ByteArrayColumnConverter.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import com.android.volley.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午10:51 11 | */ 12 | public class ByteArrayColumnConverter implements ColumnConverter { 13 | @Override 14 | public byte[] getFieldValue(final Cursor cursor, int index) { 15 | return cursor.isNull(index) ? null : cursor.getBlob(index); 16 | } 17 | 18 | @Override 19 | public byte[] getFieldValue(String fieldStringValue) { 20 | return null; 21 | } 22 | 23 | @Override 24 | public Object fieldValue2ColumnValue(byte[] fieldValue) { 25 | return fieldValue; 26 | } 27 | 28 | @Override 29 | public ColumnDbType getColumnDbType() { 30 | return ColumnDbType.BLOB; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/com/android/volley/db/converter/StringColumnConverter.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.converter; 2 | 3 | import android.database.Cursor; 4 | 5 | import com.android.volley.db.sqlite.ColumnDbType; 6 | 7 | /** 8 | * Author: wyouflf 9 | * Date: 13-11-4 10 | * Time: 下午10:51 11 | */ 12 | public class StringColumnConverter implements ColumnConverter { 13 | @Override 14 | public String getFieldValue(final Cursor cursor, int index) { 15 | return cursor.isNull(index) ? null : cursor.getString(index); 16 | } 17 | 18 | @Override 19 | public String getFieldValue(String fieldStringValue) { 20 | return fieldStringValue; 21 | } 22 | 23 | @Override 24 | public Object fieldValue2ColumnValue(String fieldValue) { 25 | return fieldValue; 26 | } 27 | 28 | @Override 29 | public ColumnDbType getColumnDbType() { 30 | return ColumnDbType.TEXT; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Volleyball_dev 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/com/android/volley/db/table/KeyValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.table; 17 | 18 | public class KeyValue { 19 | public final String key; 20 | public final Object value; 21 | 22 | public KeyValue(String key, Object value) { 23 | this.key = key; 24 | this.value = value; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/com/android/volley/db/converter/LongColumnConverter.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.converter; 2 | 3 | import android.database.Cursor; 4 | import android.text.TextUtils; 5 | 6 | import com.android.volley.db.sqlite.ColumnDbType; 7 | 8 | /** 9 | * Author: wyouflf 10 | * Date: 13-11-4 11 | * Time: 下午10:51 12 | */ 13 | public class LongColumnConverter implements ColumnConverter { 14 | @Override 15 | public Long getFieldValue(final Cursor cursor, int index) { 16 | return cursor.isNull(index) ? null : cursor.getLong(index); 17 | } 18 | 19 | @Override 20 | public Long getFieldValue(String fieldStringValue) { 21 | if (TextUtils.isEmpty(fieldStringValue)) return null; 22 | return Long.valueOf(fieldStringValue); 23 | } 24 | 25 | @Override 26 | public Object fieldValue2ColumnValue(Long fieldValue) { 27 | return fieldValue; 28 | } 29 | 30 | @Override 31 | public ColumnDbType getColumnDbType() { 32 | return ColumnDbType.INTEGER; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/com/android/volley/db/converter/FloatColumnConverter.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.converter; 2 | 3 | import android.database.Cursor; 4 | import android.text.TextUtils; 5 | 6 | import com.android.volley.db.sqlite.ColumnDbType; 7 | 8 | /** 9 | * Author: wyouflf 10 | * Date: 13-11-4 11 | * Time: 下午10:51 12 | */ 13 | public class FloatColumnConverter implements ColumnConverter { 14 | @Override 15 | public Float getFieldValue(final Cursor cursor, int index) { 16 | return cursor.isNull(index) ? null : cursor.getFloat(index); 17 | } 18 | 19 | @Override 20 | public Float getFieldValue(String fieldStringValue) { 21 | if (TextUtils.isEmpty(fieldStringValue)) return null; 22 | return Float.valueOf(fieldStringValue); 23 | } 24 | 25 | @Override 26 | public Object fieldValue2ColumnValue(Float fieldValue) { 27 | return fieldValue; 28 | } 29 | 30 | @Override 31 | public ColumnDbType getColumnDbType() { 32 | return ColumnDbType.REAL; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/com/android/volley/db/converter/ByteColumnConverter.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.converter; 2 | 3 | import android.database.Cursor; 4 | import android.text.TextUtils; 5 | 6 | import com.android.volley.db.sqlite.ColumnDbType; 7 | 8 | /** 9 | * Author: wyouflf 10 | * Date: 13-11-4 11 | * Time: 下午10:51 12 | */ 13 | public class ByteColumnConverter implements ColumnConverter { 14 | @Override 15 | public Byte getFieldValue(final Cursor cursor, int index) { 16 | return cursor.isNull(index) ? null : (byte) cursor.getInt(index); 17 | } 18 | 19 | @Override 20 | public Byte getFieldValue(String fieldStringValue) { 21 | if (TextUtils.isEmpty(fieldStringValue)) return null; 22 | return Byte.valueOf(fieldStringValue); 23 | } 24 | 25 | @Override 26 | public Object fieldValue2ColumnValue(Byte fieldValue) { 27 | return fieldValue; 28 | } 29 | 30 | @Override 31 | public ColumnDbType getColumnDbType() { 32 | return ColumnDbType.INTEGER; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/com/android/volley/db/converter/ShortColumnConverter.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.converter; 2 | 3 | import android.database.Cursor; 4 | import android.text.TextUtils; 5 | 6 | import com.android.volley.db.sqlite.ColumnDbType; 7 | 8 | /** 9 | * Author: wyouflf 10 | * Date: 13-11-4 11 | * Time: 下午10:51 12 | */ 13 | public class ShortColumnConverter implements ColumnConverter { 14 | @Override 15 | public Short getFieldValue(final Cursor cursor, int index) { 16 | return cursor.isNull(index) ? null : cursor.getShort(index); 17 | } 18 | 19 | @Override 20 | public Short getFieldValue(String fieldStringValue) { 21 | if (TextUtils.isEmpty(fieldStringValue)) return null; 22 | return Short.valueOf(fieldStringValue); 23 | } 24 | 25 | @Override 26 | public Object fieldValue2ColumnValue(Short fieldValue) { 27 | return fieldValue; 28 | } 29 | 30 | @Override 31 | public ColumnDbType getColumnDbType() { 32 | return ColumnDbType.INTEGER; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/com/android/volley/db/converter/DoubleColumnConverter.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.converter; 2 | 3 | import android.database.Cursor; 4 | import android.text.TextUtils; 5 | 6 | import com.android.volley.db.sqlite.ColumnDbType; 7 | 8 | /** 9 | * Author: wyouflf 10 | * Date: 13-11-4 11 | * Time: 下午10:51 12 | */ 13 | public class DoubleColumnConverter implements ColumnConverter { 14 | @Override 15 | public Double getFieldValue(final Cursor cursor, int index) { 16 | return cursor.isNull(index) ? null : cursor.getDouble(index); 17 | } 18 | 19 | @Override 20 | public Double getFieldValue(String fieldStringValue) { 21 | if (TextUtils.isEmpty(fieldStringValue)) return null; 22 | return Double.valueOf(fieldStringValue); 23 | } 24 | 25 | @Override 26 | public Object fieldValue2ColumnValue(Double fieldValue) { 27 | return fieldValue; 28 | } 29 | 30 | @Override 31 | public ColumnDbType getColumnDbType() { 32 | return ColumnDbType.REAL; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/com/android/volley/db/converter/IntegerColumnConverter.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.converter; 2 | 3 | import android.database.Cursor; 4 | import android.text.TextUtils; 5 | 6 | import com.android.volley.db.sqlite.ColumnDbType; 7 | 8 | /** 9 | * Author: wyouflf 10 | * Date: 13-11-4 11 | * Time: 下午10:51 12 | */ 13 | public class IntegerColumnConverter implements ColumnConverter { 14 | @Override 15 | public Integer getFieldValue(final Cursor cursor, int index) { 16 | return cursor.isNull(index) ? null : cursor.getInt(index); 17 | } 18 | 19 | @Override 20 | public Integer getFieldValue(String fieldStringValue) { 21 | if (TextUtils.isEmpty(fieldStringValue)) return null; 22 | return Integer.valueOf(fieldStringValue); 23 | } 24 | 25 | @Override 26 | public Object fieldValue2ColumnValue(Integer fieldValue) { 27 | return fieldValue; 28 | } 29 | 30 | @Override 31 | public ColumnDbType getColumnDbType() { 32 | return ColumnDbType.INTEGER; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/com/android/volley/db/annotation/Transient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Target(ElementType.FIELD) 24 | @Retention(RetentionPolicy.RUNTIME) 25 | public @interface Transient { 26 | } 27 | -------------------------------------------------------------------------------- /src/com/android/volley/db/annotation/Id.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Target(ElementType.FIELD) 24 | @Retention(RetentionPolicy.RUNTIME) 25 | public @interface Id { 26 | String column() default ""; 27 | } 28 | -------------------------------------------------------------------------------- /src/com/android/volley/db/converter/CharColumnConverter.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.converter; 2 | 3 | import android.database.Cursor; 4 | import android.text.TextUtils; 5 | 6 | import com.android.volley.db.sqlite.ColumnDbType; 7 | 8 | /** 9 | * Author: wyouflf 10 | * Date: 13-11-4 11 | * Time: 下午10:51 12 | */ 13 | public class CharColumnConverter implements ColumnConverter { 14 | @Override 15 | public Character getFieldValue(final Cursor cursor, int index) { 16 | return cursor.isNull(index) ? null : (char) cursor.getInt(index); 17 | } 18 | 19 | @Override 20 | public Character getFieldValue(String fieldStringValue) { 21 | if (TextUtils.isEmpty(fieldStringValue)) return null; 22 | return fieldStringValue.charAt(0); 23 | } 24 | 25 | @Override 26 | public Object fieldValue2ColumnValue(Character fieldValue) { 27 | if (fieldValue == null) return null; 28 | return (int) fieldValue; 29 | } 30 | 31 | @Override 32 | public ColumnDbType getColumnDbType() { 33 | return ColumnDbType.INTEGER; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/com/android/volley/NoConnectionError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | /** 20 | * Error indicating that no connection could be established when performing a Volley request. 21 | */ 22 | @SuppressWarnings("serial") 23 | public class NoConnectionError extends NetworkError { 24 | public NoConnectionError() { 25 | super(); 26 | } 27 | 28 | public NoConnectionError(Throwable reason) { 29 | super(reason); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/com/android/volley/db/annotation/Foreign.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Target(ElementType.FIELD) 24 | @Retention(RetentionPolicy.RUNTIME) 25 | public @interface Foreign { 26 | 27 | String column() default ""; 28 | 29 | String foreign(); 30 | } 31 | -------------------------------------------------------------------------------- /src/com/android/volley/db/annotation/NotNull.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | /** 24 | * Author: wyouflf 25 | * Date: 13-8-20 26 | * Time: 上午9:42 27 | */ 28 | @Target(ElementType.FIELD) 29 | @Retention(RetentionPolicy.RUNTIME) 30 | public @interface NotNull { 31 | } 32 | -------------------------------------------------------------------------------- /src/com/android/volley/db/annotation/Unique.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | /** 24 | * Author: wyouflf 25 | * Date: 13-8-20 26 | * Time: 上午9:41 27 | */ 28 | @Target(ElementType.FIELD) 29 | @Retention(RetentionPolicy.RUNTIME) 30 | public @interface Unique { 31 | } 32 | -------------------------------------------------------------------------------- /src/com/android/volley/db/annotation/Column.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Target(ElementType.FIELD) 24 | @Retention(RetentionPolicy.RUNTIME) 25 | public @interface Column { 26 | 27 | String column() default ""; 28 | 29 | String defaultValue() default ""; 30 | } 31 | -------------------------------------------------------------------------------- /src/com/android/volley/db/annotation/Table.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | @Target(ElementType.TYPE) 24 | @Retention(RetentionPolicy.RUNTIME) 25 | public @interface Table { 26 | 27 | String name() default ""; 28 | 29 | String execAfterTableCreated() default ""; 30 | } -------------------------------------------------------------------------------- /src/com/android/volley/db/converter/DateColumnConverter.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.converter; 2 | 3 | import java.util.Date; 4 | 5 | import android.database.Cursor; 6 | import android.text.TextUtils; 7 | 8 | import com.android.volley.db.sqlite.ColumnDbType; 9 | 10 | /** 11 | * Author: wyouflf 12 | * Date: 13-11-4 13 | * Time: 下午10:51 14 | */ 15 | public class DateColumnConverter implements ColumnConverter { 16 | @Override 17 | public Date getFieldValue(final Cursor cursor, int index) { 18 | return cursor.isNull(index) ? null : new Date(cursor.getLong(index)); 19 | } 20 | 21 | @Override 22 | public Date getFieldValue(String fieldStringValue) { 23 | if (TextUtils.isEmpty(fieldStringValue)) return null; 24 | return new Date(Long.valueOf(fieldStringValue)); 25 | } 26 | 27 | @Override 28 | public Object fieldValue2ColumnValue(Date fieldValue) { 29 | if (fieldValue == null) return null; 30 | return fieldValue.getTime(); 31 | } 32 | 33 | @Override 34 | public ColumnDbType getColumnDbType() { 35 | return ColumnDbType.INTEGER; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/com/android/volley/db/annotation/Check.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | /** 24 | * Author: wyouflf 25 | * Date: 13-8-20 26 | * Time: 上午9:44 27 | */ 28 | @Target(ElementType.FIELD) 29 | @Retention(RetentionPolicy.RUNTIME) 30 | public @interface Check { 31 | String value(); 32 | } 33 | -------------------------------------------------------------------------------- /src/com/android/volley/db/converter/SqlDateColumnConverter.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.converter; 2 | 3 | import android.database.Cursor; 4 | import android.text.TextUtils; 5 | 6 | import com.android.volley.db.sqlite.ColumnDbType; 7 | 8 | /** 9 | * Author: wyouflf 10 | * Date: 13-11-4 11 | * Time: 下午10:51 12 | */ 13 | public class SqlDateColumnConverter implements ColumnConverter { 14 | @Override 15 | public java.sql.Date getFieldValue(final Cursor cursor, int index) { 16 | return cursor.isNull(index) ? null : new java.sql.Date(cursor.getLong(index)); 17 | } 18 | 19 | @Override 20 | public java.sql.Date getFieldValue(String fieldStringValue) { 21 | if (TextUtils.isEmpty(fieldStringValue)) return null; 22 | return new java.sql.Date(Long.valueOf(fieldStringValue)); 23 | } 24 | 25 | @Override 26 | public Object fieldValue2ColumnValue(java.sql.Date fieldValue) { 27 | if (fieldValue == null) return null; 28 | return fieldValue.getTime(); 29 | } 30 | 31 | @Override 32 | public ColumnDbType getColumnDbType() { 33 | return ColumnDbType.INTEGER; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/com/android/volley/db/converter/BooleanColumnConverter.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.converter; 2 | 3 | import android.database.Cursor; 4 | import android.text.TextUtils; 5 | 6 | import com.android.volley.db.sqlite.ColumnDbType; 7 | 8 | /** 9 | * Author: wyouflf 10 | * Date: 13-11-4 11 | * Time: 下午10:51 12 | */ 13 | public class BooleanColumnConverter implements ColumnConverter { 14 | @Override 15 | public Boolean getFieldValue(final Cursor cursor, int index) { 16 | return cursor.isNull(index) ? null : cursor.getInt(index) == 1; 17 | } 18 | 19 | @Override 20 | public Boolean getFieldValue(String fieldStringValue) { 21 | if (TextUtils.isEmpty(fieldStringValue)) return null; 22 | return fieldStringValue.length() == 1 ? "1".equals(fieldStringValue) : Boolean.valueOf(fieldStringValue); 23 | } 24 | 25 | @Override 26 | public Object fieldValue2ColumnValue(Boolean fieldValue) { 27 | if (fieldValue == null) return null; 28 | return fieldValue ? 1 : 0; 29 | } 30 | 31 | @Override 32 | public ColumnDbType getColumnDbType() { 33 | return ColumnDbType.INTEGER; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/com/android/volley/ServerError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | import com.android.volley.NetworkResponse; 20 | import com.android.volley.VolleyError; 21 | 22 | /** 23 | * Indicates that the error responded with an error response. 24 | */ 25 | @SuppressWarnings("serial") 26 | public class ServerError extends VolleyError { 27 | public ServerError(NetworkResponse networkResponse) { 28 | super(networkResponse); 29 | } 30 | 31 | public ServerError() { 32 | super(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/com/android/volley/Network.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | /** 20 | * An interface for performing requests. 21 | */ 22 | public interface Network { 23 | /** 24 | * Performs the specified request. 25 | * @param request Request to process 26 | * @return A {@link NetworkResponse} with data and caching metadata; will never be null 27 | * @throws VolleyError on errors 28 | */ 29 | public NetworkResponse performRequest(ResponseDelivery delivery, Request request) throws VolleyError; 30 | } 31 | -------------------------------------------------------------------------------- /src/com/android/volley/ParseError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | import com.android.volley.NetworkResponse; 20 | import com.android.volley.VolleyError; 21 | 22 | /** 23 | * Indicates that the server's response could not be parsed. 24 | */ 25 | @SuppressWarnings("serial") 26 | public class ParseError extends VolleyError { 27 | public ParseError() { } 28 | 29 | public ParseError(NetworkResponse networkResponse) { 30 | super(networkResponse); 31 | } 32 | 33 | public ParseError(Throwable cause) { 34 | super(cause); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/com/android/volley/db/DbException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db; 17 | 18 | import com.android.volley.VolleyError; 19 | 20 | public class DbException extends VolleyError { 21 | private static final long serialVersionUID = 1L; 22 | 23 | public DbException() { 24 | } 25 | 26 | public DbException(String detailMessage) { 27 | super(detailMessage); 28 | } 29 | 30 | public DbException(String detailMessage, Throwable throwable) { 31 | super(detailMessage, throwable); 32 | } 33 | 34 | public DbException(Throwable throwable) { 35 | super(throwable); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/Authenticator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox; 18 | 19 | import com.android.volley.AuthFailureError; 20 | 21 | /** 22 | * An interface for interacting with auth tokens. 23 | */ 24 | public interface Authenticator { 25 | /** 26 | * Synchronously retrieves an auth token. 27 | * 28 | * @throws AuthFailureError If authentication did not succeed 29 | */ 30 | public String getAuthToken() throws AuthFailureError; 31 | 32 | /** 33 | * Invalidates the provided auth token. 34 | */ 35 | public void invalidateAuthToken(String authToken); 36 | } 37 | -------------------------------------------------------------------------------- /src/com/android/volley/NetworkError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | import com.android.volley.NetworkResponse; 20 | import com.android.volley.VolleyError; 21 | 22 | /** 23 | * Indicates that there was a network error when performing a Volley request. 24 | */ 25 | @SuppressWarnings("serial") 26 | public class NetworkError extends VolleyError { 27 | public NetworkError() { 28 | super(); 29 | } 30 | 31 | public NetworkError(Throwable cause) { 32 | super(cause); 33 | } 34 | 35 | public NetworkError(NetworkResponse networkResponse) { 36 | super(networkResponse); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/NoCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox; 18 | 19 | import com.android.volley.Cache; 20 | 21 | /** 22 | * A cache that doesn't. 23 | */ 24 | public class NoCache implements Cache { 25 | @Override 26 | public void clear() { 27 | } 28 | 29 | @Override 30 | public Entry get(String key) { 31 | return null; 32 | } 33 | 34 | @Override 35 | public void put(String key, Entry entry) { 36 | } 37 | 38 | @Override 39 | public void invalidate(String key, boolean fullExpire) { 40 | } 41 | 42 | @Override 43 | public void remove(String key) { 44 | } 45 | 46 | @Override 47 | public void initialize() { 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/com/android/volley/ResponseDelivery.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | public interface ResponseDelivery { 20 | /** 21 | * Parses a response from the network or cache and delivers it. 22 | */ 23 | public void postResponse(Request request, Response response); 24 | 25 | /** 26 | * Parses a response from the network or cache and delivers it. The provided 27 | * Runnable will be executed after delivery. 28 | */ 29 | public void postResponse(Request request, Response response, Runnable runnable); 30 | 31 | /** 32 | * Posts an error for the given request. 33 | */ 34 | public void postError(Request request, VolleyError error); 35 | 36 | public void postLoading(Request request, long count, long current); 37 | } 38 | -------------------------------------------------------------------------------- /src/com/android/volley/RetryPolicy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | /** 20 | * Retry policy for a request. 21 | */ 22 | public interface RetryPolicy { 23 | 24 | /** 25 | * Returns the current timeout (used for logging). 26 | */ 27 | public int getCurrentTimeout(); 28 | 29 | /** 30 | * Returns the current retry count (used for logging). 31 | */ 32 | public int getCurrentRetryCount(); 33 | 34 | /** 35 | * Prepares for the next retry by applying a backoff to the timeout. 36 | * @param error The error code of the last attempt. 37 | * @throws VolleyError In the event that the retry could not be performed (for example if we 38 | * ran out of attempts), the passed in error is thrown. 39 | */ 40 | public void retry(VolleyError error) throws VolleyError; 41 | } 42 | -------------------------------------------------------------------------------- /src/com/android/volley/VolleyError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | /** 20 | * Exception style class encapsulating Volley errors 21 | */ 22 | @SuppressWarnings("serial") 23 | public class VolleyError extends Exception { 24 | public final NetworkResponse networkResponse; 25 | 26 | public VolleyError() { 27 | networkResponse = null; 28 | } 29 | 30 | public VolleyError(NetworkResponse response) { 31 | networkResponse = response; 32 | } 33 | 34 | public VolleyError(String exceptionMessage) { 35 | super(exceptionMessage); 36 | networkResponse = null; 37 | } 38 | 39 | public VolleyError(String exceptionMessage, Throwable reason) { 40 | super(exceptionMessage, reason); 41 | networkResponse = null; 42 | } 43 | 44 | public VolleyError(Throwable cause) { 45 | super(cause); 46 | networkResponse = null; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/com/android/volley/db/sqlite/FinderLazyLoader.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.sqlite; 2 | 3 | import java.util.List; 4 | 5 | import com.android.volley.db.DbException; 6 | import com.android.volley.db.table.ColumnUtils; 7 | import com.android.volley.db.table.Finder; 8 | import com.android.volley.db.table.Table; 9 | 10 | /** 11 | * Author: wyouflf 12 | * Date: 13-9-10 13 | * Time: 下午10:50 14 | */ 15 | public class FinderLazyLoader { 16 | private final Finder finderColumn; 17 | private final Object finderValue; 18 | 19 | public FinderLazyLoader(Finder finderColumn, Object value) { 20 | this.finderColumn = finderColumn; 21 | this.finderValue = ColumnUtils.convert2DbColumnValueIfNeeded(value); 22 | } 23 | 24 | public List getAllFromDb() throws DbException { 25 | List entities = null; 26 | Table table = finderColumn.getTable(); 27 | if (table != null) { 28 | entities = table.db.findAll( 29 | Selector.from(finderColumn.getTargetEntityType()). 30 | where(finderColumn.getTargetColumnName(), "=", finderValue) 31 | ); 32 | } 33 | return entities; 34 | } 35 | 36 | public T getFirstFromDb() throws DbException { 37 | T entity = null; 38 | Table table = finderColumn.getTable(); 39 | if (table != null) { 40 | entity = table.db.findFirst( 41 | Selector.from(finderColumn.getTargetEntityType()). 42 | where(finderColumn.getTargetColumnName(), "=", finderValue) 43 | ); 44 | } 45 | return entity; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/HttpStack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox; 18 | 19 | import com.android.volley.AuthFailureError; 20 | import com.android.volley.Request; 21 | 22 | import org.apache.http.HttpResponse; 23 | 24 | import java.io.IOException; 25 | import java.util.Map; 26 | 27 | /** 28 | * An HTTP stack abstraction. 29 | */ 30 | public interface HttpStack { 31 | 32 | String HEADER_CONTENT_TYPE = "Content-Type"; 33 | String HEADER_ACCEPT_ENCODING = "Accept-Encoding"; 34 | String USER_AGENT = "User-Agent"; 35 | String ENCODING_GZIP = "gzip"; 36 | int CONNECTION_TIME_OUT_MS = 15000; 37 | 38 | /** 39 | * Performs an HTTP request with the given parameters. 40 | * 41 | *

A GET request is sent if request.getPostBody() == null. A POST request is sent otherwise, 42 | * and the Content-Type header is set to request.getPostBodyContentType().

43 | * 44 | * @param request the request to perform 45 | * @param additionalHeaders additional headers to be sent together with 46 | * {@link Request#getHeaders()} 47 | * @return the HTTP response 48 | */ 49 | public HttpResponse performRequest(Request request, Map additionalHeaders) 50 | throws IOException, AuthFailureError; 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/com/android/volley/AuthFailureError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | import android.content.Intent; 20 | 21 | import com.android.volley.NetworkResponse; 22 | import com.android.volley.VolleyError; 23 | 24 | /** 25 | * Error indicating that there was an authentication failure when performing a Request. 26 | */ 27 | @SuppressWarnings("serial") 28 | public class AuthFailureError extends VolleyError { 29 | /** An intent that can be used to resolve this exception. (Brings up the password dialog.) */ 30 | private Intent mResolutionIntent; 31 | 32 | public AuthFailureError() { } 33 | 34 | public AuthFailureError(Intent intent) { 35 | mResolutionIntent = intent; 36 | } 37 | 38 | public AuthFailureError(NetworkResponse response) { 39 | super(response); 40 | } 41 | 42 | public AuthFailureError(String message) { 43 | super(message); 44 | } 45 | 46 | public AuthFailureError(String message, Exception reason) { 47 | super(message, reason); 48 | } 49 | 50 | public Intent getResolutionIntent() { 51 | return mResolutionIntent; 52 | } 53 | 54 | @Override 55 | public String getMessage() { 56 | if (mResolutionIntent != null) { 57 | return "User needs to (re)enter credentials."; 58 | } 59 | return super.getMessage(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/multipart/BasePart.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.toolbox.multipart; 2 | 3 | import org.apache.http.util.ByteArrayBuffer; 4 | import org.apache.http.util.EncodingUtils; 5 | 6 | /** 7 | * Parent class for FilePart and StringPart. 8 | * 9 | * @author Vitaliy Khudenko 10 | */ 11 | /* package */ abstract class BasePart implements Part { 12 | 13 | protected static final byte[] CRLF = EncodingUtils.getAsciiBytes(MultipartEntity.CRLF); 14 | 15 | protected interface IHeadersProvider { 16 | public String getContentDisposition(); 17 | public String getContentType(); 18 | public String getContentTransferEncoding(); 19 | } 20 | 21 | protected IHeadersProvider headersProvider; // must be initialized in descendant constructor 22 | 23 | private byte[] header; 24 | 25 | protected byte[] getHeader(Boundary boundary) { 26 | if (header == null) { 27 | header = generateHeader(boundary); // lazy init 28 | } 29 | return header; 30 | } 31 | 32 | private byte[] generateHeader(Boundary boundary) { 33 | if (headersProvider == null) { 34 | throw new RuntimeException("Uninitialized headersProvider"); //$NON-NLS-1$ 35 | } 36 | final ByteArrayBuffer buf = new ByteArrayBuffer(256); 37 | append(buf, boundary.getStartingBoundary()); 38 | append(buf, headersProvider.getContentDisposition()); 39 | append(buf, CRLF); 40 | append(buf, headersProvider.getContentType()); 41 | append(buf, CRLF); 42 | append(buf, headersProvider.getContentTransferEncoding()); 43 | append(buf, CRLF); 44 | append(buf, CRLF); 45 | return buf.toByteArray(); 46 | } 47 | 48 | private static void append(ByteArrayBuffer buf, String data) { 49 | append(buf, EncodingUtils.getAsciiBytes(data)); 50 | } 51 | 52 | private static void append(ByteArrayBuffer buf, byte[] data) { 53 | buf.append(data, 0, data.length); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/com/android/volley/ext/PauseOnScrollListener.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.ext; 2 | 3 | import android.widget.AbsListView; 4 | import android.widget.AbsListView.OnScrollListener; 5 | 6 | import com.android.volley.ext.tools.BitmapTools; 7 | 8 | public class PauseOnScrollListener implements OnScrollListener { 9 | 10 | private BitmapTools bitmapTools; 11 | 12 | private final boolean pauseOnScroll; 13 | private final boolean pauseOnFling; 14 | private final OnScrollListener externalListener; 15 | 16 | public PauseOnScrollListener(BitmapTools imageLoader, boolean pauseOnScroll, boolean pauseOnFling) { 17 | this(imageLoader, pauseOnScroll, pauseOnFling, null); 18 | } 19 | 20 | public PauseOnScrollListener(BitmapTools bitmapTools, boolean pauseOnScroll, boolean pauseOnFling, 21 | OnScrollListener customListener) { 22 | this.bitmapTools = bitmapTools; 23 | this.pauseOnScroll = pauseOnScroll; 24 | this.pauseOnFling = pauseOnFling; 25 | externalListener = customListener; 26 | } 27 | 28 | @Override 29 | public void onScrollStateChanged(AbsListView view, int scrollState) { 30 | switch (scrollState) { 31 | case OnScrollListener.SCROLL_STATE_IDLE: 32 | bitmapTools.resume(); 33 | break; 34 | case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: 35 | if (pauseOnScroll) { 36 | bitmapTools.pause(); 37 | } 38 | break; 39 | case OnScrollListener.SCROLL_STATE_FLING: 40 | if (pauseOnFling) { 41 | bitmapTools.pause(); 42 | } 43 | break; 44 | } 45 | if (externalListener != null) { 46 | externalListener.onScrollStateChanged(view, scrollState); 47 | } 48 | } 49 | 50 | @Override 51 | public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 52 | if (externalListener != null) { 53 | externalListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/DownloadRequest.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.toolbox; 2 | 3 | import java.io.File; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import com.android.volley.AuthFailureError; 8 | import com.android.volley.DefaultRetryPolicy; 9 | import com.android.volley.Response.ErrorListener; 10 | import com.android.volley.Response.Listener; 11 | import com.android.volley.Response.LoadingListener; 12 | 13 | public class DownloadRequest extends StringRequest { 14 | 15 | public DownloadRequest(String url, Listener listener, ErrorListener errorListener, 16 | LoadingListener loadingListener) { 17 | super(Method.GET, url, listener, errorListener, loadingListener); 18 | // 下载文件大,失败可能性比较大,所以加大retry次数 19 | setRetryPolicy( 20 | new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS, 5, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 21 | // 关闭gzip 22 | setShouldGzip(false); 23 | } 24 | 25 | private String target; 26 | private boolean isResume; 27 | 28 | public String getTarget() { 29 | return target; 30 | } 31 | 32 | public void setTarget(String target) { 33 | this.target = target; 34 | } 35 | 36 | public boolean isResume() { 37 | return isResume; 38 | } 39 | 40 | public void setResume(boolean isResume) { 41 | this.isResume = isResume; 42 | } 43 | 44 | @Override 45 | public Map getHeaders() throws AuthFailureError { 46 | File file = new File(target); 47 | final long fileLen = file.length(); 48 | if (isResume && fileLen > 0) { 49 | Map headers = new HashMap(); 50 | headers.put("Range", "bytes="+fileLen+"-"); 51 | return headers; 52 | } 53 | return super.getHeaders(); 54 | } 55 | 56 | 57 | /** 58 | * 停止下载 59 | * stopDownload 60 | * @since 3.5 61 | */ 62 | public void stopDownload() { 63 | cancel(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/multipart/Boundary.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.toolbox.multipart; 2 | 3 | import java.util.Random; 4 | 5 | import org.apache.http.util.EncodingUtils; 6 | 7 | import android.text.TextUtils; 8 | 9 | /** 10 | * @author Vitaliy Khudenko 11 | */ 12 | /* package */ class Boundary { 13 | 14 | /* The pool of ASCII chars to be used for generating a multipart boundary. */ 15 | private final static char[] MULTIPART_CHARS = 16 | "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); //$NON-NLS-1$ 17 | 18 | private final String boundary; 19 | private final byte[] startingBoundary; 20 | private final byte[] closingBoundary; 21 | 22 | /* package */ Boundary(String boundary) { 23 | if (TextUtils.isEmpty(boundary)) { 24 | boundary = generateBoundary(); 25 | } 26 | this.boundary = boundary; 27 | 28 | final String starting = "--" + boundary + MultipartEntity.CRLF; //$NON-NLS-1$ 29 | final String closing = "--" + boundary + "--" + MultipartEntity.CRLF; //$NON-NLS-1$ 30 | 31 | startingBoundary = EncodingUtils.getAsciiBytes(starting); 32 | closingBoundary = EncodingUtils.getAsciiBytes(closing); 33 | } 34 | 35 | /* package */ String getBoundary() { 36 | return boundary; 37 | } 38 | 39 | /* package */ byte[] getStartingBoundary() { 40 | return startingBoundary; 41 | } 42 | 43 | /* package */ byte[] getClosingBoundary() { 44 | return closingBoundary; 45 | } 46 | 47 | private static String generateBoundary() { 48 | // Boundary delimiters must not appear within the encapsulated material, 49 | // and must be no longer than 70 characters, not counting the two 50 | // leading hyphens. 51 | Random rand = new Random(); 52 | final int count = rand.nextInt(11) + 30; // a random size from 30 to 40 53 | StringBuilder buffer = new StringBuilder(count); 54 | for (int i = 0; i < count; i++) { 55 | buffer.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]); 56 | } 57 | return buffer.toString(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/com/android/volley/NetworkResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | import java.util.Collections; 20 | import java.util.Map; 21 | 22 | import org.apache.http.HttpStatus; 23 | 24 | /** 25 | * Data and headers returned from {@link Network#performRequest(ResponseDelivery, Request)}. 26 | */ 27 | public class NetworkResponse { 28 | /** 29 | * Creates a new network response. 30 | * @param statusCode the HTTP status code 31 | * @param data Response body 32 | * @param headers Headers returned with this response, or null for none 33 | * @param notModified True if the server returned a 304 and the data was already in cache 34 | */ 35 | public NetworkResponse(int statusCode, byte[] data, Map headers, 36 | boolean notModified) { 37 | this.statusCode = statusCode; 38 | this.data = data; 39 | this.headers = headers; 40 | this.notModified = notModified; 41 | } 42 | 43 | public NetworkResponse(byte[] data) { 44 | this(HttpStatus.SC_OK, data, Collections.emptyMap(), false); 45 | } 46 | 47 | public NetworkResponse(byte[] data, Map headers) { 48 | this(HttpStatus.SC_OK, data, headers, false); 49 | } 50 | 51 | /** The HTTP status code. */ 52 | public final int statusCode; 53 | 54 | /** Raw data from this response. */ 55 | public final byte[] data; 56 | 57 | /** Response headers. */ 58 | public final Map headers; 59 | 60 | /** True if the server returned a 304 (Not Modified). */ 61 | public final boolean notModified; 62 | } -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/UploadMultipartEntity.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.toolbox; 2 | 3 | import java.io.FilterOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | 7 | import com.android.volley.toolbox.multipart.MultipartEntity; 8 | 9 | /** 10 | * 带进度监听的上传Entity 11 | * UploadMultipartEntity 12 | * chenbo 13 | * @version 3.6 14 | */ 15 | public class UploadMultipartEntity extends MultipartEntity { 16 | 17 | private ProgressListener listener; 18 | private long offset; 19 | 20 | public void setListener(ProgressListener listener) { 21 | this.listener = listener; 22 | } 23 | 24 | @Override 25 | public void writeTo(OutputStream outstream) throws IOException { 26 | if (listener == null) { 27 | super.writeTo(outstream); 28 | } else { 29 | super.writeTo(new CountingOutputStream(outstream, offset, this.listener)); 30 | } 31 | } 32 | 33 | static class CountingOutputStream extends FilterOutputStream { 34 | private final ProgressListener listener; 35 | private long transferred; 36 | private long offset; 37 | 38 | public CountingOutputStream(final OutputStream out, long offset, final ProgressListener listener) { 39 | super(out); 40 | this.listener = listener; 41 | this.transferred = 0; 42 | this.offset = offset; 43 | } 44 | 45 | public void write(byte[] b, int off, int len) throws IOException { 46 | out.write(b, off, len); 47 | this.transferred += len; 48 | this.listener.transferred(this.transferred + offset); 49 | } 50 | 51 | public void write(int b) throws IOException { 52 | out.write(b); 53 | this.transferred++; 54 | this.listener.transferred(this.transferred + offset); 55 | } 56 | 57 | @Override 58 | public void write(byte[] buffer) throws IOException { 59 | out.write(buffer); 60 | this.transferred += buffer.length; 61 | this.listener.transferred(this.transferred + offset); 62 | } 63 | 64 | } 65 | 66 | public static interface ProgressListener { 67 | void transferred(long num); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/JsonArrayRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox; 18 | 19 | import com.android.volley.NetworkResponse; 20 | import com.android.volley.ParseError; 21 | import com.android.volley.Response; 22 | import com.android.volley.Response.ErrorListener; 23 | import com.android.volley.Response.Listener; 24 | 25 | import org.json.JSONArray; 26 | import org.json.JSONException; 27 | 28 | import java.io.UnsupportedEncodingException; 29 | 30 | /** 31 | * A request for retrieving a {@link JSONArray} response body at a given URL. 32 | */ 33 | public class JsonArrayRequest extends JsonRequest { 34 | 35 | /** 36 | * Creates a new request. 37 | * @param url URL to fetch the JSON from 38 | * @param listener Listener to receive the JSON response 39 | * @param errorListener Error listener, or null to ignore errors. 40 | */ 41 | public JsonArrayRequest(String url, Listener listener, ErrorListener errorListener) { 42 | super(Method.GET, url, null, listener, errorListener); 43 | } 44 | 45 | @Override 46 | protected Response parseNetworkResponse(NetworkResponse response) { 47 | try { 48 | String jsonString = 49 | new String(response.data, HttpHeaderParser.parseCharset(response.headers)); 50 | return Response.success(new JSONArray(jsonString), 51 | HttpHeaderParser.parseCacheHeaders(response)); 52 | } catch (UnsupportedEncodingException e) { 53 | return Response.error(new ParseError(e)); 54 | } catch (JSONException je) { 55 | return Response.error(new ParseError(je)); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/ClearCacheRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox; 18 | 19 | import com.android.volley.Cache; 20 | import com.android.volley.NetworkResponse; 21 | import com.android.volley.Request; 22 | import com.android.volley.Response; 23 | 24 | import android.os.Handler; 25 | import android.os.Looper; 26 | 27 | /** 28 | * A synthetic request used for clearing the cache. 29 | */ 30 | public class ClearCacheRequest extends Request { 31 | private final Cache mCache; 32 | private final Runnable mCallback; 33 | 34 | /** 35 | * Creates a synthetic request for clearing the cache. 36 | * @param cache Cache to clear 37 | * @param callback Callback to make on the main thread once the cache is clear, 38 | * or null for none 39 | */ 40 | public ClearCacheRequest(Cache cache, Runnable callback) { 41 | super(Method.GET, null, null); 42 | mCache = cache; 43 | mCallback = callback; 44 | } 45 | 46 | @Override 47 | public boolean isCanceled() { 48 | // This is a little bit of a hack, but hey, why not. 49 | mCache.clear(); 50 | if (mCallback != null) { 51 | Handler handler = new Handler(Looper.getMainLooper()); 52 | handler.postAtFrontOfQueue(mCallback); 53 | } 54 | return true; 55 | } 56 | 57 | @Override 58 | public Priority getPriority() { 59 | return Priority.IMMEDIATE; 60 | } 61 | 62 | @Override 63 | protected Response parseNetworkResponse(NetworkResponse response) { 64 | return null; 65 | } 66 | 67 | @Override 68 | protected void deliverResponse(Object response) { 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/com/android/volley/db/sqlite/ForeignLazyLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.sqlite; 17 | 18 | import java.util.List; 19 | 20 | import com.android.volley.db.DbException; 21 | import com.android.volley.db.table.ColumnUtils; 22 | import com.android.volley.db.table.Foreign; 23 | import com.android.volley.db.table.Table; 24 | 25 | public class ForeignLazyLoader { 26 | private final Foreign foreignColumn; 27 | private Object columnValue; 28 | 29 | public ForeignLazyLoader(Foreign foreignColumn, Object value) { 30 | this.foreignColumn = foreignColumn; 31 | this.columnValue = ColumnUtils.convert2DbColumnValueIfNeeded(value); 32 | } 33 | 34 | public List getAllFromDb() throws DbException { 35 | List entities = null; 36 | Table table = foreignColumn.getTable(); 37 | if (table != null) { 38 | entities = table.db.findAll( 39 | Selector.from(foreignColumn.getForeignEntityType()). 40 | where(foreignColumn.getForeignColumnName(), "=", columnValue) 41 | ); 42 | } 43 | return entities; 44 | } 45 | 46 | public T getFirstFromDb() throws DbException { 47 | T entity = null; 48 | Table table = foreignColumn.getTable(); 49 | if (table != null) { 50 | entity = table.db.findFirst( 51 | Selector.from(foreignColumn.getForeignEntityType()). 52 | where(foreignColumn.getForeignColumnName(), "=", columnValue) 53 | ); 54 | } 55 | return entity; 56 | } 57 | 58 | public void setColumnValue(Object value) { 59 | this.columnValue = ColumnUtils.convert2DbColumnValueIfNeeded(value); 60 | } 61 | 62 | public Object getColumnValue() { 63 | return columnValue; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/com/android/volley/ext/ContentLengthInputStream.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Sergey Tarasevich 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.android.volley.ext; 17 | 18 | import java.io.IOException; 19 | import java.io.InputStream; 20 | 21 | /** 22 | * Decorator for {@link java.io.InputStream InputStream}. Provides possibility to return defined stream length by 23 | * {@link #available()} method. 24 | * 25 | * @author Sergey Tarasevich (nostra13[at]gmail[dot]com), Mariotaku 26 | * @since 1.9.1 27 | */ 28 | public class ContentLengthInputStream extends InputStream { 29 | 30 | private final InputStream stream; 31 | private final int length; 32 | 33 | public ContentLengthInputStream(InputStream stream, int length) { 34 | this.stream = stream; 35 | this.length = length; 36 | } 37 | 38 | @Override 39 | public int available() { 40 | return length; 41 | } 42 | 43 | @Override 44 | public void close() throws IOException { 45 | stream.close(); 46 | } 47 | 48 | @Override 49 | public void mark(int readLimit) { 50 | stream.mark(readLimit); 51 | } 52 | 53 | @Override 54 | public int read() throws IOException { 55 | return stream.read(); 56 | } 57 | 58 | @Override 59 | public int read(byte[] buffer) throws IOException { 60 | return stream.read(buffer); 61 | } 62 | 63 | @Override 64 | public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException { 65 | return stream.read(buffer, byteOffset, byteCount); 66 | } 67 | 68 | @Override 69 | public void reset() throws IOException { 70 | stream.reset(); 71 | } 72 | 73 | @Override 74 | public long skip(long byteCount) throws IOException { 75 | return stream.skip(byteCount); 76 | } 77 | 78 | @Override 79 | public boolean markSupported() { 80 | return stream.markSupported(); 81 | } 82 | } -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/BitmapCache.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.toolbox; 2 | 3 | import android.annotation.TargetApi; 4 | import android.app.ActivityManager; 5 | import android.content.Context; 6 | import android.graphics.Bitmap; 7 | import android.os.Build; 8 | 9 | import com.android.volley.LruCache; 10 | import com.android.volley.Utils; 11 | import com.android.volley.toolbox.ImageLoader.ImageCache; 12 | 13 | public class BitmapCache implements ImageCache { 14 | private static BitmapCache sUniqueInstance = null; 15 | public LruCache mCache; 16 | 17 | public static synchronized BitmapCache getSigleton(Context context) { 18 | if (sUniqueInstance == null) { 19 | sUniqueInstance = new BitmapCache(context.getApplicationContext()); 20 | } 21 | return sUniqueInstance; 22 | } 23 | 24 | @TargetApi(Build.VERSION_CODES.KITKAT) 25 | private BitmapCache(Context context) { 26 | if (mCache == null) { 27 | int maxSize = getCacheSize(context); 28 | mCache = new LruCache(maxSize) { 29 | 30 | @Override 31 | protected int sizeOf(String key, Bitmap bitmap) { 32 | int size = 1; 33 | if (Utils.hasKitKat()) { // API 34 | size = bitmap.getAllocationByteCount(); 35 | } else if (Utils.hasHoneycombMR1()) {// API 36 | size = bitmap.getByteCount(); 37 | } else { 38 | size = bitmap.getRowBytes() * bitmap.getHeight(); 39 | } 40 | // LogUtils.d("bacy", key + "" + size); 41 | return size; 42 | } 43 | 44 | }; 45 | } 46 | 47 | } 48 | 49 | @Override 50 | public Bitmap getBitmap(String url) { 51 | return mCache.get(url); 52 | } 53 | 54 | @Override 55 | public void putBitmap(String url, Bitmap bitmap) { 56 | mCache.put(url, bitmap); 57 | } 58 | 59 | public final void evictAll() { 60 | mCache.evictAll(); 61 | } 62 | 63 | private int getCacheSize(Context context) { 64 | int memClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass(); 65 | // Use 1/8th of the available memory for this memory cache. 66 | // LogUtils.d("bacy", memClass + "" + 1024 * 1024 * memClass / 8); 67 | return (1024 * 1024 * memClass / 8); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/ContentLengthInputStream.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2013 Sergey Tarasevich 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.android.volley.toolbox; 17 | 18 | import java.io.IOException; 19 | import java.io.InputStream; 20 | 21 | /** 22 | * Decorator for {@link java.io.InputStream InputStream}. Provides possibility to return defined stream length by 23 | * {@link #available()} method. 24 | * 25 | * @author Sergey Tarasevich (nostra13[at]gmail[dot]com), Mariotaku 26 | * @since 1.9.1 27 | */ 28 | public class ContentLengthInputStream extends InputStream { 29 | 30 | private final InputStream stream; 31 | private final int length; 32 | 33 | public ContentLengthInputStream(InputStream stream, int length) { 34 | this.stream = stream; 35 | this.length = length; 36 | } 37 | 38 | @Override 39 | public int available() { 40 | return length; 41 | } 42 | 43 | @Override 44 | public void close() throws IOException { 45 | stream.close(); 46 | } 47 | 48 | @Override 49 | public void mark(int readLimit) { 50 | stream.mark(readLimit); 51 | } 52 | 53 | @Override 54 | public int read() throws IOException { 55 | return stream.read(); 56 | } 57 | 58 | @Override 59 | public int read(byte[] buffer) throws IOException { 60 | return stream.read(buffer); 61 | } 62 | 63 | @Override 64 | public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException { 65 | return stream.read(buffer, byteOffset, byteCount); 66 | } 67 | 68 | @Override 69 | public void reset() throws IOException { 70 | stream.reset(); 71 | } 72 | 73 | @Override 74 | public long skip(long byteCount) throws IOException { 75 | return stream.skip(byteCount); 76 | } 77 | 78 | @Override 79 | public boolean markSupported() { 80 | return stream.markSupported(); 81 | } 82 | } -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/multipart/MultipartEntity.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.toolbox.multipart; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import org.apache.http.entity.AbstractHttpEntity; 10 | 11 | /** 12 | * @author Vitaliy Khudenko 13 | */ 14 | public class MultipartEntity extends AbstractHttpEntity implements Cloneable { 15 | 16 | /* package */ static final String CRLF = "\r\n"; //$NON-NLS-1$ 17 | 18 | private List parts = new ArrayList(); 19 | 20 | private Boundary boundary; 21 | 22 | public MultipartEntity(String boundaryStr) { 23 | super(); 24 | boundary = new Boundary(boundaryStr); 25 | setContentType("multipart/form-data; boundary=\"" + boundary.getBoundary() + '"'); //$NON-NLS-1$ 26 | } 27 | 28 | public MultipartEntity() { 29 | this(null); 30 | } 31 | 32 | public void addPart(Part part) { 33 | parts.add(part); 34 | } 35 | 36 | public boolean isRepeatable() { 37 | return true; 38 | } 39 | 40 | public long getContentLength() { 41 | long result = 0; 42 | for (Part part : parts) { 43 | result += part.getContentLength(boundary); 44 | } 45 | result += boundary.getClosingBoundary().length; 46 | return result; 47 | } 48 | 49 | /** 50 | * Returns null since it's not designed to be used for server responses. 51 | */ 52 | public InputStream getContent() throws IOException { 53 | return null; 54 | } 55 | 56 | public void writeTo(final OutputStream out) throws IOException { 57 | if (out == null) { 58 | throw new IllegalArgumentException("Output stream may not be null"); //$NON-NLS-1$ 59 | } 60 | for (Part part : parts) { 61 | part.writeTo(out, boundary); 62 | } 63 | out.write(boundary.getClosingBoundary()); 64 | out.flush(); 65 | } 66 | 67 | /** 68 | * Tells that this entity is not streaming. 69 | * 70 | * @return false 71 | */ 72 | public boolean isStreaming() { 73 | return false; 74 | } 75 | 76 | public Object clone() throws CloneNotSupportedException { 77 | throw new CloneNotSupportedException("MultipartEntity does not support cloning"); //$NON-NLS-1$ // TODO 78 | } 79 | } -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/disklrucache/Util.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox.disklrucache; 18 | 19 | import java.io.Closeable; 20 | import java.io.File; 21 | import java.io.IOException; 22 | import java.io.Reader; 23 | import java.io.StringWriter; 24 | import java.nio.charset.Charset; 25 | 26 | /** Junk drawer of utility methods. */ 27 | final class Util { 28 | static final Charset US_ASCII = Charset.forName("US-ASCII"); 29 | static final Charset UTF_8 = Charset.forName("UTF-8"); 30 | 31 | private Util() { 32 | } 33 | 34 | static String readFully(Reader reader) throws IOException { 35 | try { 36 | StringWriter writer = new StringWriter(); 37 | char[] buffer = new char[1024]; 38 | int count; 39 | while ((count = reader.read(buffer)) != -1) { 40 | writer.write(buffer, 0, count); 41 | } 42 | return writer.toString(); 43 | } finally { 44 | reader.close(); 45 | } 46 | } 47 | 48 | /** 49 | * Deletes the contents of {@code dir}. Throws an IOException if any file 50 | * could not be deleted, or if {@code dir} is not a readable directory. 51 | */ 52 | static void deleteContents(File dir) throws IOException { 53 | File[] files = dir.listFiles(); 54 | if (files == null) { 55 | throw new IOException("not a readable directory: " + dir); 56 | } 57 | for (File file : files) { 58 | if (file.isDirectory()) { 59 | deleteContents(file); 60 | } 61 | if (!file.delete()) { 62 | throw new IOException("failed to delete file: " + file); 63 | } 64 | } 65 | } 66 | 67 | static void closeQuietly(/*Auto*/Closeable closeable) { 68 | if (closeable != null) { 69 | try { 70 | closeable.close(); 71 | } catch (RuntimeException rethrown) { 72 | throw rethrown; 73 | } catch (Exception ignored) { 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/com/android/volley/db/table/DbModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.table; 17 | 18 | import android.text.TextUtils; 19 | 20 | import java.util.Date; 21 | import java.util.HashMap; 22 | 23 | public class DbModel { 24 | 25 | /** 26 | * key: columnName 27 | * value: valueStr 28 | */ 29 | private HashMap dataMap = new HashMap(); 30 | 31 | public String getString(String columnName) { 32 | return dataMap.get(columnName); 33 | } 34 | 35 | public int getInt(String columnName) { 36 | return Integer.valueOf(dataMap.get(columnName)); 37 | } 38 | 39 | public boolean getBoolean(String columnName) { 40 | String value = dataMap.get(columnName); 41 | if (value != null) { 42 | return value.length() == 1 ? "1".equals(value) : Boolean.valueOf(value); 43 | } 44 | return false; 45 | } 46 | 47 | public double getDouble(String columnName) { 48 | return Double.valueOf(dataMap.get(columnName)); 49 | } 50 | 51 | public float getFloat(String columnName) { 52 | return Float.valueOf(dataMap.get(columnName)); 53 | } 54 | 55 | public long getLong(String columnName) { 56 | return Long.valueOf(dataMap.get(columnName)); 57 | } 58 | 59 | public Date getDate(String columnName) { 60 | long date = Long.valueOf(dataMap.get(columnName)); 61 | return new Date(date); 62 | } 63 | 64 | public java.sql.Date getSqlDate(String columnName) { 65 | long date = Long.valueOf(dataMap.get(columnName)); 66 | return new java.sql.Date(date); 67 | } 68 | 69 | public void add(String columnName, String valueStr) { 70 | dataMap.put(columnName, valueStr); 71 | } 72 | 73 | /** 74 | * @return key: columnName 75 | */ 76 | public HashMap getDataMap() { 77 | return dataMap; 78 | } 79 | 80 | /** 81 | * @param columnName 82 | * @return 83 | */ 84 | public boolean isEmpty(String columnName) { 85 | return TextUtils.isEmpty(dataMap.get(columnName)); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/com/android/volley/db/sqlite/SqlInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.sqlite; 17 | 18 | import java.util.LinkedList; 19 | 20 | import com.android.volley.db.table.ColumnUtils; 21 | 22 | public class SqlInfo { 23 | 24 | private String sql; 25 | private LinkedList bindArgs; 26 | 27 | public SqlInfo() { 28 | } 29 | 30 | public SqlInfo(String sql) { 31 | this.sql = sql; 32 | } 33 | 34 | public SqlInfo(String sql, Object... bindArgs) { 35 | this.sql = sql; 36 | addBindArgs(bindArgs); 37 | } 38 | 39 | public String getSql() { 40 | return sql; 41 | } 42 | 43 | public void setSql(String sql) { 44 | this.sql = sql; 45 | } 46 | 47 | public LinkedList getBindArgs() { 48 | return bindArgs; 49 | } 50 | 51 | public Object[] getBindArgsAsArray() { 52 | if (bindArgs != null) { 53 | return bindArgs.toArray(); 54 | } 55 | return null; 56 | } 57 | 58 | public String[] getBindArgsAsStrArray() { 59 | if (bindArgs != null) { 60 | String[] strings = new String[bindArgs.size()]; 61 | for (int i = 0; i < bindArgs.size(); i++) { 62 | Object value = bindArgs.get(i); 63 | strings[i] = value == null ? null : value.toString(); 64 | } 65 | return strings; 66 | } 67 | return null; 68 | } 69 | 70 | public void addBindArg(Object arg) { 71 | if (bindArgs == null) { 72 | bindArgs = new LinkedList(); 73 | } 74 | 75 | bindArgs.add(ColumnUtils.convert2DbColumnValueIfNeeded(arg)); 76 | } 77 | 78 | /* package */ void addBindArgWithoutConverter(Object arg) { 79 | if (bindArgs == null) { 80 | bindArgs = new LinkedList(); 81 | } 82 | 83 | bindArgs.add(arg); 84 | } 85 | 86 | public void addBindArgs(Object... bindArgs) { 87 | if (bindArgs != null) { 88 | for (Object arg : bindArgs) { 89 | addBindArg(arg); 90 | } 91 | } 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/com/android/volley/db/table/Finder.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.table; 2 | 3 | import java.lang.reflect.Field; 4 | import java.util.List; 5 | 6 | import android.database.Cursor; 7 | 8 | import com.android.volley.VolleyLog; 9 | import com.android.volley.db.DbException; 10 | import com.android.volley.db.sqlite.ColumnDbType; 11 | import com.android.volley.db.sqlite.FinderLazyLoader; 12 | 13 | /** 14 | * Author: wyouflf 15 | * Date: 13-9-10 16 | * Time: 下午7:43 17 | */ 18 | public class Finder extends Column { 19 | 20 | private final String valueColumnName; 21 | private final String targetColumnName; 22 | 23 | /* package */ Finder(Class entityType, Field field) { 24 | super(entityType, field); 25 | 26 | com.android.volley.db.annotation.Finder finder = 27 | field.getAnnotation(com.android.volley.db.annotation.Finder.class); 28 | this.valueColumnName = finder.valueColumn(); 29 | this.targetColumnName = finder.targetColumn(); 30 | } 31 | 32 | public Class getTargetEntityType() { 33 | return ColumnUtils.getFinderTargetEntityType(this); 34 | } 35 | 36 | public String getTargetColumnName() { 37 | return targetColumnName; 38 | } 39 | 40 | @Override 41 | public void setValue2Entity(Object entity, Cursor cursor, int index) { 42 | Object value = null; 43 | Class columnType = columnField.getType(); 44 | Object finderValue = TableUtils.getColumnOrId(entity.getClass(), this.valueColumnName).getColumnValue(entity); 45 | if (columnType.equals(FinderLazyLoader.class)) { 46 | value = new FinderLazyLoader(this, finderValue); 47 | } else if (columnType.equals(List.class)) { 48 | try { 49 | value = new FinderLazyLoader(this, finderValue).getAllFromDb(); 50 | } catch (DbException e) { 51 | VolleyLog.e(e.getMessage(), e); 52 | } 53 | } else { 54 | try { 55 | value = new FinderLazyLoader(this, finderValue).getFirstFromDb(); 56 | } catch (DbException e) { 57 | VolleyLog.e(e.getMessage(), e); 58 | } 59 | } 60 | 61 | if (setMethod != null) { 62 | try { 63 | setMethod.invoke(entity, value); 64 | } catch (Throwable e) { 65 | VolleyLog.e(e.getMessage(), e); 66 | } 67 | } else { 68 | try { 69 | this.columnField.setAccessible(true); 70 | this.columnField.set(entity, value); 71 | } catch (Throwable e) { 72 | VolleyLog.e(e.getMessage(), e); 73 | } 74 | } 75 | } 76 | 77 | @Override 78 | public Object getColumnValue(Object entity) { 79 | return null; 80 | } 81 | 82 | @Override 83 | public Object getDefaultValue() { 84 | return null; 85 | } 86 | 87 | @Override 88 | public ColumnDbType getColumnDbType() { 89 | return ColumnDbType.TEXT; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/com/android/volley/Response.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | /** 20 | * Encapsulates a parsed response for delivery. 21 | * 22 | * @param Parsed type of this response 23 | */ 24 | public class Response { 25 | 26 | /** Callback interface for delivering parsed responses. */ 27 | public interface Listener { 28 | /** Called when a response is received. */ 29 | public void onResponse(T response); 30 | } 31 | 32 | /** Callback interface for delivering error responses. */ 33 | public interface ErrorListener { 34 | /** 35 | * Callback method that an error has been occurred with the 36 | * provided error code and optional user-readable message. 37 | */ 38 | public void onErrorResponse(VolleyError error); 39 | } 40 | 41 | public interface LoadingListener { 42 | public void onLoading(long count,long current); 43 | } 44 | 45 | /** Returns a successful response containing the parsed result. */ 46 | public static Response success(T result, Cache.Entry cacheEntry) { 47 | return new Response(result, cacheEntry); 48 | } 49 | 50 | /** 51 | * Returns a failed response containing the given error code and an optional 52 | * localized message displayed to the user. 53 | */ 54 | public static Response error(VolleyError error) { 55 | return new Response(error); 56 | } 57 | 58 | /** Parsed response, or null in the case of error. */ 59 | public final T result; 60 | 61 | /** Cache metadata for this response, or null in the case of error. */ 62 | public final Cache.Entry cacheEntry; 63 | 64 | /** Detailed error information if errorCode != OK. */ 65 | public final VolleyError error; 66 | 67 | /** True if this response was a soft-expired one and a second one MAY be coming. */ 68 | public boolean intermediate = false; 69 | 70 | /** 71 | * Returns whether this response is considered successful. 72 | */ 73 | public boolean isSuccess() { 74 | return error == null; 75 | } 76 | 77 | 78 | private Response(T result, Cache.Entry cacheEntry) { 79 | this.result = result; 80 | this.cacheEntry = cacheEntry; 81 | this.error = null; 82 | } 83 | 84 | private Response(VolleyError error) { 85 | this.result = null; 86 | this.cacheEntry = null; 87 | this.error = error; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/multipart/FilePart.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.toolbox.multipart; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.OutputStream; 8 | 9 | import org.apache.http.protocol.HTTP; 10 | 11 | 12 | /** 13 | * @author Vitaliy Khudenko 14 | */ 15 | public final class FilePart extends BasePart { 16 | 17 | private final File file; 18 | 19 | /** 20 | * @param name String - name of parameter (may not be null). 21 | * @param file File (may not be null). 22 | * @param filename String. If null is passed, 23 | * then file.getName() is used. 24 | * @param contentType String. If null is passed, 25 | * then default "application/octet-stream" is used. 26 | * 27 | * @throws IllegalArgumentException if either file 28 | * or name is null. 29 | */ 30 | public FilePart(String name, File file, String filename, String contentType) { 31 | if (file == null) { 32 | throw new IllegalArgumentException("File may not be null"); //$NON-NLS-1$ 33 | } 34 | if (name == null) { 35 | throw new IllegalArgumentException("Name may not be null"); //$NON-NLS-1$ 36 | } 37 | 38 | this.file = file; 39 | final String partName = UrlEncodingHelper.encode(name, HTTP.DEFAULT_PROTOCOL_CHARSET); 40 | final String partFilename = UrlEncodingHelper.encode( 41 | (filename == null) ? file.getName() : filename, 42 | HTTP.DEFAULT_PROTOCOL_CHARSET 43 | ); 44 | final String partContentType = (contentType == null) ? HTTP.DEFAULT_CONTENT_TYPE : contentType; 45 | 46 | headersProvider = new IHeadersProvider() { 47 | public String getContentDisposition() { 48 | return "Content-Disposition: form-data; name=\"" + partName //$NON-NLS-1$ 49 | + "\"; filename=\"" + partFilename + '"'; //$NON-NLS-1$ 50 | } 51 | public String getContentType() { 52 | return "Content-Type: " + partContentType; //$NON-NLS-1$ 53 | } 54 | public String getContentTransferEncoding() { 55 | return "Content-Transfer-Encoding: binary"; //$NON-NLS-1$ 56 | } 57 | }; 58 | } 59 | 60 | public long getContentLength(Boundary boundary) { 61 | return getHeader(boundary).length + file.length() + CRLF.length; 62 | } 63 | 64 | public void writeTo(OutputStream out, Boundary boundary) throws IOException { 65 | out.write(getHeader(boundary)); 66 | InputStream in = new FileInputStream(file); 67 | try { 68 | byte[] tmp = new byte[4096]; 69 | int l; 70 | while ((l = in.read(tmp)) != -1) { 71 | out.write(tmp, 0, l); 72 | } 73 | } finally { 74 | in.close(); 75 | } 76 | out.write(CRLF); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/StringRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox; 18 | 19 | import com.android.volley.NetworkResponse; 20 | import com.android.volley.Request; 21 | import com.android.volley.Response; 22 | import com.android.volley.Response.ErrorListener; 23 | import com.android.volley.Response.Listener; 24 | import com.android.volley.Response.LoadingListener; 25 | 26 | import java.io.UnsupportedEncodingException; 27 | 28 | /** 29 | * A canned request for retrieving the response body at a given URL as a String. 30 | */ 31 | public class StringRequest extends Request { 32 | private final Listener mListener; 33 | 34 | /** 35 | * Creates a new request with the given method. 36 | * 37 | * @param method the request {@link Method} to use 38 | * @param url URL to fetch the string at 39 | * @param listener Listener to receive the String response 40 | * @param errorListener Error listener, or null to ignore errors 41 | */ 42 | public StringRequest(int method, String url, Listener listener, 43 | ErrorListener errorListener) { 44 | super(method, url, errorListener); 45 | mListener = listener; 46 | } 47 | 48 | public StringRequest(int method, String url, Listener listener, 49 | ErrorListener errorListener, LoadingListener loadingListener) { 50 | super(method, url, errorListener, loadingListener); 51 | mListener = listener; 52 | } 53 | 54 | /** 55 | * Creates a new GET request. 56 | * 57 | * @param url URL to fetch the string at 58 | * @param listener Listener to receive the String response 59 | * @param errorListener Error listener, or null to ignore errors 60 | */ 61 | public StringRequest(String url, Listener listener, ErrorListener errorListener) { 62 | this(Method.GET, url, listener, errorListener); 63 | } 64 | 65 | @Override 66 | protected void deliverResponse(String response) { 67 | mListener.onResponse(response); 68 | } 69 | 70 | @Override 71 | protected Response parseNetworkResponse(NetworkResponse response) { 72 | String parsed; 73 | try { 74 | parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); 75 | } catch (UnsupportedEncodingException e) { 76 | parsed = new String(response.data); 77 | } catch (NullPointerException e) { 78 | parsed = ""; 79 | } 80 | return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response)); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/com/android/volley/db/table/Id.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.table; 17 | 18 | import java.lang.reflect.Field; 19 | import java.util.HashSet; 20 | 21 | import com.android.volley.VolleyLog; 22 | import com.android.volley.db.annotation.NoAutoIncrement; 23 | 24 | public class Id extends Column { 25 | 26 | private String columnFieldClassName; 27 | private boolean isAutoIncrementChecked = false; 28 | private boolean isAutoIncrement = false; 29 | 30 | /* package */ Id(Class entityType, Field field) { 31 | super(entityType, field); 32 | columnFieldClassName = columnField.getType().getName(); 33 | } 34 | 35 | public boolean isAutoIncrement() { 36 | if (!isAutoIncrementChecked) { 37 | isAutoIncrementChecked = true; 38 | isAutoIncrement = columnField.getAnnotation(NoAutoIncrement.class) == null 39 | && AUTO_INCREMENT_TYPES.contains(columnFieldClassName); 40 | } 41 | return isAutoIncrement; 42 | } 43 | 44 | public void setAutoIncrementId(Object entity, long value) { 45 | Object idValue = value; 46 | if (INTEGER_TYPES.contains(columnFieldClassName)) { 47 | idValue = (int) value; 48 | } 49 | 50 | if (setMethod != null) { 51 | try { 52 | setMethod.invoke(entity, idValue); 53 | } catch (Throwable e) { 54 | VolleyLog.e(e.getMessage(), e); 55 | } 56 | } else { 57 | try { 58 | this.columnField.setAccessible(true); 59 | this.columnField.set(entity, idValue); 60 | } catch (Throwable e) { 61 | VolleyLog.e(e.getMessage(), e); 62 | } 63 | } 64 | } 65 | 66 | @Override 67 | public Object getColumnValue(Object entity) { 68 | Object idValue = super.getColumnValue(entity); 69 | if (idValue != null) { 70 | if (this.isAutoIncrement() && (idValue.equals(0) || idValue.equals(0L))) { 71 | return null; 72 | } else { 73 | return idValue; 74 | } 75 | } 76 | return null; 77 | } 78 | 79 | private static final HashSet INTEGER_TYPES = new HashSet(2); 80 | private static final HashSet AUTO_INCREMENT_TYPES = new HashSet(4); 81 | 82 | static { 83 | INTEGER_TYPES.add(int.class.getName()); 84 | INTEGER_TYPES.add(Integer.class.getName()); 85 | 86 | AUTO_INCREMENT_TYPES.addAll(INTEGER_TYPES); 87 | AUTO_INCREMENT_TYPES.add(long.class.getName()); 88 | AUTO_INCREMENT_TYPES.add(Long.class.getName()); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/multipart/StringPart.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.toolbox.multipart; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | import java.io.UnsupportedEncodingException; 6 | 7 | import org.apache.http.protocol.HTTP; 8 | 9 | /** 10 | * @author Vitaliy Khudenko 11 | */ 12 | public final class StringPart extends BasePart { 13 | 14 | private final byte[] valueBytes; 15 | 16 | /** 17 | * @param name String - name of parameter (may not be null). 18 | * @param value String - value of parameter (may not be null). 19 | * @param charset String, if null is passed then default "ISO-8859-1" charset is used. 20 | * 21 | * @throws IllegalArgumentException if either value 22 | * or name is null. 23 | * @throws RuntimeException if charset is unsupported by OS. 24 | */ 25 | public StringPart(String name, String value, String charset) { 26 | if (name == null) { 27 | throw new IllegalArgumentException("Name may not be null"); //$NON-NLS-1$ 28 | } 29 | if (value == null) { 30 | throw new IllegalArgumentException("Value may not be null"); //$NON-NLS-1$ 31 | } 32 | 33 | final String partName = UrlEncodingHelper.encode(name, HTTP.DEFAULT_PROTOCOL_CHARSET); 34 | 35 | if (charset == null) { 36 | charset = HTTP.DEFAULT_CONTENT_CHARSET; 37 | } 38 | final String partCharset = charset; 39 | 40 | try { 41 | this.valueBytes = value.getBytes(partCharset); 42 | } catch (UnsupportedEncodingException e) { 43 | throw new RuntimeException(e); 44 | } 45 | 46 | headersProvider = new IHeadersProvider() { 47 | public String getContentDisposition() { 48 | return "Content-Disposition: form-data; name=\"" + partName + '"'; //$NON-NLS-1$ 49 | } 50 | public String getContentType() { 51 | return "Content-Type: " + HTTP.PLAIN_TEXT_TYPE + HTTP.CHARSET_PARAM + partCharset; //$NON-NLS-1$ 52 | } 53 | public String getContentTransferEncoding() { 54 | return "Content-Transfer-Encoding: 8bit"; //$NON-NLS-1$ 55 | } 56 | }; 57 | } 58 | 59 | /** 60 | * Default "ISO-8859-1" charset is used. 61 | * @param name String - name of parameter (may not be null). 62 | * @param value String - value of parameter (may not be null). 63 | * 64 | * @throws IllegalArgumentException if either value 65 | * or name is null. 66 | */ 67 | public StringPart(String name, String value) { 68 | this(name, value, null); 69 | } 70 | 71 | public long getContentLength(Boundary boundary) { 72 | return getHeader(boundary).length + valueBytes.length + CRLF.length; 73 | } 74 | 75 | public void writeTo(final OutputStream out, Boundary boundary) throws IOException { 76 | out.write(getHeader(boundary)); 77 | out.write(valueBytes); 78 | out.write(CRLF); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/JsonObjectRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox; 18 | 19 | import com.android.volley.NetworkResponse; 20 | import com.android.volley.ParseError; 21 | import com.android.volley.Response; 22 | import com.android.volley.Response.ErrorListener; 23 | import com.android.volley.Response.Listener; 24 | 25 | import org.json.JSONException; 26 | import org.json.JSONObject; 27 | 28 | import java.io.UnsupportedEncodingException; 29 | 30 | /** 31 | * A request for retrieving a {@link JSONObject} response body at a given URL, allowing for an 32 | * optional {@link JSONObject} to be passed in as part of the request body. 33 | */ 34 | public class JsonObjectRequest extends JsonRequest { 35 | 36 | /** 37 | * Creates a new request. 38 | * @param method the HTTP method to use 39 | * @param url URL to fetch the JSON from 40 | * @param jsonRequest A {@link JSONObject} to post with the request. Null is allowed and 41 | * indicates no parameters will be posted along with request. 42 | * @param listener Listener to receive the JSON response 43 | * @param errorListener Error listener, or null to ignore errors. 44 | */ 45 | public JsonObjectRequest(int method, String url, JSONObject jsonRequest, 46 | Listener listener, ErrorListener errorListener) { 47 | super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener, 48 | errorListener); 49 | } 50 | 51 | /** 52 | * Constructor which defaults to GET if jsonRequest is 53 | * null, POST otherwise. 54 | * 55 | * @see #JsonObjectRequest(int, String, JSONObject, Listener, ErrorListener) 56 | */ 57 | public JsonObjectRequest(String url, JSONObject jsonRequest, Listener listener, 58 | ErrorListener errorListener) { 59 | this(jsonRequest == null ? Method.GET : Method.POST, url, jsonRequest, 60 | listener, errorListener); 61 | } 62 | 63 | @Override 64 | protected Response parseNetworkResponse(NetworkResponse response) { 65 | try { 66 | String jsonString = 67 | new String(response.data, HttpHeaderParser.parseCharset(response.headers)); 68 | return Response.success(new JSONObject(jsonString), 69 | HttpHeaderParser.parseCacheHeaders(response)); 70 | } catch (UnsupportedEncodingException e) { 71 | return Response.error(new ParseError(e)); 72 | } catch (JSONException je) { 73 | return Response.error(new ParseError(je)); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/com/android/volley/DefaultRetryPolicy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | /** 20 | * Default retry policy for requests. 21 | */ 22 | public class DefaultRetryPolicy implements RetryPolicy { 23 | /** The current timeout in milliseconds. */ 24 | private int mCurrentTimeoutMs; 25 | 26 | /** The current retry count. */ 27 | private int mCurrentRetryCount; 28 | 29 | /** The maximum number of attempts. */ 30 | private final int mMaxNumRetries; 31 | 32 | /** The backoff multiplier for for the policy. */ 33 | private final float mBackoffMultiplier; 34 | 35 | /** The default socket timeout in milliseconds */ 36 | public static final int DEFAULT_TIMEOUT_MS = 5000; 37 | 38 | /** The default number of retries */ 39 | public static final int DEFAULT_MAX_RETRIES = 2; 40 | 41 | /** The default backoff multiplier */ 42 | public static final float DEFAULT_BACKOFF_MULT = 1.2f; 43 | 44 | /** 45 | * Constructs a new retry policy using the default timeouts. 46 | */ 47 | public DefaultRetryPolicy() { 48 | this(DEFAULT_TIMEOUT_MS, DEFAULT_MAX_RETRIES, DEFAULT_BACKOFF_MULT); 49 | } 50 | 51 | /** 52 | * Constructs a new retry policy. 53 | * @param initialTimeoutMs The initial timeout for the policy. 54 | * @param maxNumRetries The maximum number of retries. 55 | * @param backoffMultiplier Backoff multiplier for the policy. 56 | */ 57 | public DefaultRetryPolicy(int initialTimeoutMs, int maxNumRetries, float backoffMultiplier) { 58 | mCurrentTimeoutMs = initialTimeoutMs; 59 | mMaxNumRetries = maxNumRetries; 60 | mBackoffMultiplier = backoffMultiplier; 61 | } 62 | 63 | /** 64 | * Returns the current timeout. 65 | */ 66 | @Override 67 | public int getCurrentTimeout() { 68 | return mCurrentTimeoutMs; 69 | } 70 | 71 | /** 72 | * Returns the current retry count. 73 | */ 74 | @Override 75 | public int getCurrentRetryCount() { 76 | return mCurrentRetryCount; 77 | } 78 | 79 | /** 80 | * Prepares for the next retry by applying a backoff to the timeout. 81 | * @param error The error code of the last attempt. 82 | */ 83 | @Override 84 | public void retry(VolleyError error) throws VolleyError { 85 | mCurrentRetryCount++; 86 | mCurrentTimeoutMs += (mCurrentTimeoutMs * mBackoffMultiplier); 87 | if (!hasAttemptRemaining()) { 88 | throw error; 89 | } 90 | } 91 | 92 | /** 93 | * Returns true if this policy has attempts remaining, false otherwise. 94 | */ 95 | protected boolean hasAttemptRemaining() { 96 | return mCurrentRetryCount <= mMaxNumRetries; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/PoolingByteArrayOutputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox; 18 | 19 | import java.io.ByteArrayOutputStream; 20 | import java.io.IOException; 21 | 22 | /** 23 | * A variation of {@link java.io.ByteArrayOutputStream} that uses a pool of byte[] buffers instead 24 | * of always allocating them fresh, saving on heap churn. 25 | */ 26 | public class PoolingByteArrayOutputStream extends ByteArrayOutputStream { 27 | /** 28 | * If the {@link #PoolingByteArrayOutputStream(ByteArrayPool)} constructor is called, this is 29 | * the default size to which the underlying byte array is initialized. 30 | */ 31 | private static final int DEFAULT_SIZE = 256; 32 | 33 | private final ByteArrayPool mPool; 34 | 35 | /** 36 | * Constructs a new PoolingByteArrayOutputStream with a default size. If more bytes are written 37 | * to this instance, the underlying byte array will expand. 38 | */ 39 | public PoolingByteArrayOutputStream(ByteArrayPool pool) { 40 | this(pool, DEFAULT_SIZE); 41 | } 42 | 43 | /** 44 | * Constructs a new {@code ByteArrayOutputStream} with a default size of {@code size} bytes. If 45 | * more than {@code size} bytes are written to this instance, the underlying byte array will 46 | * expand. 47 | * 48 | * @param size initial size for the underlying byte array. The value will be pinned to a default 49 | * minimum size. 50 | */ 51 | public PoolingByteArrayOutputStream(ByteArrayPool pool, int size) { 52 | mPool = pool; 53 | buf = mPool.getBuf(Math.max(size, DEFAULT_SIZE)); 54 | } 55 | 56 | @Override 57 | public void close() throws IOException { 58 | mPool.returnBuf(buf); 59 | buf = null; 60 | super.close(); 61 | } 62 | 63 | @Override 64 | public void finalize() { 65 | mPool.returnBuf(buf); 66 | } 67 | 68 | /** 69 | * Ensures there is enough space in the buffer for the given number of additional bytes. 70 | */ 71 | private void expand(int i) { 72 | /* Can the buffer handle @i more bytes, if not expand it */ 73 | if (count + i <= buf.length) { 74 | return; 75 | } 76 | byte[] newbuf = mPool.getBuf((count + i) * 2); 77 | System.arraycopy(buf, 0, newbuf, 0, count); 78 | mPool.returnBuf(buf); 79 | buf = newbuf; 80 | } 81 | 82 | @Override 83 | public synchronized void write(byte[] buffer, int offset, int len) { 84 | expand(len); 85 | super.write(buffer, offset, len); 86 | } 87 | 88 | @Override 89 | public synchronized void write(int oneByte) { 90 | expand(1); 91 | super.write(oneByte); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/com/android/volley/Cache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | import java.util.Collections; 20 | import java.util.Map; 21 | 22 | /** 23 | * An interface for a cache keyed by a String with a byte array as data. 24 | */ 25 | public interface Cache { 26 | /** 27 | * Retrieves an entry from the cache. 28 | * @param key Cache key 29 | * @return An {@link Entry} or null in the event of a cache miss 30 | */ 31 | public Entry get(String key); 32 | 33 | /** 34 | * Adds or replaces an entry to the cache. 35 | * @param key Cache key 36 | * @param entry Data to store and metadata for cache coherency, TTL, etc. 37 | */ 38 | public void put(String key, Entry entry); 39 | 40 | /** 41 | * Performs any potentially long-running actions needed to initialize the cache; 42 | * will be called from a worker thread. 43 | */ 44 | public void initialize(); 45 | 46 | /** 47 | * Invalidates an entry in the cache. 48 | * @param key Cache key 49 | * @param fullExpire True to fully expire the entry, false to soft expire 50 | */ 51 | public void invalidate(String key, boolean fullExpire); 52 | 53 | /** 54 | * Removes an entry from the cache. 55 | * @param key Cache key 56 | */ 57 | public void remove(String key); 58 | 59 | /** 60 | * Empties the cache. 61 | */ 62 | public void clear(); 63 | 64 | /** 65 | * Data and metadata for an entry returned by the cache. 66 | */ 67 | public static class Entry { 68 | /** The data returned from cache. */ 69 | public byte[] data; 70 | 71 | /** ETag for cache coherency. */ 72 | public String etag; 73 | 74 | /** Date of this response as reported by the server. */ 75 | public long serverDate; 76 | 77 | /** TTL for this record. */ 78 | public long ttl; 79 | 80 | /** Soft TTL for this record. */ 81 | public long softTtl; 82 | 83 | /** Immutable response headers as received from server; must be non-null. */ 84 | public Map responseHeaders = Collections.emptyMap(); 85 | 86 | /** True if the entry is expired. */ 87 | public boolean isExpired() { 88 | return this.ttl < System.currentTimeMillis(); 89 | } 90 | 91 | /** True if a refresh is needed from the original data source. */ 92 | public boolean refreshNeeded() { 93 | return this.softTtl < System.currentTimeMillis(); 94 | } 95 | 96 | @Override 97 | public String toString() { 98 | return "Entry [etag=" + etag + ", serverDate=" + serverDate + ", ttl=" + ttl + ", softTtl=" + softTtl + "]"; 99 | } 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/com/android/volley/ext/RequestInfo.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.ext; 2 | 3 | import java.io.File; 4 | import java.io.UnsupportedEncodingException; 5 | import java.net.URLEncoder; 6 | import java.util.HashMap; 7 | import java.util.Iterator; 8 | import java.util.Map; 9 | 10 | import com.android.volley.VolleyLog; 11 | 12 | public class RequestInfo { 13 | 14 | public final String boundary = String.valueOf(System.currentTimeMillis()); 15 | 16 | public String url ; 17 | public Map params = new HashMap() ; 18 | public Map headers = new HashMap(); 19 | public Map fileParams = new HashMap(); 20 | 21 | public RequestInfo() { 22 | } 23 | 24 | public RequestInfo(String url, Map params) { 25 | this.url = url; 26 | this.params = params; 27 | } 28 | 29 | 30 | public String getFullUrl() { 31 | if (url != null && params != null) { 32 | StringBuilder sb = new StringBuilder(); 33 | if (!url.contains("?")) { 34 | url = url + "?"; 35 | } else { 36 | if (!url.endsWith("?")) { 37 | url = url + "&"; 38 | } 39 | } 40 | Iterator iterotor = params.keySet().iterator(); 41 | try { 42 | while (iterotor.hasNext()) { 43 | String key = (String) iterotor.next(); 44 | if (key != null) { 45 | if (params.get(key) != null) { 46 | sb.append(URLEncoder.encode(key, "utf-8")).append("=") 47 | .append(URLEncoder.encode(params.get(key), "utf-8")).append("&"); 48 | } 49 | } 50 | } 51 | } catch (UnsupportedEncodingException e) { 52 | e.printStackTrace(); 53 | } 54 | if (sb.length() > 0 && sb.lastIndexOf("&") == sb.length() - 1) { 55 | sb.deleteCharAt(sb.length() - 1); 56 | } 57 | return url + sb.toString(); 58 | } 59 | return url; 60 | } 61 | 62 | public String getUrl() { 63 | return url; 64 | } 65 | 66 | public Map getParams() { 67 | return params; 68 | } 69 | 70 | public Map getFileParams() { 71 | return fileParams; 72 | } 73 | 74 | public Map getHeaders() { 75 | return headers; 76 | } 77 | 78 | 79 | public void put(String key, String value) { 80 | params.put(key, value); 81 | } 82 | 83 | public void put(String key, File file) { 84 | if (fileParams.containsKey(key)) { 85 | fileParams.put(key + boundary + fileParams.size(), file); 86 | } else { 87 | fileParams.put(key, file); 88 | } 89 | } 90 | 91 | public void putFile(String key, String path) { 92 | if (fileParams.containsKey(key)) { 93 | fileParams.put(key + boundary + fileParams.size(), new File(path)); 94 | } else { 95 | fileParams.put(key, new File(path)); 96 | } 97 | } 98 | 99 | public void putAllParams(Map objectParams) { 100 | for (String key : objectParams.keySet()) { 101 | Object value = objectParams.get(key); 102 | if (value instanceof String) { 103 | put(key, (String) value); 104 | } else if (value instanceof File) { 105 | put(key, (File) value); 106 | } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/com/android/volley/db/table/Table.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.table; 17 | 18 | import java.util.HashMap; 19 | import java.util.Map; 20 | 21 | import android.text.TextUtils; 22 | 23 | import com.android.volley.ext.tools.DbTools; 24 | 25 | 26 | public class Table { 27 | 28 | public final DbTools db; 29 | public final String tableName; 30 | public final Id id; 31 | 32 | /** 33 | * key: columnName 34 | */ 35 | public final HashMap columnMap; 36 | 37 | /** 38 | * key: columnName 39 | */ 40 | public final HashMap finderMap; 41 | 42 | /** 43 | * key: dbName#className 44 | */ 45 | private static final HashMap tableMap = new HashMap(); 46 | 47 | private Table(DbTools db, Class entityType) { 48 | this.db = db; 49 | this.tableName = TableUtils.getTableName(entityType); 50 | this.id = TableUtils.getId(entityType); 51 | this.columnMap = TableUtils.getColumnMap(entityType); 52 | 53 | finderMap = new HashMap(); 54 | for (Column column : columnMap.values()) { 55 | column.setTable(this); 56 | if (column instanceof Finder) { 57 | finderMap.put(column.getColumnName(), (Finder) column); 58 | } 59 | } 60 | } 61 | 62 | public static synchronized Table get(DbTools db, Class entityType) { 63 | String tableKey = db.getDaoConfig().getDbName() + "#" + entityType.getName(); 64 | Table table = tableMap.get(tableKey); 65 | if (table == null) { 66 | table = new Table(db, entityType); 67 | tableMap.put(tableKey, table); 68 | } 69 | 70 | return table; 71 | } 72 | 73 | public static synchronized void remove(DbTools db, Class entityType) { 74 | String tableKey = db.getDaoConfig().getDbName() + "#" + entityType.getName(); 75 | tableMap.remove(tableKey); 76 | } 77 | 78 | public static synchronized void remove(DbTools db, String tableName) { 79 | if (tableMap.size() > 0) { 80 | String key = null; 81 | for (Map.Entry entry : tableMap.entrySet()) { 82 | Table table = entry.getValue(); 83 | if (table != null && table.tableName.equals(tableName)) { 84 | key = entry.getKey(); 85 | if (key.startsWith(db.getDaoConfig().getDbName() + "#")) { 86 | break; 87 | } 88 | } 89 | } 90 | if (TextUtils.isEmpty(key)) { 91 | tableMap.remove(key); 92 | } 93 | } 94 | } 95 | 96 | private boolean checkedDatabase; 97 | 98 | public boolean isCheckedDatabase() { 99 | return checkedDatabase; 100 | } 101 | 102 | public void setCheckedDatabase(boolean checkedDatabase) { 103 | this.checkedDatabase = checkedDatabase; 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | volley 2 | ====== 3 | 需要的权限 4 | 5 | 6 | 7 | 8 | 9 | ### 1.支持http 大文件上传以及下载,支持断点下载,下载中允许暂停,下次从暂停地方开始下载 10 | #### 初始化 11 |

HttpTools.init(context);

12 | 建议在Application的OnCreate中执行一次(可选) 13 | #### 普通http请求 14 | 本来有八种谓词,考虑其他几种不常见,项目中用不上,暂时不提供。 15 | HttpTools提供get,post,upload,download,delete多种请求的封装,一行代码搞定各种异步请求 16 | 17 | get(RequestInfo requestInfo, final HttpCallback httpResult); 18 | post(RequestInfo requestInfo, final HttpCallback httpResult); 19 | delete(RequestInfo requestInfo, final HttpCallback httpResult); 20 | put(RequestInfo requestInfo, final HttpCallback httpResult); 21 | 22 | #### 文件下载 23 | 24 | DownloadRequest download(String url, String target, final boolean isResume, final HttpCallback httpResult) 25 | DownloadRequest download(RequestInfo requestInfo, String target, final boolean isResume, final HttpCallback httpResult) 26 | 27 | 设置参数isResume为true,即可实现断点续传,DownloadRequest提供stopDownload方法,可以随时停止当前的下载任务,再次下载将会从上次下载的地方开始下载。quitDownloadQueue允许强制关闭下载线程池,退出下载。可以在所有下载任务完成后关闭,节约资源。 28 | 29 | #### 文件上传 30 | 31 | MultiPartRequest upload(final String url, final Map params, final HttpCallback httpResult) 32 | MultiPartRequest upload(RequestInfo requestInfo, final HttpCallback httpResult) 33 | 34 | Params是一个表单参数,可以传入string和File类型的参数。(可以使用一个key对应多个file)例如: 35 | 36 | Map params = new HashMap(); 37 | params.put("file0", new File("/sdcard/a.jpg")); 38 | params.put("file1", new File("/sdcard/a.jpg")); 39 | params.put("file2", new File("/sdcard/a.jpg")); 40 | params.put("name", "张三"); 41 | mHttpTools.upload(url, params, httpResult); 42 | #### 直接使用Volley的Request 43 | public void sendRequest(Request request) 44 | 45 | ### 2.默认开启gzip压缩 46 | ImageRequest和DownloadRequest不启用Gzip,其他请求均默认开启Gzip 47 | ### 3.支持本地图片(res,asset,sdcard) 48 | Bitmap getBitmapFromRes(int resId); 49 | Bitmap getBitmapFromAsset(String filePath); 50 | Bitmap getBitmapFromContent(String imageUri); 51 | Bitmap getBitmapFromFile(String path); 52 | 这四个方法,用来加载本地资源,分别加载Resource,Assets,系统资源,sdcard文件中的图片,这四个方法都是同步的,如果想要异步获取,display也提供加载本地资源的功能。只需要分别加上协议头即可: 53 | public static final String SCHEME_RES = "drawable://"; 54 | public static final String SCHEME_ASSET = "assets://"; 55 | public static final String SCHEME_CONTENT = "content://"; 56 | (比如需要异步加载一张resource中的图片的话,可以这样定义 57 | bitmapTools.display(view,BitmapDecoder.SCHEME_RES+R.drawable.xxx); 58 | 加载sdcard中的文件不需要加协议头) 59 | #### 初始化 60 | 61 | BitmapTools.init(context); 62 | 63 | #### 结束(可以在app退出后调用) 64 | 65 | BitmapTools.stop(); 66 | 67 | 建议在Application的OnCreate中执行一次 68 | 69 | BitmapTools的display方法支持各种图片的异步加载 70 | BitmapTools的display方法支持各种图片的异步加载 71 | 72 | BitmapTools bitmapTools = new BitmapTools(mContext); 73 | bitmapTools.display(view, uri); 74 | 75 | 配置类BitmapDisplayConfig.java。可以配置的有: 76 | 默认加载图片, 77 | 加载失败图片, 78 | 图片尺寸, 79 | 加载的动画, 80 | 图片圆角属性。 81 | BitmapTools中提供多种方法配置BitmapDisplayConfig,配置过后,BitmapTools将采用该配置来加载显示图片,也可以在display方法中带上配置参数,这种方式不会影响整体配置,只为该次展示图片所使用。 82 | 83 | bitmapTools.display(final View view, String uri, BitmapDisplayConfig displayConfig); 84 | 85 | ### 4.diskcache默认使用DiskLruCache,memoryCache默认使用LruCache 86 | 87 | ### 5.request请求添加进度监听(包括上传进度以及加载进度) 88 | 89 | ### 6.允许暂停和继续请求队列 90 | 91 | bitmapTools.resume(); 92 | bitmapTools.pause(); 93 | ### 7.DbTools模块 94 | 数据库模块集成了xUtils中DbUtils。 95 | 使用方法参考xUtils。 96 | 注意: 97 | 注解类型不要混淆,需要映射的实体类不要混淆 98 | 添加混淆配置:-keep class * extends java.lang.annotation.Annotation { *; } 99 | 100 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/JsonRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox; 18 | 19 | import com.android.volley.NetworkResponse; 20 | import com.android.volley.Request; 21 | import com.android.volley.Response; 22 | import com.android.volley.Response.ErrorListener; 23 | import com.android.volley.Response.Listener; 24 | import com.android.volley.VolleyLog; 25 | 26 | import java.io.UnsupportedEncodingException; 27 | 28 | /** 29 | * A request for retrieving a T type response body at a given URL that also 30 | * optionally sends along a JSON body in the request specified. 31 | * 32 | * @param JSON type of response expected 33 | */ 34 | public abstract class JsonRequest extends Request { 35 | /** Charset for request. */ 36 | private static final String PROTOCOL_CHARSET = "utf-8"; 37 | 38 | /** Content type for request. */ 39 | private static final String PROTOCOL_CONTENT_TYPE = 40 | String.format("application/json; charset=%s", PROTOCOL_CHARSET); 41 | 42 | private final Listener mListener; 43 | private final String mRequestBody; 44 | 45 | /** 46 | * Deprecated constructor for a JsonRequest which defaults to GET unless {@link #getPostBody()} 47 | * or {@link #getPostParams()} is overridden (which defaults to POST). 48 | * 49 | * @deprecated Use {@link #JsonRequest(int, String, String, Listener, ErrorListener)}. 50 | */ 51 | public JsonRequest(String url, String requestBody, Listener listener, 52 | ErrorListener errorListener) { 53 | this(Method.DEPRECATED_GET_OR_POST, url, requestBody, listener, errorListener); 54 | } 55 | 56 | public JsonRequest(int method, String url, String requestBody, Listener listener, 57 | ErrorListener errorListener) { 58 | super(method, url, errorListener); 59 | mListener = listener; 60 | mRequestBody = requestBody; 61 | } 62 | 63 | @Override 64 | protected void deliverResponse(T response) { 65 | mListener.onResponse(response); 66 | } 67 | 68 | @Override 69 | abstract protected Response parseNetworkResponse(NetworkResponse response); 70 | 71 | /** 72 | * @deprecated Use {@link #getBodyContentType()}. 73 | */ 74 | @Override 75 | public String getPostBodyContentType() { 76 | return getBodyContentType(); 77 | } 78 | 79 | /** 80 | * @deprecated Use {@link #getBody()}. 81 | */ 82 | @Override 83 | public byte[] getPostBody() { 84 | return getBody(); 85 | } 86 | 87 | @Override 88 | public String getBodyContentType() { 89 | return PROTOCOL_CONTENT_TYPE; 90 | } 91 | 92 | @Override 93 | public byte[] getBody() { 94 | try { 95 | return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET); 96 | } catch (UnsupportedEncodingException uee) { 97 | VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", 98 | mRequestBody, PROTOCOL_CHARSET); 99 | return null; 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/MultiPartRequest.java: -------------------------------------------------------------------------------- 1 | 2 | package com.android.volley.toolbox; 3 | 4 | import java.io.File; 5 | 6 | import android.os.Handler; 7 | import android.os.Looper; 8 | import android.os.SystemClock; 9 | 10 | import com.android.volley.DefaultRetryPolicy; 11 | import com.android.volley.ExecutorDelivery; 12 | import com.android.volley.NetworkResponse; 13 | import com.android.volley.Request; 14 | import com.android.volley.Response; 15 | import com.android.volley.Response.ErrorListener; 16 | import com.android.volley.Response.Listener; 17 | import com.android.volley.Response.LoadingListener; 18 | import com.android.volley.toolbox.UploadMultipartEntity.ProgressListener; 19 | import com.android.volley.toolbox.multipart.FilePart; 20 | import com.android.volley.toolbox.multipart.StringPart; 21 | 22 | /** 23 | * A request for making a Multi Part request 24 | * 25 | * @param 26 | * Response expected 27 | */ 28 | public abstract class MultiPartRequest extends Request { 29 | 30 | private static final String PROTOCOL_CHARSET = "utf-8"; 31 | 32 | /** 33 | * Listener object for delivering the response 34 | */ 35 | private Listener mListener; 36 | 37 | private UploadMultipartEntity mMultipartEntity; 38 | /** 39 | * Default connection timeout for Multipart requests 40 | */ 41 | public static final int TIMEOUT_MS = 60000; 42 | 43 | public MultiPartRequest(int method, String url, Listener listener, ErrorListener errorlistener, LoadingListener loadingListener) { 44 | 45 | super(method, url, errorlistener); 46 | mListener = listener; 47 | 48 | mMultipartEntity = new UploadMultipartEntity(); 49 | 50 | final ExecutorDelivery delivery = new ExecutorDelivery(new Handler(Looper.getMainLooper())); 51 | setLoadingListener(loadingListener); 52 | if (loadingListener != null) { 53 | mMultipartEntity.setListener(new ProgressListener() { 54 | long time = SystemClock.uptimeMillis(); 55 | long count = -1; 56 | 57 | @Override 58 | public void transferred(long num) { 59 | if (count == -1) { 60 | count = mMultipartEntity.getContentLength(); 61 | } 62 | // LogUtils.d("bacy", "upload->" + count + ",num->" + num); 63 | long thisTime = SystemClock.uptimeMillis(); 64 | if (thisTime - time >= getRate() || count == num) { 65 | time = thisTime; 66 | delivery.postLoading(MultiPartRequest.this, count, num); 67 | } 68 | } 69 | }); 70 | } 71 | setRetryPolicy(new DefaultRetryPolicy(TIMEOUT_MS, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); 72 | } 73 | 74 | @Override 75 | public String getBodyContentType() { 76 | return mMultipartEntity.getContentType().getValue(); 77 | } 78 | 79 | @Override 80 | abstract protected Response parseNetworkResponse(NetworkResponse response); 81 | 82 | @Override 83 | protected void deliverResponse(T response) { 84 | 85 | mListener.onResponse(response); 86 | } 87 | 88 | /** 89 | * Get the protocol charset 90 | */ 91 | public String getProtocolCharset() { 92 | 93 | return PROTOCOL_CHARSET; 94 | } 95 | 96 | public void addPart(String key, String value) { 97 | StringPart part = new StringPart(key, value, PROTOCOL_CHARSET); 98 | mMultipartEntity.addPart(part); 99 | } 100 | 101 | public void addPart(String key, File file) { 102 | FilePart part = new FilePart(key, file, null, null); 103 | mMultipartEntity.addPart(part); 104 | } 105 | 106 | public UploadMultipartEntity getMultipartEntity() { 107 | return mMultipartEntity; 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/AndroidAuthenticator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox; 18 | 19 | import com.android.volley.AuthFailureError; 20 | 21 | import android.accounts.Account; 22 | import android.accounts.AccountManager; 23 | import android.accounts.AccountManagerFuture; 24 | import android.content.Context; 25 | import android.content.Intent; 26 | import android.os.Bundle; 27 | 28 | /** 29 | * An Authenticator that uses {@link AccountManager} to get auth 30 | * tokens of a specified type for a specified account. 31 | */ 32 | public class AndroidAuthenticator implements Authenticator { 33 | private final Context mContext; 34 | private final Account mAccount; 35 | private final String mAuthTokenType; 36 | private final boolean mNotifyAuthFailure; 37 | 38 | /** 39 | * Creates a new authenticator. 40 | * @param context Context for accessing AccountManager 41 | * @param account Account to authenticate as 42 | * @param authTokenType Auth token type passed to AccountManager 43 | */ 44 | public AndroidAuthenticator(Context context, Account account, String authTokenType) { 45 | this(context, account, authTokenType, false); 46 | } 47 | 48 | /** 49 | * Creates a new authenticator. 50 | * @param context Context for accessing AccountManager 51 | * @param account Account to authenticate as 52 | * @param authTokenType Auth token type passed to AccountManager 53 | * @param notifyAuthFailure Whether to raise a notification upon auth failure 54 | */ 55 | public AndroidAuthenticator(Context context, Account account, String authTokenType, 56 | boolean notifyAuthFailure) { 57 | mContext = context; 58 | mAccount = account; 59 | mAuthTokenType = authTokenType; 60 | mNotifyAuthFailure = notifyAuthFailure; 61 | } 62 | 63 | /** 64 | * Returns the Account being used by this authenticator. 65 | */ 66 | public Account getAccount() { 67 | return mAccount; 68 | } 69 | 70 | // TODO: Figure out what to do about notifyAuthFailure 71 | @SuppressWarnings("deprecation") 72 | @Override 73 | public String getAuthToken() throws AuthFailureError { 74 | final AccountManager accountManager = AccountManager.get(mContext); 75 | AccountManagerFuture future = accountManager.getAuthToken(mAccount, 76 | mAuthTokenType, mNotifyAuthFailure, null, null); 77 | Bundle result; 78 | try { 79 | result = future.getResult(); 80 | } catch (Exception e) { 81 | throw new AuthFailureError("Error while retrieving auth token", e); 82 | } 83 | String authToken = null; 84 | if (future.isDone() && !future.isCancelled()) { 85 | if (result.containsKey(AccountManager.KEY_INTENT)) { 86 | Intent intent = result.getParcelable(AccountManager.KEY_INTENT); 87 | throw new AuthFailureError(intent); 88 | } 89 | authToken = result.getString(AccountManager.KEY_AUTHTOKEN); 90 | } 91 | if (authToken == null) { 92 | throw new AuthFailureError("Got null auth token for type: " + mAuthTokenType); 93 | } 94 | 95 | return authToken; 96 | } 97 | 98 | @Override 99 | public void invalidateAuthToken(String authToken) { 100 | AccountManager.get(mContext).invalidateAuthToken(mAccount.type, authToken); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/com/android/volley/ExecutorDelivery.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | import android.os.Handler; 20 | 21 | import java.util.concurrent.Executor; 22 | 23 | /** 24 | * Delivers responses and errors. 25 | */ 26 | public class ExecutorDelivery implements ResponseDelivery { 27 | /** Used for posting responses, typically to the main thread. */ 28 | private final Executor mResponsePoster; 29 | 30 | /** 31 | * Creates a new response delivery interface. 32 | * @param handler {@link Handler} to post responses on 33 | */ 34 | public ExecutorDelivery(final Handler handler) { 35 | // Make an Executor that just wraps the handler. 36 | mResponsePoster = new Executor() { 37 | @Override 38 | public void execute(Runnable command) { 39 | handler.post(command); 40 | } 41 | }; 42 | } 43 | 44 | /** 45 | * Creates a new response delivery interface, mockable version 46 | * for testing. 47 | * @param executor For running delivery tasks 48 | */ 49 | public ExecutorDelivery(Executor executor) { 50 | mResponsePoster = executor; 51 | } 52 | 53 | @Override 54 | public void postResponse(Request request, Response response) { 55 | postResponse(request, response, null); 56 | } 57 | 58 | @Override 59 | public void postResponse(Request request, Response response, Runnable runnable) { 60 | request.markDelivered(); 61 | request.addMarker("post-response"); 62 | mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, runnable)); 63 | } 64 | 65 | @Override 66 | public void postError(Request request, VolleyError error) { 67 | request.addMarker("post-error"); 68 | Response response = Response.error(error); 69 | mResponsePoster.execute(new ResponseDeliveryRunnable(request, response, null)); 70 | } 71 | 72 | /** 73 | * A Runnable used for delivering network responses to a listener on the 74 | * main thread. 75 | */ 76 | @SuppressWarnings("rawtypes") 77 | private class ResponseDeliveryRunnable implements Runnable { 78 | private final Request mRequest; 79 | private final Response mResponse; 80 | private final Runnable mRunnable; 81 | 82 | public ResponseDeliveryRunnable(Request request, Response response, Runnable runnable) { 83 | mRequest = request; 84 | mResponse = response; 85 | mRunnable = runnable; 86 | } 87 | 88 | @SuppressWarnings("unchecked") 89 | @Override 90 | public void run() { 91 | // If this request has canceled, finish it and don't deliver. 92 | if (mRequest.isCanceled()) { 93 | mRequest.finish("canceled-at-delivery"); 94 | return; 95 | } 96 | 97 | // Deliver a normal response or error, depending. 98 | if (mResponse.isSuccess()) { 99 | mRequest.deliverResponse(mResponse.result); 100 | } else { 101 | mRequest.deliverError(mResponse.error); 102 | } 103 | 104 | // If this is an intermediate response, add a marker, otherwise we're done 105 | // and the request can be finished. 106 | if (mResponse.intermediate) { 107 | mRequest.addMarker("intermediate-response"); 108 | } else { 109 | mRequest.finish("done"); 110 | } 111 | 112 | // If we have been provided a post-delivery runnable, run it. 113 | if (mRunnable != null) { 114 | mRunnable.run(); 115 | } 116 | } 117 | } 118 | 119 | @Override 120 | public void postLoading(final Request request, final long count, final long current) { 121 | mResponsePoster.execute(new Runnable() { 122 | 123 | @Override 124 | public void run() { 125 | request.deliverLoading(count, current); 126 | } 127 | }); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/RequestFuture.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox; 18 | 19 | import com.android.volley.Request; 20 | import com.android.volley.Response; 21 | import com.android.volley.VolleyError; 22 | 23 | import java.util.concurrent.ExecutionException; 24 | import java.util.concurrent.Future; 25 | import java.util.concurrent.TimeUnit; 26 | import java.util.concurrent.TimeoutException; 27 | 28 | /** 29 | * A Future that represents a Volley request. 30 | * 31 | * Used by providing as your response and error listeners. For example: 32 | *
 33 |  * RequestFuture<JSONObject> future = RequestFuture.newFuture();
 34 |  * MyRequest request = new MyRequest(URL, future, future);
 35 |  *
 36 |  * // If you want to be able to cancel the request:
 37 |  * future.setRequest(requestQueue.add(request));
 38 |  *
 39 |  * // Otherwise:
 40 |  * requestQueue.add(request);
 41 |  *
 42 |  * try {
 43 |  *   JSONObject response = future.get();
 44 |  *   // do something with response
 45 |  * } catch (InterruptedException e) {
 46 |  *   // handle the error
 47 |  * } catch (ExecutionException e) {
 48 |  *   // handle the error
 49 |  * }
 50 |  * 
51 | * 52 | * @param The type of parsed response this future expects. 53 | */ 54 | public class RequestFuture implements Future, Response.Listener, 55 | Response.ErrorListener { 56 | private Request mRequest; 57 | private boolean mResultReceived = false; 58 | private T mResult; 59 | private VolleyError mException; 60 | 61 | public static RequestFuture newFuture() { 62 | return new RequestFuture(); 63 | } 64 | 65 | private RequestFuture() {} 66 | 67 | public void setRequest(Request request) { 68 | mRequest = request; 69 | } 70 | 71 | @Override 72 | public synchronized boolean cancel(boolean mayInterruptIfRunning) { 73 | if (mRequest == null) { 74 | return false; 75 | } 76 | 77 | if (!isDone()) { 78 | mRequest.cancel(); 79 | return true; 80 | } else { 81 | return false; 82 | } 83 | } 84 | 85 | @Override 86 | public T get() throws InterruptedException, ExecutionException { 87 | try { 88 | return doGet(null); 89 | } catch (TimeoutException e) { 90 | throw new AssertionError(e); 91 | } 92 | } 93 | 94 | @Override 95 | public T get(long timeout, TimeUnit unit) 96 | throws InterruptedException, ExecutionException, TimeoutException { 97 | return doGet(TimeUnit.MILLISECONDS.convert(timeout, unit)); 98 | } 99 | 100 | private synchronized T doGet(Long timeoutMs) 101 | throws InterruptedException, ExecutionException, TimeoutException { 102 | if (mException != null) { 103 | throw new ExecutionException(mException); 104 | } 105 | 106 | if (mResultReceived) { 107 | return mResult; 108 | } 109 | 110 | if (timeoutMs == null) { 111 | wait(0); 112 | } else if (timeoutMs > 0) { 113 | wait(timeoutMs); 114 | } 115 | 116 | if (mException != null) { 117 | throw new ExecutionException(mException); 118 | } 119 | 120 | if (!mResultReceived) { 121 | throw new TimeoutException(); 122 | } 123 | 124 | return mResult; 125 | } 126 | 127 | @Override 128 | public boolean isCancelled() { 129 | if (mRequest == null) { 130 | return false; 131 | } 132 | return mRequest.isCanceled(); 133 | } 134 | 135 | @Override 136 | public synchronized boolean isDone() { 137 | return mResultReceived || mException != null || isCancelled(); 138 | } 139 | 140 | @Override 141 | public synchronized void onResponse(T response) { 142 | mResultReceived = true; 143 | mResult = response; 144 | notifyAll(); 145 | } 146 | 147 | @Override 148 | public synchronized void onErrorResponse(VolleyError error) { 149 | mException = error; 150 | notifyAll(); 151 | } 152 | } 153 | 154 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/Volley.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox; 18 | 19 | import java.io.File; 20 | 21 | import android.annotation.TargetApi; 22 | import android.content.Context; 23 | import android.content.pm.PackageInfo; 24 | import android.content.pm.PackageManager.NameNotFoundException; 25 | import android.net.http.AndroidHttpClient; 26 | import android.os.Build; 27 | 28 | import com.android.volley.Network; 29 | import com.android.volley.RequestQueue; 30 | import com.android.volley.VolleyLog; 31 | 32 | @TargetApi(Build.VERSION_CODES.FROYO) 33 | public class Volley { 34 | 35 | /** Default on-disk cache directory. */ 36 | private static final String DEFAULT_CACHE_DIR = "volley"; 37 | 38 | /** 39 | * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it. 40 | * 41 | * @param context A {@link Context} to use for creating the cache dir. 42 | * @param stack An {@link HttpStack} to use for the network, or null for default. 43 | * @return A started {@link RequestQueue} instance. 44 | */ 45 | public static RequestQueue newRequestQueue(Context context, HttpStack stack) { 46 | File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR); 47 | 48 | String userAgent = null; 49 | try { 50 | String packageName = context.getPackageName(); 51 | PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0); 52 | userAgent = packageName + "/" + info.versionCode; 53 | } catch (NameNotFoundException e) { 54 | } 55 | 56 | if (stack == null) { 57 | if (Build.VERSION.SDK_INT >= 9) { 58 | stack = new HurlStack(userAgent); 59 | } else { 60 | // Prior to Gingerbread, HttpUrlConnection was unreliable. 61 | // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html 62 | stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); 63 | } 64 | } 65 | 66 | Network network = new BasicNetwork(stack); 67 | 68 | RequestQueue queue = new RequestQueue(new DiskLruBasedCache(cacheDir), network); 69 | queue.start(); 70 | 71 | return queue; 72 | } 73 | 74 | /** 75 | * 不带缓存的requestQueue 76 | * newNoCacheRequestQueue 77 | * @param context 78 | * @param stack 79 | * @return 80 | * @since 3.5 81 | */ 82 | public static RequestQueue newNoCacheRequestQueue(Context context) { 83 | String userAgent = null; 84 | try { 85 | String packageName = context.getPackageName(); 86 | PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0); 87 | userAgent = packageName + "/" + info.versionCode; 88 | } catch (NameNotFoundException e) { 89 | } 90 | 91 | HttpStack stack = null; 92 | if (Build.VERSION.SDK_INT >= 9) { 93 | stack = new HurlStack(userAgent); 94 | } else { 95 | // Prior to Gingerbread, HttpUrlConnection was unreliable. 96 | // See: 97 | // http://android-developers.blogspot.com/2011/09/androids-http-clients.html 98 | stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); 99 | } 100 | 101 | Network network = new BasicNetwork(stack); 102 | 103 | RequestQueue queue = new RequestQueue(new NoCache(), network); 104 | queue.start(); 105 | 106 | return queue; 107 | } 108 | 109 | /** 110 | * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it. 111 | * 112 | * @param context A {@link Context} to use for creating the cache dir. 113 | * @return A started {@link RequestQueue} instance. 114 | */ 115 | public static RequestQueue newRequestQueue(Context context) { 116 | return newRequestQueue(context, null); 117 | } 118 | 119 | public static File getDefaultCacheFile(Context context) { 120 | return new File(context.getCacheDir(), DEFAULT_CACHE_DIR); 121 | } 122 | 123 | /** 124 | * 判断是否打开volley的log输出 125 | * @param isOpened 126 | */ 127 | public void openLog(boolean isOpened) { 128 | VolleyLog.DEBUG = isOpened; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/com/android/volley/db/table/Column.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.table; 17 | 18 | import java.lang.reflect.Field; 19 | 20 | import java.lang.reflect.Method; 21 | 22 | import android.database.Cursor; 23 | 24 | import com.android.volley.VolleyLog; 25 | import com.android.volley.db.converter.ColumnConverter; 26 | import com.android.volley.db.converter.ColumnConverterFactory; 27 | import com.android.volley.db.sqlite.ColumnDbType; 28 | 29 | public class Column { 30 | 31 | private Table table; 32 | 33 | private int index = -1; 34 | 35 | protected final String columnName; 36 | private final Object defaultValue; 37 | 38 | protected final Method getMethod; 39 | protected final Method setMethod; 40 | 41 | protected final Field columnField; 42 | protected final ColumnConverter columnConverter; 43 | 44 | /* package */ Column(Class entityType, Field field) { 45 | this.columnField = field; 46 | this.columnConverter = ColumnConverterFactory.getColumnConverter(field.getType()); 47 | this.columnName = ColumnUtils.getColumnNameByField(field); 48 | if (this.columnConverter != null) { 49 | this.defaultValue = this.columnConverter.getFieldValue(ColumnUtils.getColumnDefaultValue(field)); 50 | } else { 51 | this.defaultValue = null; 52 | } 53 | this.getMethod = ColumnUtils.getColumnGetMethod(entityType, field); 54 | this.setMethod = ColumnUtils.getColumnSetMethod(entityType, field); 55 | } 56 | 57 | public void setValue2Entity(Object entity, Cursor cursor, int index) { 58 | this.index = index; 59 | Object value = columnConverter.getFieldValue(cursor, index); 60 | setValue(entity, value); 61 | } 62 | 63 | @SuppressWarnings("unchecked") 64 | public Object getColumnValue(Object entity) { 65 | Object fieldValue = getFieldValue(entity); 66 | return columnConverter.fieldValue2ColumnValue(fieldValue); 67 | } 68 | 69 | public void setValue(Object entity,Object value) { 70 | if (value == null && defaultValue == null) return; 71 | if (setMethod != null) { 72 | try { 73 | setMethod.invoke(entity, value == null ? defaultValue : value); 74 | } catch (Throwable e) { 75 | VolleyLog.e(e.getMessage(), e); 76 | } 77 | } else { 78 | try { 79 | this.columnField.setAccessible(true); 80 | this.columnField.set(entity, value == null ? defaultValue : value); 81 | } catch (Throwable e) { 82 | VolleyLog.e(e.getMessage(), e); 83 | } 84 | } 85 | } 86 | 87 | public Object getFieldValue(Object entity) { 88 | Object fieldValue = null; 89 | if (entity != null) { 90 | if (getMethod != null) { 91 | try { 92 | fieldValue = getMethod.invoke(entity); 93 | } catch (Throwable e) { 94 | VolleyLog.e(e.getMessage(), e); 95 | } 96 | } else { 97 | try { 98 | this.columnField.setAccessible(true); 99 | fieldValue = this.columnField.get(entity); 100 | } catch (Throwable e) { 101 | VolleyLog.e(e.getMessage(), e); 102 | } 103 | } 104 | } 105 | return fieldValue; 106 | } 107 | 108 | public Table getTable() { 109 | return table; 110 | } 111 | 112 | /* package */ void setTable(Table table) { 113 | this.table = table; 114 | } 115 | 116 | /** 117 | * The value set in setValue2Entity(...) 118 | * 119 | * @return -1 or the index of this column. 120 | */ 121 | public int getIndex() { 122 | return index; 123 | } 124 | 125 | public String getColumnName() { 126 | return columnName; 127 | } 128 | 129 | public Object getDefaultValue() { 130 | return defaultValue; 131 | } 132 | 133 | public Field getColumnField() { 134 | return columnField; 135 | } 136 | 137 | public ColumnConverter getColumnConverter() { 138 | return columnConverter; 139 | } 140 | 141 | public ColumnDbType getColumnDbType() { 142 | return columnConverter.getColumnDbType(); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/HttpHeaderParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox; 18 | 19 | import java.util.Map; 20 | 21 | import org.apache.http.impl.cookie.DateParseException; 22 | import org.apache.http.impl.cookie.DateUtils; 23 | import org.apache.http.protocol.HTTP; 24 | 25 | import com.android.volley.Cache; 26 | import com.android.volley.NetworkResponse; 27 | 28 | /** 29 | * Utility methods for parsing HTTP headers. 30 | */ 31 | public class HttpHeaderParser { 32 | 33 | /** 34 | * Extracts a {@link Cache.Entry} from a {@link NetworkResponse}. 35 | * 36 | * @param response The network response to parse headers from 37 | * @return a cache entry for the given response, or null if the response is not cacheable. 38 | */ 39 | public static Cache.Entry parseCacheHeaders(NetworkResponse response) { 40 | long now = System.currentTimeMillis(); 41 | 42 | Map headers = response.headers; 43 | 44 | long serverDate = 0; 45 | long serverExpires = 0; 46 | long softExpire = 0; 47 | long maxAge = 0; 48 | boolean hasCacheControl = false; 49 | 50 | String serverEtag = null; 51 | String headerValue; 52 | 53 | headerValue = headers.get("Date"); 54 | if (headerValue != null) { 55 | serverDate = parseDateAsEpoch(headerValue); 56 | } 57 | 58 | headerValue = headers.get("Cache-Control"); 59 | if (headerValue != null) { 60 | hasCacheControl = true; 61 | String[] tokens = headerValue.split(","); 62 | for (int i = 0; i < tokens.length; i++) { 63 | String token = tokens[i].trim(); 64 | if (token.equals("no-cache") || token.equals("no-store")) { 65 | return null; 66 | } else if (token.startsWith("max-age=")) { 67 | try { 68 | maxAge = Long.parseLong(token.substring(8)); 69 | } catch (Exception e) { 70 | } 71 | } else if (token.equals("must-revalidate") || token.equals("proxy-revalidate")) { 72 | maxAge = 0; 73 | } 74 | } 75 | } 76 | 77 | headerValue = headers.get("Expires"); 78 | if (headerValue != null) { 79 | serverExpires = parseDateAsEpoch(headerValue); 80 | } 81 | 82 | serverEtag = headers.get("ETag"); 83 | 84 | // Cache-Control takes precedence over an Expires header, even if both exist and Expires 85 | // is more restrictive. 86 | if (hasCacheControl) { 87 | softExpire = now + maxAge * 1000; 88 | } else if (serverDate > 0 && serverExpires >= serverDate) { 89 | // Default semantic for Expire header in HTTP specification is softExpire. 90 | softExpire = now + (serverExpires - serverDate); 91 | } 92 | Cache.Entry entry = new Cache.Entry(); 93 | entry.data = response.data; 94 | entry.etag = serverEtag; 95 | entry.softTtl = softExpire; 96 | entry.ttl = entry.softTtl; 97 | entry.serverDate = serverDate; 98 | entry.responseHeaders = headers; 99 | return entry; 100 | } 101 | 102 | /** 103 | * Parse date in RFC1123 format, and return its value as epoch 104 | */ 105 | public static long parseDateAsEpoch(String dateStr) { 106 | try { 107 | // Parse date in RFC1123 format if this header contains one 108 | return DateUtils.parseDate(dateStr).getTime(); 109 | } catch (DateParseException e) { 110 | // Date in invalid format, fallback to 0 111 | return 0; 112 | } 113 | } 114 | 115 | /** 116 | * Returns the charset specified in the Content-Type of this header, 117 | * or the HTTP default (UTF_8) if none can be found. 118 | */ 119 | public static String parseCharset(Map headers) { 120 | String contentType = headers.get(HTTP.CONTENT_TYPE); 121 | if (contentType != null) { 122 | String[] params = contentType.split(";"); 123 | for (int i = 1; i < params.length; i++) { 124 | String[] pair = params[i].trim().split("="); 125 | if (pair.length == 2) { 126 | if (pair[0].equals("charset")) { 127 | return pair[1]; 128 | } 129 | } 130 | } 131 | } 132 | 133 | return HTTP.UTF_8; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/com/android/volley/db/converter/ColumnConverterFactory.java: -------------------------------------------------------------------------------- 1 | package com.android.volley.db.converter; 2 | 3 | import java.util.Date; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | 6 | import com.android.volley.db.sqlite.ColumnDbType; 7 | 8 | /** 9 | * Author: wyouflf 10 | * Date: 13-11-4 11 | * Time: 下午10:27 12 | */ 13 | public class ColumnConverterFactory { 14 | 15 | private ColumnConverterFactory() { 16 | } 17 | 18 | public static ColumnConverter getColumnConverter(Class columnType) { 19 | if (columnType_columnConverter_map.containsKey(columnType.getName())) { 20 | return columnType_columnConverter_map.get(columnType.getName()); 21 | } else if (ColumnConverter.class.isAssignableFrom(columnType)) { 22 | try { 23 | ColumnConverter columnConverter = (ColumnConverter) columnType.newInstance(); 24 | if (columnConverter != null) { 25 | columnType_columnConverter_map.put(columnType.getName(), columnConverter); 26 | } 27 | return columnConverter; 28 | } catch (Throwable e) { 29 | } 30 | } 31 | return null; 32 | } 33 | 34 | public static ColumnDbType getDbColumnType(Class columnType) { 35 | ColumnConverter converter = getColumnConverter(columnType); 36 | if (converter != null) { 37 | return converter.getColumnDbType(); 38 | } 39 | return ColumnDbType.TEXT; 40 | } 41 | 42 | public static void registerColumnConverter(Class columnType, ColumnConverter columnConverter) { 43 | columnType_columnConverter_map.put(columnType.getName(), columnConverter); 44 | } 45 | 46 | public static boolean isSupportColumnConverter(Class columnType) { 47 | if (columnType_columnConverter_map.containsKey(columnType.getName())) { 48 | return true; 49 | } else if (ColumnConverter.class.isAssignableFrom(columnType)) { 50 | try { 51 | ColumnConverter columnConverter = (ColumnConverter) columnType.newInstance(); 52 | if (columnConverter != null) { 53 | columnType_columnConverter_map.put(columnType.getName(), columnConverter); 54 | } 55 | return columnConverter == null; 56 | } catch (Throwable e) { 57 | } 58 | } 59 | return false; 60 | } 61 | 62 | private static final ConcurrentHashMap columnType_columnConverter_map; 63 | 64 | static { 65 | columnType_columnConverter_map = new ConcurrentHashMap(); 66 | 67 | BooleanColumnConverter booleanColumnConverter = new BooleanColumnConverter(); 68 | columnType_columnConverter_map.put(boolean.class.getName(), booleanColumnConverter); 69 | columnType_columnConverter_map.put(Boolean.class.getName(), booleanColumnConverter); 70 | 71 | ByteArrayColumnConverter byteArrayColumnConverter = new ByteArrayColumnConverter(); 72 | columnType_columnConverter_map.put(byte[].class.getName(), byteArrayColumnConverter); 73 | 74 | ByteColumnConverter byteColumnConverter = new ByteColumnConverter(); 75 | columnType_columnConverter_map.put(byte.class.getName(), byteColumnConverter); 76 | columnType_columnConverter_map.put(Byte.class.getName(), byteColumnConverter); 77 | 78 | CharColumnConverter charColumnConverter = new CharColumnConverter(); 79 | columnType_columnConverter_map.put(char.class.getName(), charColumnConverter); 80 | columnType_columnConverter_map.put(Character.class.getName(), charColumnConverter); 81 | 82 | DateColumnConverter dateColumnConverter = new DateColumnConverter(); 83 | columnType_columnConverter_map.put(Date.class.getName(), dateColumnConverter); 84 | 85 | DoubleColumnConverter doubleColumnConverter = new DoubleColumnConverter(); 86 | columnType_columnConverter_map.put(double.class.getName(), doubleColumnConverter); 87 | columnType_columnConverter_map.put(Double.class.getName(), doubleColumnConverter); 88 | 89 | FloatColumnConverter floatColumnConverter = new FloatColumnConverter(); 90 | columnType_columnConverter_map.put(float.class.getName(), floatColumnConverter); 91 | columnType_columnConverter_map.put(Float.class.getName(), floatColumnConverter); 92 | 93 | IntegerColumnConverter integerColumnConverter = new IntegerColumnConverter(); 94 | columnType_columnConverter_map.put(int.class.getName(), integerColumnConverter); 95 | columnType_columnConverter_map.put(Integer.class.getName(), integerColumnConverter); 96 | 97 | LongColumnConverter longColumnConverter = new LongColumnConverter(); 98 | columnType_columnConverter_map.put(long.class.getName(), longColumnConverter); 99 | columnType_columnConverter_map.put(Long.class.getName(), longColumnConverter); 100 | 101 | ShortColumnConverter shortColumnConverter = new ShortColumnConverter(); 102 | columnType_columnConverter_map.put(short.class.getName(), shortColumnConverter); 103 | columnType_columnConverter_map.put(Short.class.getName(), shortColumnConverter); 104 | 105 | SqlDateColumnConverter sqlDateColumnConverter = new SqlDateColumnConverter(); 106 | columnType_columnConverter_map.put(java.sql.Date.class.getName(), sqlDateColumnConverter); 107 | 108 | StringColumnConverter stringColumnConverter = new StringColumnConverter(); 109 | columnType_columnConverter_map.put(String.class.getName(), stringColumnConverter); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/com/android/volley/db/sqlite/Selector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.sqlite; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | import com.android.volley.db.table.TableUtils; 22 | 23 | /** 24 | * Author: wyouflf 25 | * Date: 13-8-9 26 | * Time: 下午10:19 27 | */ 28 | public class Selector { 29 | 30 | protected Class entityType; 31 | protected String tableName; 32 | 33 | protected WhereBuilder whereBuilder; 34 | protected List orderByList; 35 | protected int limit = 0; 36 | protected int offset = 0; 37 | 38 | private Selector(Class entityType) { 39 | this.entityType = entityType; 40 | this.tableName = TableUtils.getTableName(entityType); 41 | } 42 | 43 | public static Selector from(Class entityType) { 44 | return new Selector(entityType); 45 | } 46 | 47 | public Selector where(WhereBuilder whereBuilder) { 48 | this.whereBuilder = whereBuilder; 49 | return this; 50 | } 51 | 52 | public Selector where(String columnName, String op, Object value) { 53 | this.whereBuilder = WhereBuilder.b(columnName, op, value); 54 | return this; 55 | } 56 | 57 | public Selector and(String columnName, String op, Object value) { 58 | this.whereBuilder.and(columnName, op, value); 59 | return this; 60 | } 61 | 62 | public Selector and(WhereBuilder where) { 63 | this.whereBuilder.expr("AND (" + where.toString() + ")"); 64 | return this; 65 | } 66 | 67 | public Selector or(String columnName, String op, Object value) { 68 | this.whereBuilder.or(columnName, op, value); 69 | return this; 70 | } 71 | 72 | public Selector or(WhereBuilder where) { 73 | this.whereBuilder.expr("OR (" + where.toString() + ")"); 74 | return this; 75 | } 76 | 77 | public Selector expr(String expr) { 78 | if (this.whereBuilder == null) { 79 | this.whereBuilder = WhereBuilder.b(); 80 | } 81 | this.whereBuilder.expr(expr); 82 | return this; 83 | } 84 | 85 | public Selector expr(String columnName, String op, Object value) { 86 | if (this.whereBuilder == null) { 87 | this.whereBuilder = WhereBuilder.b(); 88 | } 89 | this.whereBuilder.expr(columnName, op, value); 90 | return this; 91 | } 92 | 93 | public DbModelSelector groupBy(String columnName) { 94 | return new DbModelSelector(this, columnName); 95 | } 96 | 97 | public DbModelSelector select(String... columnExpressions) { 98 | return new DbModelSelector(this, columnExpressions); 99 | } 100 | 101 | public Selector orderBy(String columnName) { 102 | if (orderByList == null) { 103 | orderByList = new ArrayList(2); 104 | } 105 | orderByList.add(new OrderBy(columnName)); 106 | return this; 107 | } 108 | 109 | public Selector orderBy(String columnName, boolean desc) { 110 | if (orderByList == null) { 111 | orderByList = new ArrayList(2); 112 | } 113 | orderByList.add(new OrderBy(columnName, desc)); 114 | return this; 115 | } 116 | 117 | public Selector limit(int limit) { 118 | this.limit = limit; 119 | return this; 120 | } 121 | 122 | public Selector offset(int offset) { 123 | this.offset = offset; 124 | return this; 125 | } 126 | 127 | @Override 128 | public String toString() { 129 | StringBuilder result = new StringBuilder(); 130 | result.append("SELECT "); 131 | result.append("*"); 132 | result.append(" FROM ").append(tableName); 133 | if (whereBuilder != null && whereBuilder.getWhereItemSize() > 0) { 134 | result.append(" WHERE ").append(whereBuilder.toString()); 135 | } 136 | if (orderByList != null) { 137 | for (int i = 0; i < orderByList.size(); i++) { 138 | result.append(" ORDER BY ").append(orderByList.get(i).toString()); 139 | } 140 | } 141 | if (limit > 0) { 142 | result.append(" LIMIT ").append(limit); 143 | result.append(" OFFSET ").append(offset); 144 | } 145 | return result.toString(); 146 | } 147 | 148 | public Class getEntityType() { 149 | return entityType; 150 | } 151 | 152 | protected class OrderBy { 153 | private String columnName; 154 | private boolean desc; 155 | 156 | public OrderBy(String columnName) { 157 | this.columnName = columnName; 158 | } 159 | 160 | public OrderBy(String columnName, boolean desc) { 161 | this.columnName = columnName; 162 | this.desc = desc; 163 | } 164 | 165 | @Override 166 | public String toString() { 167 | return columnName + (desc ? " DESC" : " ASC"); 168 | } 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/com/android/volley/db/sqlite/DbModelSelector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.sqlite; 17 | 18 | import android.text.TextUtils; 19 | 20 | /** 21 | * Author: wyouflf 22 | * Date: 13-8-10 23 | * Time: 下午2:15 24 | */ 25 | public class DbModelSelector { 26 | 27 | private String[] columnExpressions; 28 | private String groupByColumnName; 29 | private WhereBuilder having; 30 | 31 | private Selector selector; 32 | 33 | private DbModelSelector(Class entityType) { 34 | selector = Selector.from(entityType); 35 | } 36 | 37 | protected DbModelSelector(Selector selector, String groupByColumnName) { 38 | this.selector = selector; 39 | this.groupByColumnName = groupByColumnName; 40 | } 41 | 42 | protected DbModelSelector(Selector selector, String[] columnExpressions) { 43 | this.selector = selector; 44 | this.columnExpressions = columnExpressions; 45 | } 46 | 47 | public static DbModelSelector from(Class entityType) { 48 | return new DbModelSelector(entityType); 49 | } 50 | 51 | public DbModelSelector where(WhereBuilder whereBuilder) { 52 | selector.where(whereBuilder); 53 | return this; 54 | } 55 | 56 | public DbModelSelector where(String columnName, String op, Object value) { 57 | selector.where(columnName, op, value); 58 | return this; 59 | } 60 | 61 | public DbModelSelector and(String columnName, String op, Object value) { 62 | selector.and(columnName, op, value); 63 | return this; 64 | } 65 | 66 | public DbModelSelector and(WhereBuilder where) { 67 | selector.and(where); 68 | return this; 69 | } 70 | 71 | public DbModelSelector or(String columnName, String op, Object value) { 72 | selector.or(columnName, op, value); 73 | return this; 74 | } 75 | 76 | public DbModelSelector or(WhereBuilder where) { 77 | selector.or(where); 78 | return this; 79 | } 80 | 81 | public DbModelSelector expr(String expr) { 82 | selector.expr(expr); 83 | return this; 84 | } 85 | 86 | public DbModelSelector expr(String columnName, String op, Object value) { 87 | selector.expr(columnName, op, value); 88 | return this; 89 | } 90 | 91 | public DbModelSelector groupBy(String columnName) { 92 | this.groupByColumnName = columnName; 93 | return this; 94 | } 95 | 96 | public DbModelSelector having(WhereBuilder whereBuilder) { 97 | this.having = whereBuilder; 98 | return this; 99 | } 100 | 101 | public DbModelSelector select(String... columnExpressions) { 102 | this.columnExpressions = columnExpressions; 103 | return this; 104 | } 105 | 106 | public DbModelSelector orderBy(String columnName) { 107 | selector.orderBy(columnName); 108 | return this; 109 | } 110 | 111 | public DbModelSelector orderBy(String columnName, boolean desc) { 112 | selector.orderBy(columnName, desc); 113 | return this; 114 | } 115 | 116 | public DbModelSelector limit(int limit) { 117 | selector.limit(limit); 118 | return this; 119 | } 120 | 121 | public DbModelSelector offset(int offset) { 122 | selector.offset(offset); 123 | return this; 124 | } 125 | 126 | public Class getEntityType() { 127 | return selector.getEntityType(); 128 | } 129 | 130 | @Override 131 | public String toString() { 132 | StringBuffer result = new StringBuffer(); 133 | result.append("SELECT "); 134 | if (columnExpressions != null && columnExpressions.length > 0) { 135 | for (int i = 0; i < columnExpressions.length; i++) { 136 | result.append(columnExpressions[i]); 137 | result.append(","); 138 | } 139 | result.deleteCharAt(result.length() - 1); 140 | } else { 141 | if (!TextUtils.isEmpty(groupByColumnName)) { 142 | result.append(groupByColumnName); 143 | } else { 144 | result.append("*"); 145 | } 146 | } 147 | result.append(" FROM ").append(selector.tableName); 148 | if (selector.whereBuilder != null && selector.whereBuilder.getWhereItemSize() > 0) { 149 | result.append(" WHERE ").append(selector.whereBuilder.toString()); 150 | } 151 | if (!TextUtils.isEmpty(groupByColumnName)) { 152 | result.append(" GROUP BY ").append(groupByColumnName); 153 | if (having != null && having.getWhereItemSize() > 0) { 154 | result.append(" HAVING ").append(having.toString()); 155 | } 156 | } 157 | if (selector.orderByList != null) { 158 | for (int i = 0; i < selector.orderByList.size(); i++) { 159 | result.append(" ORDER BY ").append(selector.orderByList.get(i).toString()); 160 | } 161 | } 162 | if (selector.limit > 0) { 163 | result.append(" LIMIT ").append(selector.limit); 164 | result.append(" OFFSET ").append(selector.offset); 165 | } 166 | return result.toString(); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/com/android/volley/toolbox/ByteArrayPool.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley.toolbox; 18 | 19 | import java.util.ArrayList; 20 | import java.util.Collections; 21 | import java.util.Comparator; 22 | import java.util.LinkedList; 23 | import java.util.List; 24 | 25 | /** 26 | * ByteArrayPool is a source and repository of byte[] objects. Its purpose is to 27 | * supply those buffers to consumers who need to use them for a short period of time and then 28 | * dispose of them. Simply creating and disposing such buffers in the conventional manner can 29 | * considerable heap churn and garbage collection delays on Android, which lacks good management of 30 | * short-lived heap objects. It may be advantageous to trade off some memory in the form of a 31 | * permanently allocated pool of buffers in order to gain heap performance improvements; that is 32 | * what this class does. 33 | *

34 | * A good candidate user for this class is something like an I/O system that uses large temporary 35 | * byte[] buffers to copy data around. In these use cases, often the consumer wants 36 | * the buffer to be a certain minimum size to ensure good performance (e.g. when copying data chunks 37 | * off of a stream), but doesn't mind if the buffer is larger than the minimum. Taking this into 38 | * account and also to maximize the odds of being able to reuse a recycled buffer, this class is 39 | * free to return buffers larger than the requested size. The caller needs to be able to gracefully 40 | * deal with getting buffers any size over the minimum. 41 | *

42 | * If there is not a suitably-sized buffer in its recycling pool when a buffer is requested, this 43 | * class will allocate a new buffer and return it. 44 | *

45 | * This class has no special ownership of buffers it creates; the caller is free to take a buffer 46 | * it receives from this pool, use it permanently, and never return it to the pool; additionally, 47 | * it is not harmful to return to this pool a buffer that was allocated elsewhere, provided there 48 | * are no other lingering references to it. 49 | *

50 | * This class ensures that the total size of the buffers in its recycling pool never exceeds a 51 | * certain byte limit. When a buffer is returned that would cause the pool to exceed the limit, 52 | * least-recently-used buffers are disposed. 53 | */ 54 | public class ByteArrayPool { 55 | /** The buffer pool, arranged both by last use and by buffer size */ 56 | private List mBuffersByLastUse = new LinkedList(); 57 | private List mBuffersBySize = new ArrayList(64); 58 | 59 | /** The total size of the buffers in the pool */ 60 | private int mCurrentSize = 0; 61 | 62 | /** 63 | * The maximum aggregate size of the buffers in the pool. Old buffers are discarded to stay 64 | * under this limit. 65 | */ 66 | private final int mSizeLimit; 67 | 68 | /** Compares buffers by size */ 69 | protected static final Comparator BUF_COMPARATOR = new Comparator() { 70 | @Override 71 | public int compare(byte[] lhs, byte[] rhs) { 72 | return lhs.length - rhs.length; 73 | } 74 | }; 75 | 76 | /** 77 | * @param sizeLimit the maximum size of the pool, in bytes 78 | */ 79 | public ByteArrayPool(int sizeLimit) { 80 | mSizeLimit = sizeLimit; 81 | } 82 | 83 | /** 84 | * Returns a buffer from the pool if one is available in the requested size, or allocates a new 85 | * one if a pooled one is not available. 86 | * 87 | * @param len the minimum size, in bytes, of the requested buffer. The returned buffer may be 88 | * larger. 89 | * @return a byte[] buffer is always returned. 90 | */ 91 | public synchronized byte[] getBuf(int len) { 92 | for (int i = 0; i < mBuffersBySize.size(); i++) { 93 | byte[] buf = mBuffersBySize.get(i); 94 | if (buf.length >= len) { 95 | mCurrentSize -= buf.length; 96 | mBuffersBySize.remove(i); 97 | mBuffersByLastUse.remove(buf); 98 | return buf; 99 | } 100 | } 101 | return new byte[len]; 102 | } 103 | 104 | /** 105 | * Returns a buffer to the pool, throwing away old buffers if the pool would exceed its allotted 106 | * size. 107 | * 108 | * @param buf the buffer to return to the pool. 109 | */ 110 | public synchronized void returnBuf(byte[] buf) { 111 | if (buf == null || buf.length > mSizeLimit) { 112 | return; 113 | } 114 | mBuffersByLastUse.add(buf); 115 | int pos = Collections.binarySearch(mBuffersBySize, buf, BUF_COMPARATOR); 116 | if (pos < 0) { 117 | pos = -pos - 1; 118 | } 119 | mBuffersBySize.add(pos, buf); 120 | mCurrentSize += buf.length; 121 | trim(); 122 | } 123 | 124 | /** 125 | * Removes buffers from the pool until it is under its size limit. 126 | */ 127 | private synchronized void trim() { 128 | while (mCurrentSize > mSizeLimit) { 129 | byte[] buf = mBuffersByLastUse.remove(0); 130 | mBuffersBySize.remove(buf); 131 | mCurrentSize -= buf.length; 132 | } 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /src/com/android/volley/db/sqlite/CursorUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.sqlite; 17 | 18 | import java.util.HashMap; 19 | import java.util.Map.Entry; 20 | import java.util.concurrent.ConcurrentHashMap; 21 | 22 | import android.database.Cursor; 23 | 24 | import com.android.volley.VolleyLog; 25 | import com.android.volley.db.table.Column; 26 | import com.android.volley.db.table.DbModel; 27 | import com.android.volley.db.table.Finder; 28 | import com.android.volley.db.table.Id; 29 | import com.android.volley.db.table.Table; 30 | import com.android.volley.ext.tools.DbTools; 31 | 32 | public class CursorUtils { 33 | 34 | public static T getEntity(final DbTools db, final Cursor cursor, Class entityType, long findCacheSequence) { 35 | if (db == null || cursor == null) return null; 36 | 37 | EntityTempCache.setSeq(findCacheSequence); 38 | try { 39 | Table table = Table.get(db, entityType); 40 | Id id = table.id; 41 | String idColumnName = id.getColumnName(); 42 | int idIndex = id.getIndex(); 43 | if (idIndex < 0) { 44 | idIndex = cursor.getColumnIndex(idColumnName); 45 | } 46 | Object idValue = id.getColumnConverter().getFieldValue(cursor, idIndex); 47 | T entity = EntityTempCache.get(entityType, idValue); 48 | if (entity == null) { 49 | entity = entityType.newInstance(); 50 | id.setValue2Entity(entity, cursor, idIndex); 51 | EntityTempCache.put(entityType, idValue, entity); 52 | } else { 53 | return entity; 54 | } 55 | int columnCount = cursor.getColumnCount(); 56 | for (int i = 0; i < columnCount; i++) { 57 | String columnName = cursor.getColumnName(i); 58 | Column column = table.columnMap.get(columnName); 59 | if (column != null) { 60 | column.setValue2Entity(entity, cursor, i); 61 | } 62 | } 63 | 64 | // init finder 65 | for (Finder finder : table.finderMap.values()) { 66 | finder.setValue2Entity(entity, null, 0); 67 | } 68 | return entity; 69 | } catch (Throwable e) { 70 | VolleyLog.e(e.getMessage(), e); 71 | } 72 | 73 | return null; 74 | } 75 | 76 | public static T dbModel2Entity(final DbTools db, DbModel dbModel,Class clazz){ 77 | if(dbModel!=null){ 78 | HashMap dataMap = dbModel.getDataMap(); 79 | try { 80 | @SuppressWarnings("unchecked") 81 | T entity = (T) clazz.newInstance(); 82 | for(Entry entry : dataMap.entrySet()){ 83 | String columnKey = entry.getKey(); 84 | Table table = Table.get(db, clazz); 85 | Column column = table.columnMap.get(columnKey); 86 | if (column != null) { 87 | column.setValue(entity, entry.getValue()==null?null:entry.getValue().toString()); 88 | } 89 | } 90 | return entity; 91 | } catch (Exception e) { 92 | e.printStackTrace(); 93 | } 94 | } 95 | 96 | return null; 97 | } 98 | 99 | public static DbModel getDbModel(final Cursor cursor) { 100 | DbModel result = null; 101 | if (cursor != null) { 102 | result = new DbModel(); 103 | int columnCount = cursor.getColumnCount(); 104 | for (int i = 0; i < columnCount; i++) { 105 | result.add(cursor.getColumnName(i), cursor.getString(i)); 106 | } 107 | } 108 | return result; 109 | } 110 | 111 | public static class FindCacheSequence { 112 | private FindCacheSequence() { 113 | } 114 | 115 | private static long seq = 0; 116 | private static final String FOREIGN_LAZY_LOADER_CLASS_NAME = ForeignLazyLoader.class.getName(); 117 | private static final String FINDER_LAZY_LOADER_CLASS_NAME = FinderLazyLoader.class.getName(); 118 | 119 | public static long getSeq() { 120 | String findMethodCaller = Thread.currentThread().getStackTrace()[4].getClassName(); 121 | if (!findMethodCaller.equals(FOREIGN_LAZY_LOADER_CLASS_NAME) && !findMethodCaller.equals(FINDER_LAZY_LOADER_CLASS_NAME)) { 122 | ++seq; 123 | } 124 | return seq; 125 | } 126 | } 127 | 128 | private static class EntityTempCache { 129 | private EntityTempCache() { 130 | } 131 | 132 | private static final ConcurrentHashMap cache = new ConcurrentHashMap(); 133 | 134 | private static long seq = 0; 135 | 136 | public static void put(Class entityType, Object idValue, Object entity) { 137 | cache.put(entityType.getName() + "#" + idValue, entity); 138 | } 139 | 140 | @SuppressWarnings("unchecked") 141 | public static T get(Class entityType, Object idValue) { 142 | return (T) cache.get(entityType.getName() + "#" + idValue); 143 | } 144 | 145 | public static void setSeq(long seq) { 146 | if (EntityTempCache.seq != seq) { 147 | cache.clear(); 148 | EntityTempCache.seq = seq; 149 | } 150 | } 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/com/android/volley/db/table/Foreign.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package com.android.volley.db.table; 17 | 18 | import java.lang.reflect.Field; 19 | import java.util.List; 20 | 21 | import android.database.Cursor; 22 | 23 | import com.android.volley.VolleyLog; 24 | import com.android.volley.db.DbException; 25 | import com.android.volley.db.converter.ColumnConverter; 26 | import com.android.volley.db.converter.ColumnConverterFactory; 27 | import com.android.volley.db.sqlite.ColumnDbType; 28 | import com.android.volley.db.sqlite.ForeignLazyLoader; 29 | 30 | public class Foreign extends Column { 31 | 32 | private final String foreignColumnName; 33 | private final ColumnConverter foreignColumnConverter; 34 | 35 | /* package */ Foreign(Class entityType, Field field) { 36 | super(entityType, field); 37 | 38 | foreignColumnName = ColumnUtils.getForeignColumnNameByField(field); 39 | Class foreignColumnType = 40 | TableUtils.getColumnOrId(getForeignEntityType(), foreignColumnName).columnField.getType(); 41 | foreignColumnConverter = ColumnConverterFactory.getColumnConverter(foreignColumnType); 42 | } 43 | 44 | public String getForeignColumnName() { 45 | return foreignColumnName; 46 | } 47 | 48 | public Class getForeignEntityType() { 49 | return ColumnUtils.getForeignEntityType(this); 50 | } 51 | 52 | @SuppressWarnings("unchecked") 53 | @Override 54 | public void setValue2Entity(Object entity, Cursor cursor, int index) { 55 | Object fieldValue = foreignColumnConverter.getFieldValue(cursor, index); 56 | if (fieldValue == null) return; 57 | 58 | Object value = null; 59 | Class columnType = columnField.getType(); 60 | if (columnType.equals(ForeignLazyLoader.class)) { 61 | value = new ForeignLazyLoader(this, fieldValue); 62 | } else if (columnType.equals(List.class)) { 63 | try { 64 | value = new ForeignLazyLoader(this, fieldValue).getAllFromDb(); 65 | } catch (DbException e) { 66 | VolleyLog.e(e.getMessage(), e); 67 | } 68 | } else { 69 | try { 70 | value = new ForeignLazyLoader(this, fieldValue).getFirstFromDb(); 71 | } catch (DbException e) { 72 | VolleyLog.e(e.getMessage(), e); 73 | } 74 | } 75 | 76 | if (setMethod != null) { 77 | try { 78 | setMethod.invoke(entity, value); 79 | } catch (Throwable e) { 80 | VolleyLog.e(e.getMessage(), e); 81 | } 82 | } else { 83 | try { 84 | this.columnField.setAccessible(true); 85 | this.columnField.set(entity, value); 86 | } catch (Throwable e) { 87 | VolleyLog.e(e.getMessage(), e); 88 | } 89 | } 90 | } 91 | 92 | @SuppressWarnings("unchecked") 93 | @Override 94 | public Object getColumnValue(Object entity) { 95 | Object fieldValue = getFieldValue(entity); 96 | Object columnValue = null; 97 | 98 | if (fieldValue != null) { 99 | Class columnType = columnField.getType(); 100 | if (columnType.equals(ForeignLazyLoader.class)) { 101 | columnValue = ((ForeignLazyLoader) fieldValue).getColumnValue(); 102 | } else if (columnType.equals(List.class)) { 103 | try { 104 | List foreignEntities = (List) fieldValue; 105 | if (foreignEntities.size() > 0) { 106 | 107 | Class foreignEntityType = ColumnUtils.getForeignEntityType(this); 108 | Column column = TableUtils.getColumnOrId(foreignEntityType, foreignColumnName); 109 | columnValue = column.getColumnValue(foreignEntities.get(0)); 110 | 111 | // 仅自动关联外 112 | Table table = this.getTable(); 113 | if (table != null && column instanceof Id) { 114 | for (Object foreignObj : foreignEntities) { 115 | Object idValue = column.getColumnValue(foreignObj); 116 | if (idValue == null) { 117 | table.db.saveOrUpdate(foreignObj); 118 | } 119 | } 120 | } 121 | 122 | columnValue = column.getColumnValue(foreignEntities.get(0)); 123 | } 124 | } catch (Throwable e) { 125 | VolleyLog.e(e.getMessage(), e); 126 | } 127 | } else { 128 | try { 129 | Column column = TableUtils.getColumnOrId(columnType, foreignColumnName); 130 | columnValue = column.getColumnValue(fieldValue); 131 | 132 | Table table = this.getTable(); 133 | if (table != null && columnValue == null && column instanceof Id) { 134 | table.db.saveOrUpdate(fieldValue); 135 | } 136 | 137 | columnValue = column.getColumnValue(fieldValue); 138 | } catch (Throwable e) { 139 | VolleyLog.e(e.getMessage(), e); 140 | } 141 | } 142 | } 143 | 144 | return columnValue; 145 | } 146 | 147 | @Override 148 | public ColumnDbType getColumnDbType() { 149 | return foreignColumnConverter.getColumnDbType(); 150 | } 151 | 152 | /** 153 | * It always return null. 154 | * 155 | * @return null 156 | */ 157 | @Override 158 | public Object getDefaultValue() { 159 | return null; 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/com/android/volley/NetworkDispatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.android.volley; 18 | 19 | import java.util.concurrent.BlockingQueue; 20 | 21 | import android.annotation.TargetApi; 22 | import android.net.TrafficStats; 23 | import android.os.Build; 24 | import android.os.Process; 25 | 26 | /** 27 | * Provides a thread for performing network dispatch from a queue of requests. 28 | * 29 | * Requests added to the specified queue are processed from the network via a 30 | * specified {@link Network} interface. Responses are committed to cache, if 31 | * eligible, using a specified {@link Cache} interface. Valid responses and 32 | * errors are posted back to the caller via a {@link ResponseDelivery}. 33 | */ 34 | public class NetworkDispatcher extends Thread { 35 | /** The queue of requests to service. */ 36 | private final BlockingQueue> mQueue; 37 | /** The network interface for processing requests. */ 38 | private final Network mNetwork; 39 | /** The cache to write to. */ 40 | private final Cache mCache; 41 | /** For posting responses and errors. */ 42 | private final ResponseDelivery mDelivery; 43 | /** Used for telling us to die. */ 44 | private volatile boolean mQuit = false; 45 | 46 | private volatile boolean mPause = false; 47 | private Object mPauseLock = new Object(); 48 | 49 | /** 50 | * Creates a new network dispatcher thread. You must call {@link #start()} 51 | * in order to begin processing. 52 | * 53 | * @param queue Queue of incoming requests for triage 54 | * @param network Network interface to use for performing requests 55 | * @param cache Cache interface to use for writing responses to cache 56 | * @param delivery Delivery interface to use for posting responses 57 | */ 58 | public NetworkDispatcher(BlockingQueue> queue, 59 | Network network, Cache cache, 60 | ResponseDelivery delivery) { 61 | mQueue = queue; 62 | mNetwork = network; 63 | mCache = cache; 64 | mDelivery = delivery; 65 | } 66 | 67 | /** 68 | * Forces this dispatcher to quit immediately. If any requests are still in 69 | * the queue, they are not guaranteed to be processed. 70 | */ 71 | public void quit() { 72 | resumeTask(); 73 | mQuit = true; 74 | interrupt(); 75 | } 76 | 77 | // chenbo add start 78 | public void resumeTask() { 79 | mPause = false; 80 | synchronized (mPauseLock) { 81 | mPauseLock.notifyAll(); 82 | } 83 | } 84 | 85 | public void pauseTask() { 86 | mPause = true; 87 | } 88 | 89 | // end 90 | 91 | @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) 92 | private void addTrafficStatsTag(Request request) { 93 | // Tag the request (if API >= 14) 94 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 95 | TrafficStats.setThreadStatsTag(request.getTrafficStatsTag()); 96 | } 97 | } 98 | 99 | @Override 100 | public void run() { 101 | Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 102 | while (true) { 103 | Request request; 104 | try { 105 | if (mPause) { 106 | synchronized (mPauseLock) { 107 | mPauseLock.wait(); 108 | } 109 | } 110 | // Take a request from the queue. 111 | request = mQueue.take(); 112 | } catch (InterruptedException e) { 113 | // We may have been interrupted because it was time to quit. 114 | if (mQuit) { 115 | return; 116 | } 117 | continue; 118 | } 119 | try { 120 | request.addMarker("network-queue-take"); 121 | 122 | // If the request was cancelled already, do not perform the 123 | // network request. 124 | if (request.isCanceled()) { 125 | request.finish("network-discard-cancelled"); 126 | continue; 127 | } 128 | addTrafficStatsTag(request); 129 | 130 | // Perform the network request. 131 | NetworkResponse networkResponse = mNetwork.performRequest(mDelivery, request); 132 | request.addMarker("network-http-complete"); 133 | 134 | // If the server returned 304 AND we delivered a response already, 135 | // we're done -- don't deliver a second identical response. 136 | if (networkResponse.notModified && request.hasHadResponseDelivered()) { 137 | request.finish("not-modified"); 138 | continue; 139 | } 140 | 141 | // Parse the response here on the worker thread. 142 | Response response = request.parseNetworkResponse(networkResponse); 143 | request.addMarker("network-parse-complete"); 144 | 145 | // Write to cache if applicable. 146 | // TODO: Only update cache metadata instead of entire record for 304s. 147 | if (request.shouldCache() && response.cacheEntry != null) { 148 | mCache.put(request.getCacheKey(), response.cacheEntry); 149 | request.addMarker("network-cache-written"); 150 | } 151 | 152 | // Post the response back. 153 | request.markDelivered(); 154 | mDelivery.postResponse(request, response); 155 | } catch (VolleyError volleyError) { 156 | parseAndDeliverNetworkError(request, volleyError); 157 | } catch (Exception e) { 158 | VolleyLog.e(e, "Unhandled exception %s", e.toString()); 159 | mDelivery.postError(request, new VolleyError(e)); 160 | } 161 | } 162 | } 163 | 164 | private void parseAndDeliverNetworkError(Request request, VolleyError error) { 165 | error = request.parseNetworkError(error); 166 | mDelivery.postError(request, error); 167 | } 168 | } 169 | --------------------------------------------------------------------------------