Move modified dependencies to another repository. Reorganize dependencies

This commit is contained in:
len 2016-04-09 17:33:21 +02:00
parent c1ebccd0f4
commit ff906e8ee7
20 changed files with 47 additions and 3813 deletions

View File

@ -95,9 +95,11 @@ dependencies {
final STORIO_VERSION = '1.8.0'
final MOCKITO_VERSION = '1.10.19'
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(":SubsamplingScaleImageView")
// Modified dependencies
compile 'com.github.inorichi:subsampling-scale-image-view:7dc97eb'
compile 'com.github.inorichi:ReactiveNetwork:69092ed'
// Android support library
compile "com.android.support:support-v4:$SUPPORT_LIBRARY_VERSION"
compile "com.android.support:appcompat-v7:$SUPPORT_LIBRARY_VERSION"
compile "com.android.support:cardview-v7:$SUPPORT_LIBRARY_VERSION"
@ -107,39 +109,65 @@ dependencies {
compile "com.android.support:percent:$SUPPORT_LIBRARY_VERSION"
compile "com.android.support:preference-v7:$SUPPORT_LIBRARY_VERSION"
compile "com.android.support:preference-v14:$SUPPORT_LIBRARY_VERSION"
compile "com.squareup.okhttp3:okhttp:$OKHTTP_VERSION"
compile "com.squareup.okhttp3:okhttp-urlconnection:$OKHTTP_VERSION"
compile 'com.squareup.okio:okio:1.6.0'
compile "com.squareup.retrofit2:retrofit:$RETROFIT_VERSION"
compile "com.squareup.retrofit2:converter-gson:$RETROFIT_VERSION"
compile "com.squareup.retrofit2:adapter-rxjava:$RETROFIT_VERSION"
compile 'com.jakewharton:disklrucache:2.0.2'
compile 'com.google.code.gson:gson:2.6.2'
compile 'org.jsoup:jsoup:1.8.3'
// ReactiveX
compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.1'
compile 'com.f2prateek.rx.preferences:rx-preferences:1.0.1'
// Network client
compile "com.squareup.okhttp3:okhttp:$OKHTTP_VERSION"
compile "com.squareup.okhttp3:okhttp-urlconnection:$OKHTTP_VERSION"
// REST
compile "com.squareup.retrofit2:retrofit:$RETROFIT_VERSION"
compile "com.squareup.retrofit2:converter-gson:$RETROFIT_VERSION"
compile "com.squareup.retrofit2:adapter-rxjava:$RETROFIT_VERSION"
// IO
compile 'com.squareup.okio:okio:1.6.0'
// JSON
compile 'com.google.code.gson:gson:2.6.2'
// Disk cache
compile 'com.jakewharton:disklrucache:2.0.2'
// Parse HTML
compile 'org.jsoup:jsoup:1.8.3'
// Database
compile "com.pushtorefresh.storio:sqlite:$STORIO_VERSION"
compile "com.pushtorefresh.storio:sqlite-annotations:$STORIO_VERSION"
kapt "com.pushtorefresh.storio:sqlite-annotations-processor:$STORIO_VERSION"
// Model View Presenter
compile 'info.android15.nucleus:nucleus:2.0.5'
// Dependency injection
compile "com.google.dagger:dagger:$DAGGER_VERSION"
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
provided 'org.glassfish:javax.annotation:10.0-b28'
// Image library
compile 'com.github.bumptech.glide:glide:3.7.0'
// Logging
compile 'com.jakewharton.timber:timber:4.1.2'
// Crash reports
compile 'ch.acra:acra:4.8.5'
// UI
compile 'com.github.dmytrodanylyk.android-process-button:library:1.0.4'
compile 'eu.davidea:flexible-adapter:4.2.0'
compile 'com.nononsenseapps:filepicker:2.5.2'
compile 'com.github.amulyakhare:TextDrawable:558677e'
compile "com.google.dagger:dagger:$DAGGER_VERSION"
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
kapt "com.pushtorefresh.storio:sqlite-annotations-processor:$STORIO_VERSION"
provided 'org.glassfish:javax.annotation:10.0-b28'
compile('com.github.afollestad.material-dialogs:core:0.8.5.5@aar') {
transitive = true
}
// Tests
testCompile 'junit:junit:4.12'
testCompile 'org.assertj:assertj-core:1.7.1'
testCompile "org.mockito:mockito-core:$MOCKITO_VERSION"

View File

@ -1,84 +0,0 @@
/*
* Copyright (C) 2015 Piotr Wittchen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.pwittchen.reactivenetwork.library;
import rx.functions.Func1;
public enum ConnectivityStatus {
UNKNOWN("unknown"),
WIFI_CONNECTED("connected to WiFi"),
WIFI_CONNECTED_HAS_INTERNET("connected to WiFi (Internet available)"),
WIFI_CONNECTED_HAS_NO_INTERNET("connected to WiFi (Internet not available)"),
MOBILE_CONNECTED("connected to mobile network"),
OFFLINE("offline");
public final String description;
ConnectivityStatus(final String description) {
this.description = description;
}
/**
* Creates a function, which checks
* if single connectivity status or many statuses
* are equal to current status. It can be used inside filter(...)
* method from RxJava
*
* @param statuses many connectivity statuses or single status
* @return Func1<ConnectivityStatus, Boolean> from RxJava
*/
public static Func1<ConnectivityStatus, Boolean> isEqualTo(final ConnectivityStatus... statuses) {
return new Func1<ConnectivityStatus, Boolean>() {
@Override public Boolean call(ConnectivityStatus connectivityStatus) {
boolean statuesAreEqual = false;
for (ConnectivityStatus singleStatus : statuses) {
statuesAreEqual = singleStatus == connectivityStatus;
}
return statuesAreEqual;
}
};
}
/**
* Creates a function, which checks
* if single connectivity status or many statuses
* are not equal to current status. It can be used inside filter(...)
* method from RxJava
*
* @param statuses many connectivity statuses or single status
* @return Func1<ConnectivityStatus, Boolean> from RxJava
*/
public static Func1<ConnectivityStatus, Boolean> isNotEqualTo(
final ConnectivityStatus... statuses) {
return new Func1<ConnectivityStatus, Boolean>() {
@Override public Boolean call(ConnectivityStatus connectivityStatus) {
boolean statuesAreNotEqual = false;
for (ConnectivityStatus singleStatus : statuses) {
statuesAreNotEqual = singleStatus != connectivityStatus;
}
return statuesAreNotEqual;
}
};
}
@Override public String toString() {
return "ConnectivityStatus{" + "description='" + description + '\'' + '}';
}
}

View File

@ -1,142 +0,0 @@
/*
* Copyright (C) 2015 Piotr Wittchen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.pwittchen.reactivenetwork.library;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Looper;
import rx.Observable;
import rx.Scheduler;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action0;
import rx.subscriptions.Subscriptions;
/**
* ReactiveNetwork is an Android library
* listening network connection state and change of the WiFi signal strength
* with RxJava Observables. It can be easily used with RxAndroid.
*/
public class ReactiveNetwork {
private boolean checkInternet = false;
private ConnectivityStatus status = ConnectivityStatus.UNKNOWN;
/**
* Enables Internet connection check.
* When it's called WIFI_CONNECTED_HAS_INTERNET and WIFI_CONNECTED_HAS_NO_INTERNET statuses
* can be emitted by observeConnectivity(context) method. When it isn't called
* only WIFI_CONNECTED can by emitted by observeConnectivity(context) method.
*
* @return ReactiveNetwork object
*/
public ReactiveNetwork enableInternetCheck() {
checkInternet = true;
return this;
}
/**
* Observes ConnectivityStatus,
* which can be WIFI_CONNECTED, MOBILE_CONNECTED or OFFLINE
*
* @param context Context of the activity or an application
* @return RxJava Observable with ConnectivityStatus
*/
public Observable<ConnectivityStatus> observeConnectivity(final Context context) {
final IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
return Observable.create(new Observable.OnSubscribe<ConnectivityStatus>() {
@Override public void call(final Subscriber<? super ConnectivityStatus> subscriber) {
final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override public void onReceive(Context context, Intent intent) {
final ConnectivityStatus newStatus = getConnectivityStatus(context, checkInternet);
// we need to perform check below,
// because after going off-line, onReceive() is called twice
if (newStatus != status) {
status = newStatus;
subscriber.onNext(newStatus);
}
}
};
context.registerReceiver(receiver, filter);
subscriber.add(unsubscribeInUiThread(new Action0() {
@Override public void call() {
context.unregisterReceiver(receiver);
}
}));
}
}).defaultIfEmpty(ConnectivityStatus.OFFLINE);
}
public ConnectivityStatus getConnectivityStatus(final Context context,
final boolean checkInternet) {
final String service = Context.CONNECTIVITY_SERVICE;
final ConnectivityManager manager = (ConnectivityManager) context.getSystemService(service);
final NetworkInfo networkInfo = manager.getActiveNetworkInfo();
if (networkInfo == null) {
return ConnectivityStatus.OFFLINE;
}
if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
if (checkInternet) {
return getWifiInternetStatus(networkInfo);
} else {
return ConnectivityStatus.WIFI_CONNECTED;
}
} else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
return ConnectivityStatus.MOBILE_CONNECTED;
}
return ConnectivityStatus.OFFLINE;
}
private ConnectivityStatus getWifiInternetStatus(final NetworkInfo networkInfo) {
if (networkInfo.isConnected()) {
return ConnectivityStatus.WIFI_CONNECTED_HAS_INTERNET;
} else {
return ConnectivityStatus.WIFI_CONNECTED_HAS_NO_INTERNET;
}
}
private Subscription unsubscribeInUiThread(final Action0 unsubscribe) {
return Subscriptions.create(new Action0() {
@Override public void call() {
if (Looper.getMainLooper() == Looper.myLooper()) {
unsubscribe.call();
} else {
final Scheduler.Worker inner = AndroidSchedulers.mainThread().createWorker();
inner.schedule(new Action0() {
@Override public void call() {
unsubscribe.call();
inner.unsubscribe();
}
});
}
}
});
}
}

View File

@ -1 +0,0 @@
build/

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.davemorrissey.labs.subscaleview"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="14"/>
</manifest>

View File

@ -1,41 +0,0 @@
apply plugin: 'com.android.library'
group = 'com.davemorrissey.labs'
version = '3.4.1'
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile "com.android.support:support-annotations:23.1.1"
compile 'com.github.suckgamony.RapidDecoder:library:7cdfca4'
compile 'com.github.suckgamony.RapidDecoder:jpeg-decoder:7cdfca4'
compile 'com.github.suckgamony.RapidDecoder:png-decoder:7cdfca4'
}
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
// Move the tests to tests/java, tests/res, etc...
instrumentTest.setRoot('tests')
// Move the build types to build-types/<type>
// For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
// This moves them out of them default location under src/<type>/... which would
// conflict with src/ being used by the main source set.
// Adding new build types or product flavors should be accompanied
// by a similar customization.
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
}

View File

@ -1,15 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-19
android.library=true

View File

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2014 David Morrissey
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<declare-styleable name="SubsamplingScaleImageView">
<attr name="src" format="reference"/>
<attr name="assetName" format="string"/>
<attr name="panEnabled" format="boolean"/>
<attr name="zoomEnabled" format="boolean"/>
<attr name="quickScaleEnabled" format="boolean"/>
<attr name="tileBackgroundColor" format="color"/>
</declare-styleable>
</resources>

View File

@ -1,233 +0,0 @@
package com.davemorrissey.labs.subscaleview;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.net.Uri;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
/**
* Helper class used to set the source and additional attributes from a variety of sources. Supports
* use of a bitmap, asset, resource, external file or any other URI.
*
* When you are using a preview image, you must set the dimensions of the full size image on the
* ImageSource object for the full size image using the {@link #dimensions(int, int)} method.
*/
public final class ImageSource {
static final String FILE_SCHEME = "file:///";
static final String ASSET_SCHEME = "file:///android_asset/";
private final Uri uri;
private final Bitmap bitmap;
private final Integer resource;
private boolean tile;
private int sWidth;
private int sHeight;
private Rect sRegion;
private boolean cached;
private ImageSource(Bitmap bitmap, boolean cached) {
this.bitmap = bitmap;
this.uri = null;
this.resource = null;
this.tile = false;
this.sWidth = bitmap.getWidth();
this.sHeight = bitmap.getHeight();
this.cached = cached;
}
private ImageSource(Uri uri) {
// #114 If file doesn't exist, attempt to url decode the URI and try again
String uriString = uri.toString();
if (uriString.startsWith(FILE_SCHEME)) {
File uriFile = new File(uriString.substring(FILE_SCHEME.length() - 1));
if (!uriFile.exists()) {
try {
uri = Uri.parse(URLDecoder.decode(uriString, "UTF-8"));
} catch (UnsupportedEncodingException e) {
// Fallback to encoded URI. This exception is not expected.
}
}
}
this.bitmap = null;
this.uri = uri;
this.resource = null;
this.tile = true;
}
private ImageSource(int resource) {
this.bitmap = null;
this.uri = null;
this.resource = resource;
this.tile = true;
}
/**
* Create an instance from a resource. The correct resource for the device screen resolution will be used.
* @param resId resource ID.
*/
public static ImageSource resource(int resId) {
return new ImageSource(resId);
}
/**
* Create an instance from an asset name.
* @param assetName asset name.
*/
public static ImageSource asset(String assetName) {
if (assetName == null) {
throw new NullPointerException("Asset name must not be null");
}
return uri(ASSET_SCHEME + assetName);
}
/**
* Create an instance from a URI. If the URI does not start with a scheme, it's assumed to be the URI
* of a file.
* @param uri image URI.
*/
public static ImageSource uri(String uri) {
if (uri == null) {
throw new NullPointerException("Uri must not be null");
}
if (!uri.contains("://")) {
if (uri.startsWith("/")) {
uri = uri.substring(1);
}
uri = FILE_SCHEME + uri;
}
return new ImageSource(Uri.parse(uri));
}
/**
* Create an instance from a URI.
* @param uri image URI.
*/
public static ImageSource uri(Uri uri) {
if (uri == null) {
throw new NullPointerException("Uri must not be null");
}
return new ImageSource(uri);
}
/**
* Provide a loaded bitmap for display.
* @param bitmap bitmap to be displayed.
*/
public static ImageSource bitmap(Bitmap bitmap) {
if (bitmap == null) {
throw new NullPointerException("Bitmap must not be null");
}
return new ImageSource(bitmap, false);
}
/**
* Provide a loaded and cached bitmap for display. This bitmap will not be recycled when it is no
* longer needed. Use this method if you loaded the bitmap with an image loader such as Picasso
* or Volley.
* @param bitmap bitmap to be displayed.
*/
public static ImageSource cachedBitmap(Bitmap bitmap) {
if (bitmap == null) {
throw new NullPointerException("Bitmap must not be null");
}
return new ImageSource(bitmap, true);
}
/**
* Enable tiling of the image. This does not apply to preview images which are always loaded as a single bitmap.,
* and tiling cannot be disabled when displaying a region of the source image.
* @return this instance for chaining.
*/
public ImageSource tilingEnabled() {
return tiling(true);
}
/**
* Disable tiling of the image. This does not apply to preview images which are always loaded as a single bitmap,
* and tiling cannot be disabled when displaying a region of the source image.
* @return this instance for chaining.
*/
public ImageSource tilingDisabled() {
return tiling(false);
}
/**
* Enable or disable tiling of the image. This does not apply to preview images which are always loaded as a single bitmap,
* and tiling cannot be disabled when displaying a region of the source image.
* @return this instance for chaining.
*/
public ImageSource tiling(boolean tile) {
this.tile = tile;
return this;
}
/**
* Use a region of the source image. Region must be set independently for the full size image and the preview if
* you are using one.
* @return this instance for chaining.
*/
public ImageSource region(Rect sRegion) {
this.sRegion = sRegion;
setInvariants();
return this;
}
/**
* Declare the dimensions of the image. This is only required for a full size image, when you are specifying a URI
* and also a preview image. When displaying a bitmap object, or not using a preview, you do not need to declare
* the image dimensions. Note if the declared dimensions are found to be incorrect, the view will reset.
* @return this instance for chaining.
*/
public ImageSource dimensions(int sWidth, int sHeight) {
if (bitmap == null) {
this.sWidth = sWidth;
this.sHeight = sHeight;
}
setInvariants();
return this;
}
private void setInvariants() {
if (this.sRegion != null) {
this.tile = true;
this.sWidth = this.sRegion.width();
this.sHeight = this.sRegion.height();
}
}
protected final Uri getUri() {
return uri;
}
protected final Bitmap getBitmap() {
return bitmap;
}
protected final Integer getResource() {
return resource;
}
protected final boolean getTile() {
return tile;
}
protected final int getSWidth() {
return sWidth;
}
protected final int getSHeight() {
return sHeight;
}
protected final Rect getSRegion() {
return sRegion;
}
protected final boolean isCached() {
return cached;
}
}

View File

@ -1,55 +0,0 @@
/*
Copyright 2014 David Morrissey
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package com.davemorrissey.labs.subscaleview;
import android.graphics.PointF;
import java.io.Serializable;
/**
* Wraps the scale, center and orientation of a displayed image for easy restoration on screen rotate.
*/
public class ImageViewState implements Serializable {
private float scale;
private float centerX;
private float centerY;
private int orientation;
public ImageViewState(float scale, PointF center, int orientation) {
this.scale = scale;
this.centerX = center.x;
this.centerY = center.y;
this.orientation = orientation;
}
public float getScale() {
return scale;
}
public PointF getCenter() {
return new PointF(centerX, centerY);
}
public int getOrientation() {
return orientation;
}
}

View File

@ -1,20 +0,0 @@
package com.davemorrissey.labs.subscaleview.decoder;
import android.support.annotation.NonNull;
/**
* Compatibility factory to instantiate decoders with empty public constructors.
* @param <T> The base type of the decoder this factory will produce.
*/
public class CompatDecoderFactory <T> implements DecoderFactory<T> {
private Class<? extends T> clazz;
public CompatDecoderFactory(@NonNull Class<? extends T> clazz) {
this.clazz = clazz;
}
@Override
public T make() throws IllegalAccessException, InstantiationException {
return clazz.newInstance();
}
}

View File

@ -1,13 +0,0 @@
package com.davemorrissey.labs.subscaleview.decoder;
/**
* Interface for decoder (and region decoder) factories.
* @param <T> the class of decoder that will be produced.
*/
public interface DecoderFactory<T> {
/**
* Produce a new instance of a decoder with type {@link T}.
* @return a new instance of your decoder.
*/
T make() throws IllegalAccessException, InstantiationException;
}

View File

@ -1,28 +0,0 @@
package com.davemorrissey.labs.subscaleview.decoder;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.net.Uri;
/**
* Interface for image decoding classes, allowing the default {@link android.graphics.BitmapRegionDecoder}
* based on the Skia library to be replaced with a custom class.
*/
public interface ImageDecoder {
/**
* Decode an image. When possible, initial setup work once in this method. This method
* must return the dimensions of the image. The URI can be in one of the following formats:
* File: file:///scard/picture.jpg
* Asset: file:///android_asset/picture.png
* Resource: android.resource://com.example.app/drawable/picture
* @param context Application context. A reference may be held, but must be cleared on recycle.
* @param uri URI of the image.
* @return Dimensions of the image.
* @throws Exception if initialisation fails.
*/
Bitmap decode(Context context, Uri uri) throws Exception;
}

View File

@ -1,50 +0,0 @@
package com.davemorrissey.labs.subscaleview.decoder;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.net.Uri;
/**
* Interface for image decoding classes, allowing the default {@link android.graphics.BitmapRegionDecoder}
* based on the Skia library to be replaced with a custom class.
*/
public interface ImageRegionDecoder {
/**
* Initialise the decoder. When possible, initial setup work once in this method. This method
* must return the dimensions of the image. The URI can be in one of the following formats:
* File: file:///scard/picture.jpg
* Asset: file:///android_asset/picture.png
* Resource: android.resource://com.example.app/drawable/picture
* @param context Application context. A reference may be held, but must be cleared on recycle.
* @param uri URI of the image.
* @return Dimensions of the image.
* @throws Exception if initialisation fails.
*/
Point init(Context context, Uri uri) throws Exception;
/**
* Decode a region of the image with the given sample size. This method is called off the UI thread so it can safely
* load the image on the current thread. It is called from an {@link android.os.AsyncTask} running in a single
* threaded executor, and while a synchronization lock is held on this object, so will never be called concurrently
* even if the decoder implementation supports it.
* @param sRect Source image rectangle to decode.
* @param sampleSize Sample size.
* @return The decoded region. It is safe to return null if decoding fails.
*/
Bitmap decodeRegion(Rect sRect, int sampleSize);
/**
* Status check. Should return false before initialisation and after recycle.
* @return true if the decoder is ready to be used.
*/
boolean isReady();
/**
* This method will be called when the decoder is no longer required. It should clean up any resources still in use.
*/
void recycle();
}

View File

@ -1,24 +0,0 @@
package com.davemorrissey.labs.subscaleview.decoder;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import rapid.decoder.BitmapDecoder;
/**
* A very simple implementation of {@link com.davemorrissey.labs.subscaleview.decoder.ImageRegionDecoder}
* using the RapidDecoder library (https://github.com/suckgamony/RapidDecoder). For PNGs, this can
* give more reliable decoding and better performance. For JPGs, it is slower and can run out of
* memory with large images, but has better support for grayscale and CMYK images.
*
* This is an incomplete and untested implementation provided as an example only.
*/
public class RapidImageDecoder implements ImageDecoder {
@Override
public Bitmap decode(Context context, Uri uri) throws Exception {
return BitmapDecoder.from(context, uri).useBuiltInDecoder(true).config(Bitmap.Config.RGB_565).decode();
}
}

View File

@ -1,55 +0,0 @@
package com.davemorrissey.labs.subscaleview.decoder;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.net.Uri;
import rapid.decoder.BitmapDecoder;
/**
* A very simple implementation of {@link com.davemorrissey.labs.subscaleview.decoder.ImageRegionDecoder}
* using the RapidDecoder library (https://github.com/suckgamony/RapidDecoder). For PNGs, this can
* give more reliable decoding and better performance. For JPGs, it is slower and can run out of
* memory with large images, but has better support for grayscale and CMYK images.
*
* This is an incomplete and untested implementation provided as an example only.
*/
public class RapidImageRegionDecoder implements ImageRegionDecoder {
private BitmapDecoder decoder;
@Override
public Point init(Context context, Uri uri) throws Exception {
decoder = BitmapDecoder.from(context, uri);
decoder.useBuiltInDecoder(true);
int width = decoder.sourceWidth();
int height = decoder.sourceHeight();
if (width == 0 || height == 0)
throw new Exception("Rapid image decoder returned empty image - image format may not be supported");
return new Point(width, height);
}
@Override
public synchronized Bitmap decodeRegion(Rect sRect, int sampleSize) {
try {
return decoder.reset().region(sRect).scale(sRect.width() / sampleSize, sRect.height() / sampleSize).decode();
} catch (Exception e) {
throw new RuntimeException("Rapid image decoder returned null bitmap - image format may not be supported");
}
}
@Override
public boolean isReady() {
return decoder != null;
}
@Override
public void recycle() {
BitmapDecoder.destroyMemoryCache();
BitmapDecoder.destroyDiskCache();
decoder.reset();
decoder = null;
}
}

View File

@ -1,79 +0,0 @@
package com.davemorrissey.labs.subscaleview.decoder;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.text.TextUtils;
import java.io.InputStream;
import java.util.List;
/**
* Default implementation of {@link com.davemorrissey.labs.subscaleview.decoder.ImageDecoder}
* using Android's {@link android.graphics.BitmapFactory}, based on the Skia library. This
* works well in most circumstances and has reasonable performance, however it has some problems
* with grayscale, indexed and CMYK images.
*/
public class SkiaImageDecoder implements ImageDecoder {
private static final String FILE_PREFIX = "file://";
private static final String ASSET_PREFIX = FILE_PREFIX + "/android_asset/";
private static final String RESOURCE_PREFIX = ContentResolver.SCHEME_ANDROID_RESOURCE + "://";
@Override
public Bitmap decode(Context context, Uri uri) throws Exception {
String uriString = uri.toString();
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bitmap;
options.inPreferredConfig = Bitmap.Config.RGB_565;
if (uriString.startsWith(RESOURCE_PREFIX)) {
Resources res;
String packageName = uri.getAuthority();
if (context.getPackageName().equals(packageName)) {
res = context.getResources();
} else {
PackageManager pm = context.getPackageManager();
res = pm.getResourcesForApplication(packageName);
}
int id = 0;
List<String> segments = uri.getPathSegments();
int size = segments.size();
if (size == 2 && segments.get(0).equals("drawable")) {
String resName = segments.get(1);
id = res.getIdentifier(resName, "drawable", packageName);
} else if (size == 1 && TextUtils.isDigitsOnly(segments.get(0))) {
try {
id = Integer.parseInt(segments.get(0));
} catch (NumberFormatException ignored) {
}
}
bitmap = BitmapFactory.decodeResource(context.getResources(), id, options);
} else if (uriString.startsWith(ASSET_PREFIX)) {
String assetName = uriString.substring(ASSET_PREFIX.length());
bitmap = BitmapFactory.decodeStream(context.getAssets().open(assetName), null, options);
} else if (uriString.startsWith(FILE_PREFIX)) {
bitmap = BitmapFactory.decodeFile(uriString.substring(FILE_PREFIX.length()), options);
} else {
InputStream inputStream = null;
try {
ContentResolver contentResolver = context.getContentResolver();
inputStream = contentResolver.openInputStream(uri);
bitmap = BitmapFactory.decodeStream(inputStream, null, options);
} finally {
if (inputStream != null) {
try { inputStream.close(); } catch (Exception e) { }
}
}
}
if (bitmap == null) {
throw new RuntimeException("Skia image region decoder returned null bitmap - image format may not be supported");
}
return bitmap;
}
}

View File

@ -1,101 +0,0 @@
package com.davemorrissey.labs.subscaleview.decoder;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.*;
import android.graphics.Bitmap.Config;
import android.net.Uri;
import android.text.TextUtils;
import java.io.InputStream;
import java.util.List;
/**
* Default implementation of {@link com.davemorrissey.labs.subscaleview.decoder.ImageRegionDecoder}
* using Android's {@link android.graphics.BitmapRegionDecoder}, based on the Skia library. This
* works well in most circumstances and has reasonable performance due to the cached decoder instance,
* however it has some problems with grayscale, indexed and CMYK images.
*/
public class SkiaImageRegionDecoder implements ImageRegionDecoder {
private BitmapRegionDecoder decoder;
private final Object decoderLock = new Object();
private static final String FILE_PREFIX = "file://";
private static final String ASSET_PREFIX = FILE_PREFIX + "/android_asset/";
private static final String RESOURCE_PREFIX = ContentResolver.SCHEME_ANDROID_RESOURCE + "://";
@Override
public Point init(Context context, Uri uri) throws Exception {
String uriString = uri.toString();
if (uriString.startsWith(RESOURCE_PREFIX)) {
Resources res;
String packageName = uri.getAuthority();
if (context.getPackageName().equals(packageName)) {
res = context.getResources();
} else {
PackageManager pm = context.getPackageManager();
res = pm.getResourcesForApplication(packageName);
}
int id = 0;
List<String> segments = uri.getPathSegments();
int size = segments.size();
if (size == 2 && segments.get(0).equals("drawable")) {
String resName = segments.get(1);
id = res.getIdentifier(resName, "drawable", packageName);
} else if (size == 1 && TextUtils.isDigitsOnly(segments.get(0))) {
try {
id = Integer.parseInt(segments.get(0));
} catch (NumberFormatException ignored) {
}
}
decoder = BitmapRegionDecoder.newInstance(context.getResources().openRawResource(id), false);
} else if (uriString.startsWith(ASSET_PREFIX)) {
String assetName = uriString.substring(ASSET_PREFIX.length());
decoder = BitmapRegionDecoder.newInstance(context.getAssets().open(assetName, AssetManager.ACCESS_RANDOM), false);
} else if (uriString.startsWith(FILE_PREFIX)) {
decoder = BitmapRegionDecoder.newInstance(uriString.substring(FILE_PREFIX.length()), false);
} else {
InputStream inputStream = null;
try {
ContentResolver contentResolver = context.getContentResolver();
inputStream = contentResolver.openInputStream(uri);
decoder = BitmapRegionDecoder.newInstance(inputStream, false);
} finally {
if (inputStream != null) {
try { inputStream.close(); } catch (Exception e) { }
}
}
}
return new Point(decoder.getWidth(), decoder.getHeight());
}
@Override
public Bitmap decodeRegion(Rect sRect, int sampleSize) {
synchronized (decoderLock) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = sampleSize;
options.inPreferredConfig = Config.RGB_565;
Bitmap bitmap = decoder.decodeRegion(sRect, options);
if (bitmap == null) {
throw new RuntimeException("Skia image decoder returned null bitmap - image format may not be supported");
}
return bitmap;
}
}
@Override
public boolean isReady() {
return decoder != null && !decoder.isRecycled();
}
@Override
public void recycle() {
decoder.recycle();
}
}

View File

@ -1,2 +1 @@
include ':app', ':SubsamplingScaleImageView'
project(':SubsamplingScaleImageView').projectDir = new File('libs/SubsamplingScaleImageView')
include ':app'