├── .gitignore
├── ABOUT.txt
├── Application
├── build.gradle
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── android
│ │ │ ├── common
│ │ │ └── logger
│ │ │ │ ├── Log.java
│ │ │ │ ├── LogFragment.java
│ │ │ │ ├── LogNode.java
│ │ │ │ ├── LogView.java
│ │ │ │ ├── LogWrapper.java
│ │ │ │ └── MessageOnlyLogFilter.java
│ │ │ └── displayingbitmaps
│ │ │ ├── provider
│ │ │ └── Images.java
│ │ │ ├── ui
│ │ │ ├── ImageDetailActivity.java
│ │ │ ├── ImageDetailFragment.java
│ │ │ ├── ImageGridActivity.java
│ │ │ ├── ImageGridFragment.java
│ │ │ └── RecyclingImageView.java
│ │ │ └── util
│ │ │ ├── AsyncTask.java
│ │ │ ├── DiskLruCache.java
│ │ │ ├── ImageCache.java
│ │ │ ├── ImageFetcher.java
│ │ │ ├── ImageResizer.java
│ │ │ ├── ImageWorker.java
│ │ │ ├── RecyclingBitmapDrawable.java
│ │ │ └── Utils.java
│ │ └── res
│ │ ├── drawable-hdpi
│ │ ├── ic_launcher.png
│ │ └── tile.9.png
│ │ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ │ ├── drawable-nodpi
│ │ └── empty_photo.png
│ │ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ │ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── drawable
│ │ └── photogrid_list_selector.xml
│ │ ├── layout
│ │ ├── image_detail_fragment.xml
│ │ ├── image_detail_pager.xml
│ │ └── image_grid_fragment.xml
│ │ ├── menu
│ │ └── main_menu.xml
│ │ ├── values-large
│ │ └── dimens.xml
│ │ ├── values-sw600dp
│ │ ├── template-dimens.xml
│ │ └── template-styles.xml
│ │ ├── values-v11
│ │ ├── styles.xml
│ │ └── template-styles.xml
│ │ ├── values-v21
│ │ ├── base-colors.xml
│ │ └── base-template-styles.xml
│ │ ├── values-xlarge
│ │ └── dimens.xml
│ │ └── values
│ │ ├── base-strings.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ ├── styles.xml
│ │ ├── template-dimens.xml
│ │ └── template-styles.xml
└── tests
│ ├── AndroidManifest.xml
│ └── src
│ └── com
│ └── example
│ └── android
│ └── displayingbitmaps
│ └── tests
│ └── SampleTests.java
├── CONTRIB.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── packaging.yaml
└── settings.gradle
/.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 |
28 | # Android Studio Navigation editor temp files
29 | .navigation/
30 |
31 | # Android Studio captures folder
32 | captures/
33 |
34 | .idea/
35 | *.iml
36 | **/*.iml
37 |
--------------------------------------------------------------------------------
/ABOUT.txt:
--------------------------------------------------------------------------------
1 | Copyright (C) 2014 The Android Open Source Project
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
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 |
17 | This is a sample application for the Android Training class "Displaying Bitmaps
18 | Efficiently" (http://developer.android.com/training/displaying-bitmaps/).
19 |
20 | It demonstrates how to load large bitmaps efficiently off the main UI thread,
21 | caching bitmaps (both in memory and on disk), managing bitmap memory and
22 | displaying bitmaps in UI elements such as ViewPager and ListView/GridView.
--------------------------------------------------------------------------------
/Application/build.gradle:
--------------------------------------------------------------------------------
1 |
2 | buildscript {
3 | repositories {
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.0.0-alpha3'
9 | }
10 | }
11 |
12 | apply plugin: 'com.android.application'
13 |
14 | repositories {
15 | jcenter()
16 | mavenLocal()
17 | }
18 |
19 | dependencies {
20 | compile "com.android.support:support-v4:23.1.1"
21 | compile "com.android.support:gridlayout-v7:23.1.1"
22 | compile "com.android.support:cardview-v7:23.1.1"
23 | compile("org.deeplearning4j:deeplearning4j-core:0.4-rc3.8"){
24 | exclude group: "ch.qos.logback", module: "logback-core"
25 | exclude group: "ch.qos.logback", module: "logback-classic"
26 | }
27 | compile("org.nd4j:nd4j-x86:0.4-rc3.9-SNAPSHOT"){
28 | exclude group: "ch.qos.logback", module: "logback-core"
29 | exclude group: "ch.qos.logback", module: "logback-classic"
30 | }
31 | compile 'com.github.tony19:logback-android-core:1.1.1-4'
32 | compile 'com.github.tony19:logback-android-classic:1.1.1-4'
33 | }
34 |
35 | android {
36 | compileSdkVersion 23
37 | buildToolsVersion "23.0.2"
38 |
39 | defaultConfig {
40 | minSdkVersion 9
41 | targetSdkVersion 23
42 | versionCode 1
43 | versionName "0.1-SNAPSHOT"
44 | multiDexEnabled true
45 | }
46 |
47 | compileOptions {
48 | sourceCompatibility JavaVersion.VERSION_1_7
49 | targetCompatibility JavaVersion.VERSION_1_7
50 | }
51 |
52 | sourceSets {
53 | androidTest.setRoot('tests')
54 | androidTest.java.srcDirs = ['tests/src']
55 |
56 | }
57 |
58 | dexOptions {
59 | incremental true
60 | javaMaxHeapSize "2048M"
61 | }
62 | packagingOptions {
63 | exclude 'META-INF/DEPENDENCIES.txt'
64 | exclude 'META-INF/LICENSE'
65 | exclude 'META-INF/LICENSE.txt'
66 | exclude 'META-INF/license.txt'
67 | exclude 'META-INF/NOTICE'
68 | exclude 'META-INF/NOTICE.txt'
69 | exclude 'META-INF/notice.txt'
70 | exclude 'META-INF/DEPENDENCIES'
71 | exclude 'META-INF/io.netty.versions.properties'
72 | exclude 'META-INF/INDEX.LIST'
73 | exclude 'META-INF/services/javax.imageio.spi.ImageReaderSpi'
74 | exclude 'META-INF/services/javax.imageio.spi.ImageWriterSpi'
75 | exclude 'META-INF/services/com.fasterxml.jackson.core.JsonFactory'
76 | }
77 |
78 | }
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/Application/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
When this is set as the head of the list, 22 | * an instance of it can function as a drop-in replacement for {@link android.util.Log}. 23 | * Most of the methods in this class server only to map a method call in Log to its equivalent 24 | * in LogNode.
25 | */ 26 | public class Log { 27 | // Grabbing the native values from Android's native logging facilities, 28 | // to make for easy migration and interop. 29 | public static final int NONE = -1; 30 | public static final int VERBOSE = android.util.Log.VERBOSE; 31 | public static final int DEBUG = android.util.Log.DEBUG; 32 | public static final int INFO = android.util.Log.INFO; 33 | public static final int WARN = android.util.Log.WARN; 34 | public static final int ERROR = android.util.Log.ERROR; 35 | public static final int ASSERT = android.util.Log.ASSERT; 36 | 37 | // Stores the beginning of the LogNode topology. 38 | private static LogNode mLogNode; 39 | 40 | /** 41 | * Returns the next LogNode in the linked list. 42 | */ 43 | public static LogNode getLogNode() { 44 | return mLogNode; 45 | } 46 | 47 | /** 48 | * Sets the LogNode data will be sent to. 49 | */ 50 | public static void setLogNode(LogNode node) { 51 | mLogNode = node; 52 | } 53 | 54 | /** 55 | * Instructs the LogNode to print the log data provided. Other LogNodes can 56 | * be chained to the end of the LogNode as desired. 57 | * 58 | * @param priority Log level of the data being logged. Verbose, Error, etc. 59 | * @param tag Tag for for the log data. Can be used to organize log statements. 60 | * @param msg The actual message to be logged. 61 | * @param tr If an exception was thrown, this can be sent along for the logging facilities 62 | * to extract and print useful information. 63 | */ 64 | public static void println(int priority, String tag, String msg, Throwable tr) { 65 | if (mLogNode != null) { 66 | mLogNode.println(priority, tag, msg, tr); 67 | } 68 | } 69 | 70 | /** 71 | * Instructs the LogNode to print the log data provided. Other LogNodes can 72 | * be chained to the end of the LogNode as desired. 73 | * 74 | * @param priority Log level of the data being logged. Verbose, Error, etc. 75 | * @param tag Tag for for the log data. Can be used to organize log statements. 76 | * @param msg The actual message to be logged. The actual message to be logged. 77 | */ 78 | public static void println(int priority, String tag, String msg) { 79 | println(priority, tag, msg, null); 80 | } 81 | 82 | /** 83 | * Prints a message at VERBOSE priority. 84 | * 85 | * @param tag Tag for for the log data. Can be used to organize log statements. 86 | * @param msg The actual message to be logged. 87 | * @param tr If an exception was thrown, this can be sent along for the logging facilities 88 | * to extract and print useful information. 89 | */ 90 | public static void v(String tag, String msg, Throwable tr) { 91 | println(VERBOSE, tag, msg, tr); 92 | } 93 | 94 | /** 95 | * Prints a message at VERBOSE priority. 96 | * 97 | * @param tag Tag for for the log data. Can be used to organize log statements. 98 | * @param msg The actual message to be logged. 99 | */ 100 | public static void v(String tag, String msg) { 101 | v(tag, msg, null); 102 | } 103 | 104 | 105 | /** 106 | * Prints a message at DEBUG priority. 107 | * 108 | * @param tag Tag for for the log data. Can be used to organize log statements. 109 | * @param msg The actual message to be logged. 110 | * @param tr If an exception was thrown, this can be sent along for the logging facilities 111 | * to extract and print useful information. 112 | */ 113 | public static void d(String tag, String msg, Throwable tr) { 114 | println(DEBUG, tag, msg, tr); 115 | } 116 | 117 | /** 118 | * Prints a message at DEBUG priority. 119 | * 120 | * @param tag Tag for for the log data. Can be used to organize log statements. 121 | * @param msg The actual message to be logged. 122 | */ 123 | public static void d(String tag, String msg) { 124 | d(tag, msg, null); 125 | } 126 | 127 | /** 128 | * Prints a message at INFO priority. 129 | * 130 | * @param tag Tag for for the log data. Can be used to organize log statements. 131 | * @param msg The actual message to be logged. 132 | * @param tr If an exception was thrown, this can be sent along for the logging facilities 133 | * to extract and print useful information. 134 | */ 135 | public static void i(String tag, String msg, Throwable tr) { 136 | println(INFO, tag, msg, tr); 137 | } 138 | 139 | /** 140 | * Prints a message at INFO priority. 141 | * 142 | * @param tag Tag for for the log data. Can be used to organize log statements. 143 | * @param msg The actual message to be logged. 144 | */ 145 | public static void i(String tag, String msg) { 146 | i(tag, msg, null); 147 | } 148 | 149 | /** 150 | * Prints a message at WARN priority. 151 | * 152 | * @param tag Tag for for the log data. Can be used to organize log statements. 153 | * @param msg The actual message to be logged. 154 | * @param tr If an exception was thrown, this can be sent along for the logging facilities 155 | * to extract and print useful information. 156 | */ 157 | public static void w(String tag, String msg, Throwable tr) { 158 | println(WARN, tag, msg, tr); 159 | } 160 | 161 | /** 162 | * Prints a message at WARN priority. 163 | * 164 | * @param tag Tag for for the log data. Can be used to organize log statements. 165 | * @param msg The actual message to be logged. 166 | */ 167 | public static void w(String tag, String msg) { 168 | w(tag, msg, null); 169 | } 170 | 171 | /** 172 | * Prints a message at WARN priority. 173 | * 174 | * @param tag Tag for for the log data. Can be used to organize log statements. 175 | * @param tr If an exception was thrown, this can be sent along for the logging facilities 176 | * to extract and print useful information. 177 | */ 178 | public static void w(String tag, Throwable tr) { 179 | w(tag, null, tr); 180 | } 181 | 182 | /** 183 | * Prints a message at ERROR priority. 184 | * 185 | * @param tag Tag for for the log data. Can be used to organize log statements. 186 | * @param msg The actual message to be logged. 187 | * @param tr If an exception was thrown, this can be sent along for the logging facilities 188 | * to extract and print useful information. 189 | */ 190 | public static void e(String tag, String msg, Throwable tr) { 191 | println(ERROR, tag, msg, tr); 192 | } 193 | 194 | /** 195 | * Prints a message at ERROR priority. 196 | * 197 | * @param tag Tag for for the log data. Can be used to organize log statements. 198 | * @param msg The actual message to be logged. 199 | */ 200 | public static void e(String tag, String msg) { 201 | e(tag, msg, null); 202 | } 203 | 204 | /** 205 | * Prints a message at ASSERT priority. 206 | * 207 | * @param tag Tag for for the log data. Can be used to organize log statements. 208 | * @param msg The actual message to be logged. 209 | * @param tr If an exception was thrown, this can be sent along for the logging facilities 210 | * to extract and print useful information. 211 | */ 212 | public static void wtf(String tag, String msg, Throwable tr) { 213 | println(ASSERT, tag, msg, tr); 214 | } 215 | 216 | /** 217 | * Prints a message at ASSERT priority. 218 | * 219 | * @param tag Tag for for the log data. Can be used to organize log statements. 220 | * @param msg The actual message to be logged. 221 | */ 222 | public static void wtf(String tag, String msg) { 223 | wtf(tag, msg, null); 224 | } 225 | 226 | /** 227 | * Prints a message at ASSERT priority. 228 | * 229 | * @param tag Tag for for the log data. Can be used to organize log statements. 230 | * @param tr If an exception was thrown, this can be sent along for the logging facilities 231 | * to extract and print useful information. 232 | */ 233 | public static void wtf(String tag, Throwable tr) { 234 | wtf(tag, null, tr); 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /Application/src/main/java/com/example/android/common/logger/LogFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 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 | * Copyright 2013 The Android Open Source Project 18 | * 19 | * Licensed under the Apache License, Version 2.0 (the "License"); 20 | * you may not use this file except in compliance with the License. 21 | * You may obtain a copy of the License at 22 | * 23 | * http://www.apache.org/licenses/LICENSE-2.0 24 | * 25 | * Unless required by applicable law or agreed to in writing, software 26 | * distributed under the License is distributed on an "AS IS" BASIS, 27 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 | * See the License for the specific language governing permissions and 29 | * limitations under the License. 30 | */ 31 | 32 | package com.example.android.common.logger; 33 | 34 | import android.graphics.Typeface; 35 | import android.os.Bundle; 36 | import android.support.v4.app.Fragment; 37 | import android.text.Editable; 38 | import android.text.TextWatcher; 39 | import android.view.Gravity; 40 | import android.view.LayoutInflater; 41 | import android.view.View; 42 | import android.view.ViewGroup; 43 | import android.widget.ScrollView; 44 | 45 | /** 46 | * Simple fraggment which contains a LogView and uses is to output log data it receives 47 | * through the LogNode interface. 48 | */ 49 | public class LogFragment extends Fragment { 50 | 51 | private LogView mLogView; 52 | private ScrollView mScrollView; 53 | 54 | public LogFragment() {} 55 | 56 | public View inflateViews() { 57 | mScrollView = new ScrollView(getActivity()); 58 | ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams( 59 | ViewGroup.LayoutParams.MATCH_PARENT, 60 | ViewGroup.LayoutParams.MATCH_PARENT); 61 | mScrollView.setLayoutParams(scrollParams); 62 | 63 | mLogView = new LogView(getActivity()); 64 | ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams); 65 | logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; 66 | mLogView.setLayoutParams(logParams); 67 | mLogView.setClickable(true); 68 | mLogView.setFocusable(true); 69 | mLogView.setTypeface(Typeface.MONOSPACE); 70 | 71 | // Want to set padding as 16 dips, setPadding takes pixels. Hooray math! 72 | int paddingDips = 16; 73 | double scale = getResources().getDisplayMetrics().density; 74 | int paddingPixels = (int) ((paddingDips * (scale)) + .5); 75 | mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels); 76 | mLogView.setCompoundDrawablePadding(paddingPixels); 77 | 78 | mLogView.setGravity(Gravity.BOTTOM); 79 | mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium); 80 | 81 | mScrollView.addView(mLogView); 82 | return mScrollView; 83 | } 84 | 85 | @Override 86 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 87 | Bundle savedInstanceState) { 88 | 89 | View result = inflateViews(); 90 | 91 | mLogView.addTextChangedListener(new TextWatcher() { 92 | @Override 93 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {} 94 | 95 | @Override 96 | public void onTextChanged(CharSequence s, int start, int before, int count) {} 97 | 98 | @Override 99 | public void afterTextChanged(Editable s) { 100 | mScrollView.fullScroll(ScrollView.FOCUS_DOWN); 101 | } 102 | }); 103 | return result; 104 | } 105 | 106 | public LogView getLogView() { 107 | return mLogView; 108 | } 109 | } -------------------------------------------------------------------------------- /Application/src/main/java/com/example/android/common/logger/LogNode.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 | package com.example.android.common.logger; 17 | 18 | /** 19 | * Basic interface for a logging system that can output to one or more targets. 20 | * Note that in addition to classes that will output these logs in some format, 21 | * one can also implement this interface over a filter and insert that in the chain, 22 | * such that no targets further down see certain data, or see manipulated forms of the data. 23 | * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data 24 | * it received to HTML and sent it along to the next node in the chain, without printing it 25 | * anywhere. 26 | */ 27 | public interface LogNode { 28 | 29 | /** 30 | * Instructs first LogNode in the list to print the log data provided. 31 | * @param priority Log level of the data being logged. Verbose, Error, etc. 32 | * @param tag Tag for for the log data. Can be used to organize log statements. 33 | * @param msg The actual message to be logged. The actual message to be logged. 34 | * @param tr If an exception was thrown, this can be sent along for the logging facilities 35 | * to extract and print useful information. 36 | */ 37 | public void println(int priority, String tag, String msg, Throwable tr); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Application/src/main/java/com/example/android/common/logger/LogView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 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 | package com.example.android.common.logger; 17 | 18 | import android.app.Activity; 19 | import android.content.Context; 20 | import android.util.*; 21 | import android.widget.TextView; 22 | 23 | /** Simple TextView which is used to output log data received through the LogNode interface. 24 | */ 25 | public class LogView extends TextView implements LogNode { 26 | 27 | public LogView(Context context) { 28 | super(context); 29 | } 30 | 31 | public LogView(Context context, AttributeSet attrs) { 32 | super(context, attrs); 33 | } 34 | 35 | public LogView(Context context, AttributeSet attrs, int defStyle) { 36 | super(context, attrs, defStyle); 37 | } 38 | 39 | /** 40 | * Formats the log data and prints it out to the LogView. 41 | * @param priority Log level of the data being logged. Verbose, Error, etc. 42 | * @param tag Tag for for the log data. Can be used to organize log statements. 43 | * @param msg The actual message to be logged. The actual message to be logged. 44 | * @param tr If an exception was thrown, this can be sent along for the logging facilities 45 | * to extract and print useful information. 46 | */ 47 | @Override 48 | public void println(int priority, String tag, String msg, Throwable tr) { 49 | 50 | 51 | String priorityStr = null; 52 | 53 | // For the purposes of this View, we want to print the priority as readable text. 54 | switch(priority) { 55 | case android.util.Log.VERBOSE: 56 | priorityStr = "VERBOSE"; 57 | break; 58 | case android.util.Log.DEBUG: 59 | priorityStr = "DEBUG"; 60 | break; 61 | case android.util.Log.INFO: 62 | priorityStr = "INFO"; 63 | break; 64 | case android.util.Log.WARN: 65 | priorityStr = "WARN"; 66 | break; 67 | case android.util.Log.ERROR: 68 | priorityStr = "ERROR"; 69 | break; 70 | case android.util.Log.ASSERT: 71 | priorityStr = "ASSERT"; 72 | break; 73 | default: 74 | break; 75 | } 76 | 77 | // Handily, the Log class has a facility for converting a stack trace into a usable string. 78 | String exceptionStr = null; 79 | if (tr != null) { 80 | exceptionStr = android.util.Log.getStackTraceString(tr); 81 | } 82 | 83 | // Take the priority, tag, message, and exception, and concatenate as necessary 84 | // into one usable line of text. 85 | final StringBuilder outputBuilder = new StringBuilder(); 86 | 87 | String delimiter = "\t"; 88 | appendIfNotNull(outputBuilder, priorityStr, delimiter); 89 | appendIfNotNull(outputBuilder, tag, delimiter); 90 | appendIfNotNull(outputBuilder, msg, delimiter); 91 | appendIfNotNull(outputBuilder, exceptionStr, delimiter); 92 | 93 | // In case this was originally called from an AsyncTask or some other off-UI thread, 94 | // make sure the update occurs within the UI thread. 95 | ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() { 96 | @Override 97 | public void run() { 98 | // Display the text we just generated within the LogView. 99 | appendToLog(outputBuilder.toString()); 100 | } 101 | }))); 102 | 103 | if (mNext != null) { 104 | mNext.println(priority, tag, msg, tr); 105 | } 106 | } 107 | 108 | public LogNode getNext() { 109 | return mNext; 110 | } 111 | 112 | public void setNext(LogNode node) { 113 | mNext = node; 114 | } 115 | 116 | /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since 117 | * the logger takes so many arguments that might be null, this method helps cut out some of the 118 | * agonizing tedium of writing the same 3 lines over and over. 119 | * @param source StringBuilder containing the text to append to. 120 | * @param addStr The String to append 121 | * @param delimiter The String to separate the source and appended strings. A tab or comma, 122 | * for instance. 123 | * @return The fully concatenated String as a StringBuilder 124 | */ 125 | private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) { 126 | if (addStr != null) { 127 | if (addStr.length() == 0) { 128 | delimiter = ""; 129 | } 130 | 131 | return source.append(addStr).append(delimiter); 132 | } 133 | return source; 134 | } 135 | 136 | // The next LogNode in the chain. 137 | LogNode mNext; 138 | 139 | /** Outputs the string as a new line of log data in the LogView. */ 140 | public void appendToLog(String s) { 141 | append("\n" + s); 142 | } 143 | 144 | 145 | } 146 | -------------------------------------------------------------------------------- /Application/src/main/java/com/example/android/common/logger/LogWrapper.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 | package com.example.android.common.logger; 17 | 18 | import android.util.Log; 19 | 20 | /** 21 | * Helper class which wraps Android's native Log utility in the Logger interface. This way 22 | * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously. 23 | */ 24 | public class LogWrapper implements LogNode { 25 | 26 | // For piping: The next node to receive Log data after this one has done its work. 27 | private LogNode mNext; 28 | 29 | /** 30 | * Returns the next LogNode in the linked list. 31 | */ 32 | public LogNode getNext() { 33 | return mNext; 34 | } 35 | 36 | /** 37 | * Sets the LogNode data will be sent to.. 38 | */ 39 | public void setNext(LogNode node) { 40 | mNext = node; 41 | } 42 | 43 | /** 44 | * Prints data out to the console using Android's native log mechanism. 45 | * @param priority Log level of the data being logged. Verbose, Error, etc. 46 | * @param tag Tag for for the log data. Can be used to organize log statements. 47 | * @param msg The actual message to be logged. The actual message to be logged. 48 | * @param tr If an exception was thrown, this can be sent along for the logging facilities 49 | * to extract and print useful information. 50 | */ 51 | @Override 52 | public void println(int priority, String tag, String msg, Throwable tr) { 53 | // There actually are log methods that don't take a msg parameter. For now, 54 | // if that's the case, just convert null to the empty string and move on. 55 | String useMsg = msg; 56 | if (useMsg == null) { 57 | useMsg = ""; 58 | } 59 | 60 | // If an exeption was provided, convert that exception to a usable string and attach 61 | // it to the end of the msg method. 62 | if (tr != null) { 63 | msg += "\n" + Log.getStackTraceString(tr); 64 | } 65 | 66 | // This is functionally identical to Log.x(tag, useMsg); 67 | // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg) 68 | Log.println(priority, tag, useMsg); 69 | 70 | // If this isn't the last node in the chain, move things along. 71 | if (mNext != null) { 72 | mNext.println(priority, tag, msg, tr); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Application/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 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 | package com.example.android.common.logger; 17 | 18 | /** 19 | * Simple {@link LogNode} filter, removes everything except the message. 20 | * Useful for situations like on-screen log output where you don't want a lot of metadata displayed, 21 | * just easy-to-read message updates as they're happening. 22 | */ 23 | public class MessageOnlyLogFilter implements LogNode { 24 | 25 | LogNode mNext; 26 | 27 | /** 28 | * Takes the "next" LogNode as a parameter, to simplify chaining. 29 | * 30 | * @param next The next LogNode in the pipeline. 31 | */ 32 | public MessageOnlyLogFilter(LogNode next) { 33 | mNext = next; 34 | } 35 | 36 | public MessageOnlyLogFilter() { 37 | } 38 | 39 | @Override 40 | public void println(int priority, String tag, String msg, Throwable tr) { 41 | if (mNext != null) { 42 | getNext().println(Log.NONE, null, msg, null); 43 | } 44 | } 45 | 46 | /** 47 | * Returns the next LogNode in the chain. 48 | */ 49 | public LogNode getNext() { 50 | return mNext; 51 | } 52 | 53 | /** 54 | * Sets the LogNode data will be sent to.. 55 | */ 56 | public void setNext(LogNode node) { 57 | mNext = node; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /Application/src/main/java/com/example/android/displayingbitmaps/provider/Images.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.example.android.displayingbitmaps.provider; 18 | 19 | /** 20 | * Some simple test data to use for this sample app. 21 | */ 22 | public class Images { 23 | 24 | /** 25 | * This are PicasaWeb URLs and could potentially change. Ideally the PicasaWeb API should be 26 | * used to fetch the URLs. 27 | * 28 | * Credit to Romain Guy for the photos: 29 | * http://www.curious-creature.org/ 30 | * https://plus.google.com/109538161516040592207/about 31 | * http://www.flickr.com/photos/romainguy 32 | */ 33 | public final static String[] imageUrls = new String[] { 34 | "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s1024/A%252520Photographer.jpg", 35 | "https://lh4.googleusercontent.com/--dq8niRp7W4/URquVgmXvgI/AAAAAAAAAbs/-gnuLQfNnBA/s1024/A%252520Song%252520of%252520Ice%252520and%252520Fire.jpg", 36 | "https://lh5.googleusercontent.com/-7qZeDtRKFKc/URquWZT1gOI/AAAAAAAAAbs/hqWgteyNXsg/s1024/Another%252520Rockaway%252520Sunset.jpg", 37 | "https://lh3.googleusercontent.com/--L0Km39l5J8/URquXHGcdNI/AAAAAAAAAbs/3ZrSJNrSomQ/s1024/Antelope%252520Butte.jpg", 38 | "https://lh6.googleusercontent.com/-8HO-4vIFnlw/URquZnsFgtI/AAAAAAAAAbs/WT8jViTF7vw/s1024/Antelope%252520Hallway.jpg", 39 | "https://lh4.googleusercontent.com/-WIuWgVcU3Qw/URqubRVcj4I/AAAAAAAAAbs/YvbwgGjwdIQ/s1024/Antelope%252520Walls.jpg", 40 | "https://lh6.googleusercontent.com/-UBmLbPELvoQ/URqucCdv0kI/AAAAAAAAAbs/IdNhr2VQoQs/s1024/Apre%2525CC%252580s%252520la%252520Pluie.jpg", 41 | "https://lh3.googleusercontent.com/-s-AFpvgSeew/URquc6dF-JI/AAAAAAAAAbs/Mt3xNGRUd68/s1024/Backlit%252520Cloud.jpg", 42 | "https://lh5.googleusercontent.com/-bvmif9a9YOQ/URquea3heHI/AAAAAAAAAbs/rcr6wyeQtAo/s1024/Bee%252520and%252520Flower.jpg", 43 | "https://lh5.googleusercontent.com/-n7mdm7I7FGs/URqueT_BT-I/AAAAAAAAAbs/9MYmXlmpSAo/s1024/Bonzai%252520Rock%252520Sunset.jpg", 44 | "https://lh6.googleusercontent.com/-4CN4X4t0M1k/URqufPozWzI/AAAAAAAAAbs/8wK41lg1KPs/s1024/Caterpillar.jpg", 45 | "https://lh3.googleusercontent.com/-rrFnVC8xQEg/URqufdrLBaI/AAAAAAAAAbs/s69WYy_fl1E/s1024/Chess.jpg", 46 | "https://lh5.googleusercontent.com/-WVpRptWH8Yw/URqugh-QmDI/AAAAAAAAAbs/E-MgBgtlUWU/s1024/Chihuly.jpg", 47 | "https://lh5.googleusercontent.com/-0BDXkYmckbo/URquhKFW84I/AAAAAAAAAbs/ogQtHCTk2JQ/s1024/Closed%252520Door.jpg", 48 | "https://lh3.googleusercontent.com/-PyggXXZRykM/URquh-kVvoI/AAAAAAAAAbs/hFtDwhtrHHQ/s1024/Colorado%252520River%252520Sunset.jpg", 49 | "https://lh3.googleusercontent.com/-ZAs4dNZtALc/URquikvOCWI/AAAAAAAAAbs/DXz4h3dll1Y/s1024/Colors%252520of%252520Autumn.jpg", 50 | "https://lh4.googleusercontent.com/-GztnWEIiMz8/URqukVCU7bI/AAAAAAAAAbs/jo2Hjv6MZ6M/s1024/Countryside.jpg", 51 | "https://lh4.googleusercontent.com/-bEg9EZ9QoiM/URquklz3FGI/AAAAAAAAAbs/UUuv8Ac2BaE/s1024/Death%252520Valley%252520-%252520Dunes.jpg", 52 | "https://lh6.googleusercontent.com/-ijQJ8W68tEE/URqulGkvFEI/AAAAAAAAAbs/zPXvIwi_rFw/s1024/Delicate%252520Arch.jpg", 53 | "https://lh5.googleusercontent.com/-Oh8mMy2ieng/URqullDwehI/AAAAAAAAAbs/TbdeEfsaIZY/s1024/Despair.jpg", 54 | "https://lh5.googleusercontent.com/-gl0y4UiAOlk/URqumC_KjBI/AAAAAAAAAbs/PM1eT7dn4oo/s1024/Eagle%252520Fall%252520Sunrise.jpg", 55 | "https://lh3.googleusercontent.com/-hYYHd2_vXPQ/URqumtJa9eI/AAAAAAAAAbs/wAalXVkbSh0/s1024/Electric%252520Storm.jpg", 56 | "https://lh5.googleusercontent.com/-PyY_yiyjPTo/URqunUOhHFI/AAAAAAAAAbs/azZoULNuJXc/s1024/False%252520Kiva.jpg", 57 | "https://lh6.googleusercontent.com/-PYvLVdvXywk/URqunwd8hfI/AAAAAAAAAbs/qiMwgkFvf6I/s1024/Fitzgerald%252520Streaks.jpg", 58 | "https://lh4.googleusercontent.com/-KIR_UobIIqY/URquoCZ9SlI/AAAAAAAAAbs/Y4d4q8sXu4c/s1024/Foggy%252520Sunset.jpg", 59 | "https://lh6.googleusercontent.com/-9lzOk_OWZH0/URquoo4xYoI/AAAAAAAAAbs/AwgzHtNVCwU/s1024/Frantic.jpg", 60 | "https://lh3.googleusercontent.com/-0X3JNaKaz48/URqupH78wpI/AAAAAAAAAbs/lHXxu_zbH8s/s1024/Golden%252520Gate%252520Afternoon.jpg", 61 | "https://lh6.googleusercontent.com/-95sb5ag7ABc/URqupl95RDI/AAAAAAAAAbs/g73R20iVTRA/s1024/Golden%252520Gate%252520Fog.jpg", 62 | "https://lh3.googleusercontent.com/-JB9v6rtgHhk/URqup21F-zI/AAAAAAAAAbs/64Fb8qMZWXk/s1024/Golden%252520Grass.jpg", 63 | "https://lh4.googleusercontent.com/-EIBGfnuLtII/URquqVHwaRI/AAAAAAAAAbs/FA4McV2u8VE/s1024/Grand%252520Teton.jpg", 64 | "https://lh4.googleusercontent.com/-WoMxZvmN9nY/URquq1v2AoI/AAAAAAAAAbs/grj5uMhL6NA/s1024/Grass%252520Closeup.jpg", 65 | "https://lh3.googleusercontent.com/-6hZiEHXx64Q/URqurxvNdqI/AAAAAAAAAbs/kWMXM3o5OVI/s1024/Green%252520Grass.jpg", 66 | "https://lh5.googleusercontent.com/-6LVb9OXtQ60/URquteBFuKI/AAAAAAAAAbs/4F4kRgecwFs/s1024/Hanging%252520Leaf.jpg", 67 | "https://lh4.googleusercontent.com/-zAvf__52ONk/URqutT_IuxI/AAAAAAAAAbs/D_bcuc0thoU/s1024/Highway%2525201.jpg", 68 | "https://lh6.googleusercontent.com/-H4SrUg615rA/URquuL27fXI/AAAAAAAAAbs/4aEqJfiMsOU/s1024/Horseshoe%252520Bend%252520Sunset.jpg", 69 | "https://lh4.googleusercontent.com/-JhFi4fb_Pqw/URquuX-QXbI/AAAAAAAAAbs/IXpYUxuweYM/s1024/Horseshoe%252520Bend.jpg", 70 | "https://lh5.googleusercontent.com/-UGgssvFRJ7g/URquueyJzGI/AAAAAAAAAbs/yYIBlLT0toM/s1024/Into%252520the%252520Blue.jpg", 71 | "https://lh3.googleusercontent.com/-CH7KoupI7uI/URquu0FF__I/AAAAAAAAAbs/R7GDmI7v_G0/s1024/Jelly%252520Fish%2525202.jpg", 72 | "https://lh4.googleusercontent.com/-pwuuw6yhg8U/URquvPxR3FI/AAAAAAAAAbs/VNGk6f-tsGE/s1024/Jelly%252520Fish%2525203.jpg", 73 | "https://lh5.googleusercontent.com/-GoUQVw1fnFw/URquv6xbC0I/AAAAAAAAAbs/zEUVTQQ43Zc/s1024/Kauai.jpg", 74 | "https://lh6.googleusercontent.com/-8QdYYQEpYjw/URquwvdh88I/AAAAAAAAAbs/cktDy-ysfHo/s1024/Kyoto%252520Sunset.jpg", 75 | "https://lh4.googleusercontent.com/-vPeekyDjOE0/URquwzJ28qI/AAAAAAAAAbs/qxcyXULsZrg/s1024/Lake%252520Tahoe%252520Colors.jpg", 76 | "https://lh4.googleusercontent.com/-xBPxWpD4yxU/URquxWHk8AI/AAAAAAAAAbs/ARDPeDYPiMY/s1024/Lava%252520from%252520the%252520Sky.jpg", 77 | "https://lh3.googleusercontent.com/-897VXrJB6RE/URquxxxd-5I/AAAAAAAAAbs/j-Cz4T4YvIw/s1024/Leica%25252050mm%252520Summilux.jpg", 78 | "https://lh5.googleusercontent.com/-qSJ4D4iXzGo/URquyDWiJ1I/AAAAAAAAAbs/k2pBXeWehOA/s1024/Leica%25252050mm%252520Summilux.jpg", 79 | "https://lh6.googleusercontent.com/-dwlPg83vzLg/URquylTVuFI/AAAAAAAAAbs/G6SyQ8b4YsI/s1024/Leica%252520M8%252520%252528Front%252529.jpg", 80 | "https://lh3.googleusercontent.com/-R3_EYAyJvfk/URquzQBv8eI/AAAAAAAAAbs/b9xhpUM3pEI/s1024/Light%252520to%252520Sand.jpg", 81 | "https://lh3.googleusercontent.com/-fHY5h67QPi0/URqu0Cp4J1I/AAAAAAAAAbs/0lG6m94Z6vM/s1024/Little%252520Bit%252520of%252520Paradise.jpg", 82 | "https://lh5.googleusercontent.com/-TzF_LwrCnRM/URqu0RddPOI/AAAAAAAAAbs/gaj2dLiuX0s/s1024/Lone%252520Pine%252520Sunset.jpg", 83 | "https://lh3.googleusercontent.com/-4HdpJ4_DXU4/URqu046dJ9I/AAAAAAAAAbs/eBOodtk2_uk/s1024/Lonely%252520Rock.jpg", 84 | "https://lh6.googleusercontent.com/-erbF--z-W4s/URqu1ajSLkI/AAAAAAAAAbs/xjDCDO1INzM/s1024/Longue%252520Vue.jpg", 85 | "https://lh6.googleusercontent.com/-0CXJRdJaqvc/URqu1opNZNI/AAAAAAAAAbs/PFB2oPUU7Lk/s1024/Look%252520Me%252520in%252520the%252520Eye.jpg", 86 | "https://lh3.googleusercontent.com/-D_5lNxnDN6g/URqu2Tk7HVI/AAAAAAAAAbs/p0ddca9W__Y/s1024/Lost%252520in%252520a%252520Field.jpg", 87 | "https://lh6.googleusercontent.com/-flsqwMrIk2Q/URqu24PcmjI/AAAAAAAAAbs/5ocIH85XofM/s1024/Marshall%252520Beach%252520Sunset.jpg", 88 | "https://lh4.googleusercontent.com/-Y4lgryEVTmU/URqu28kG3gI/AAAAAAAAAbs/OjXpekqtbJ4/s1024/Mono%252520Lake%252520Blue.jpg", 89 | "https://lh4.googleusercontent.com/-AaHAJPmcGYA/URqu3PIldHI/AAAAAAAAAbs/lcTqk1SIcRs/s1024/Monument%252520Valley%252520Overlook.jpg", 90 | "https://lh4.googleusercontent.com/-vKxfdQ83dQA/URqu31Yq_BI/AAAAAAAAAbs/OUoGk_2AyfM/s1024/Moving%252520Rock.jpg", 91 | "https://lh5.googleusercontent.com/-CG62QiPpWXg/URqu4ia4vRI/AAAAAAAAAbs/0YOdqLAlcAc/s1024/Napali%252520Coast.jpg", 92 | "https://lh6.googleusercontent.com/-wdGrP5PMmJQ/URqu5PZvn7I/AAAAAAAAAbs/m0abEcdPXe4/s1024/One%252520Wheel.jpg", 93 | "https://lh6.googleusercontent.com/-6WS5DoCGuOA/URqu5qx1UgI/AAAAAAAAAbs/giMw2ixPvrY/s1024/Open%252520Sky.jpg", 94 | "https://lh6.googleusercontent.com/-u8EHKj8G8GQ/URqu55sM6yI/AAAAAAAAAbs/lIXX_GlTdmI/s1024/Orange%252520Sunset.jpg", 95 | "https://lh6.googleusercontent.com/-74Z5qj4bTDE/URqu6LSrJrI/AAAAAAAAAbs/XzmVkw90szQ/s1024/Orchid.jpg", 96 | "https://lh6.googleusercontent.com/-lEQE4h6TePE/URqu6t_lSkI/AAAAAAAAAbs/zvGYKOea_qY/s1024/Over%252520there.jpg", 97 | "https://lh5.googleusercontent.com/-cauH-53JH2M/URqu66v_USI/AAAAAAAAAbs/EucwwqclfKQ/s1024/Plumes.jpg", 98 | "https://lh3.googleusercontent.com/-eDLT2jHDoy4/URqu7axzkAI/AAAAAAAAAbs/iVZE-xJ7lZs/s1024/Rainbokeh.jpg", 99 | "https://lh5.googleusercontent.com/-j1NLqEFIyco/URqu8L1CGcI/AAAAAAAAAbs/aqZkgX66zlI/s1024/Rainbow.jpg", 100 | "https://lh5.googleusercontent.com/-DRnqmK0t4VU/URqu8XYN9yI/AAAAAAAAAbs/LgvF_592WLU/s1024/Rice%252520Fields.jpg", 101 | "https://lh3.googleusercontent.com/-hwh1v3EOGcQ/URqu8qOaKwI/AAAAAAAAAbs/IljRJRnbJGw/s1024/Rockaway%252520Fire%252520Sky.jpg", 102 | "https://lh5.googleusercontent.com/-wjV6FQk7tlk/URqu9jCQ8sI/AAAAAAAAAbs/RyYUpdo-c9o/s1024/Rockaway%252520Flow.jpg", 103 | "https://lh6.googleusercontent.com/-6cAXNfo7D20/URqu-BdzgPI/AAAAAAAAAbs/OmsYllzJqwo/s1024/Rockaway%252520Sunset%252520Sky.jpg", 104 | "https://lh3.googleusercontent.com/-sl8fpGPS-RE/URqu_BOkfgI/AAAAAAAAAbs/Dg2Fv-JxOeg/s1024/Russian%252520Ridge%252520Sunset.jpg", 105 | "https://lh6.googleusercontent.com/-gVtY36mMBIg/URqu_q91lkI/AAAAAAAAAbs/3CiFMBcy5MA/s1024/Rust%252520Knot.jpg", 106 | "https://lh6.googleusercontent.com/-GHeImuHqJBE/URqu_FKfVLI/AAAAAAAAAbs/axuEJeqam7Q/s1024/Sailing%252520Stones.jpg", 107 | "https://lh3.googleusercontent.com/-hBbYZjTOwGc/URqu_ycpIrI/AAAAAAAAAbs/nAdJUXnGJYE/s1024/Seahorse.jpg", 108 | "https://lh3.googleusercontent.com/-Iwi6-i6IexY/URqvAYZHsVI/AAAAAAAAAbs/5ETWl4qXsFE/s1024/Shinjuku%252520Street.jpg", 109 | "https://lh6.googleusercontent.com/-amhnySTM_MY/URqvAlb5KoI/AAAAAAAAAbs/pFCFgzlKsn0/s1024/Sierra%252520Heavens.jpg", 110 | "https://lh5.googleusercontent.com/-dJgjepFrYSo/URqvBVJZrAI/AAAAAAAAAbs/v-F5QWpYO6s/s1024/Sierra%252520Sunset.jpg", 111 | "https://lh4.googleusercontent.com/-Z4zGiC5nWdc/URqvBdEwivI/AAAAAAAAAbs/ZRZR1VJ84QA/s1024/Sin%252520Lights.jpg", 112 | "https://lh4.googleusercontent.com/-_0cYiWW8ccY/URqvBz3iM4I/AAAAAAAAAbs/9N_Wq8MhLTY/s1024/Starry%252520Lake.jpg", 113 | "https://lh3.googleusercontent.com/-A9LMoRyuQUA/URqvCYx_JoI/AAAAAAAAAbs/s7sde1Bz9cI/s1024/Starry%252520Night.jpg", 114 | "https://lh3.googleusercontent.com/-KtLJ3k858eY/URqvC_2h_bI/AAAAAAAAAbs/zzEBImwDA_g/s1024/Stream.jpg", 115 | "https://lh5.googleusercontent.com/-dFB7Lad6RcA/URqvDUftwWI/AAAAAAAAAbs/BrhoUtXTN7o/s1024/Strip%252520Sunset.jpg", 116 | "https://lh5.googleusercontent.com/-at6apgFiN20/URqvDyffUZI/AAAAAAAAAbs/clABCx171bE/s1024/Sunset%252520Hills.jpg", 117 | "https://lh4.googleusercontent.com/-7-EHhtQthII/URqvEYTk4vI/AAAAAAAAAbs/QSJZoB3YjVg/s1024/Tenaya%252520Lake%2525202.jpg", 118 | "https://lh6.googleusercontent.com/-8MrjV_a-Pok/URqvFC5repI/AAAAAAAAAbs/9inKTg9fbCE/s1024/Tenaya%252520Lake.jpg", 119 | "https://lh5.googleusercontent.com/-B1HW-z4zwao/URqvFWYRwUI/AAAAAAAAAbs/8Peli53Bs8I/s1024/The%252520Cave%252520BW.jpg", 120 | "https://lh3.googleusercontent.com/-PO4E-xZKAnQ/URqvGRqjYkI/AAAAAAAAAbs/42nyADFsXag/s1024/The%252520Fisherman.jpg", 121 | "https://lh4.googleusercontent.com/-iLyZlzfdy7s/URqvG0YScdI/AAAAAAAAAbs/1J9eDKmkXtk/s1024/The%252520Night%252520is%252520Coming.jpg", 122 | "https://lh6.googleusercontent.com/-G-k7YkkUco0/URqvHhah6fI/AAAAAAAAAbs/_taQQG7t0vo/s1024/The%252520Road.jpg", 123 | "https://lh6.googleusercontent.com/-h-ALJt7kSus/URqvIThqYfI/AAAAAAAAAbs/ejiv35olWS8/s1024/Tokyo%252520Heights.jpg", 124 | "https://lh5.googleusercontent.com/-Hy9k-TbS7xg/URqvIjQMOxI/AAAAAAAAAbs/RSpmmOATSkg/s1024/Tokyo%252520Highway.jpg", 125 | "https://lh6.googleusercontent.com/-83oOvMb4OZs/URqvJL0T7lI/AAAAAAAAAbs/c5TECZ6RONM/s1024/Tokyo%252520Smog.jpg", 126 | "https://lh3.googleusercontent.com/-FB-jfgREEfI/URqvJI3EXAI/AAAAAAAAAbs/XfyweiRF4v8/s1024/Tufa%252520at%252520Night.jpg", 127 | "https://lh4.googleusercontent.com/-vngKD5Z1U8w/URqvJUCEgPI/AAAAAAAAAbs/ulxCMVcU6EU/s1024/Valley%252520Sunset.jpg", 128 | "https://lh6.googleusercontent.com/-DOz5I2E2oMQ/URqvKMND1kI/AAAAAAAAAbs/Iqf0IsInleo/s1024/Windmill%252520Sunrise.jpg", 129 | "https://lh5.googleusercontent.com/-biyiyWcJ9MU/URqvKculiAI/AAAAAAAAAbs/jyPsCplJOpE/s1024/Windmill.jpg", 130 | "https://lh4.googleusercontent.com/-PDT167_xRdA/URqvK36mLcI/AAAAAAAAAbs/oi2ik9QseMI/s1024/Windmills.jpg", 131 | "https://lh5.googleusercontent.com/-kI_QdYx7VlU/URqvLXCB6gI/AAAAAAAAAbs/N31vlZ6u89o/s1024/Yet%252520Another%252520Rockaway%252520Sunset.jpg", 132 | "https://lh4.googleusercontent.com/-e9NHZ5k5MSs/URqvMIBZjtI/AAAAAAAAAbs/1fV810rDNfQ/s1024/Yosemite%252520Tree.jpg", 133 | }; 134 | 135 | /** 136 | * This are PicasaWeb thumbnail URLs and could potentially change. Ideally the PicasaWeb API 137 | * should be used to fetch the URLs. 138 | * 139 | * Credit to Romain Guy for the photos: 140 | * http://www.curious-creature.org/ 141 | * https://plus.google.com/109538161516040592207/about 142 | * http://www.flickr.com/photos/romainguy 143 | */ 144 | public final static String[] imageThumbUrls = new String[] { 145 | "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s240-c/A%252520Photographer.jpg", 146 | "https://lh4.googleusercontent.com/--dq8niRp7W4/URquVgmXvgI/AAAAAAAAAbs/-gnuLQfNnBA/s240-c/A%252520Song%252520of%252520Ice%252520and%252520Fire.jpg", 147 | "https://lh5.googleusercontent.com/-7qZeDtRKFKc/URquWZT1gOI/AAAAAAAAAbs/hqWgteyNXsg/s240-c/Another%252520Rockaway%252520Sunset.jpg", 148 | "https://lh3.googleusercontent.com/--L0Km39l5J8/URquXHGcdNI/AAAAAAAAAbs/3ZrSJNrSomQ/s240-c/Antelope%252520Butte.jpg", 149 | "https://lh6.googleusercontent.com/-8HO-4vIFnlw/URquZnsFgtI/AAAAAAAAAbs/WT8jViTF7vw/s240-c/Antelope%252520Hallway.jpg", 150 | "https://lh4.googleusercontent.com/-WIuWgVcU3Qw/URqubRVcj4I/AAAAAAAAAbs/YvbwgGjwdIQ/s240-c/Antelope%252520Walls.jpg", 151 | "https://lh6.googleusercontent.com/-UBmLbPELvoQ/URqucCdv0kI/AAAAAAAAAbs/IdNhr2VQoQs/s240-c/Apre%2525CC%252580s%252520la%252520Pluie.jpg", 152 | "https://lh3.googleusercontent.com/-s-AFpvgSeew/URquc6dF-JI/AAAAAAAAAbs/Mt3xNGRUd68/s240-c/Backlit%252520Cloud.jpg", 153 | "https://lh5.googleusercontent.com/-bvmif9a9YOQ/URquea3heHI/AAAAAAAAAbs/rcr6wyeQtAo/s240-c/Bee%252520and%252520Flower.jpg", 154 | "https://lh5.googleusercontent.com/-n7mdm7I7FGs/URqueT_BT-I/AAAAAAAAAbs/9MYmXlmpSAo/s240-c/Bonzai%252520Rock%252520Sunset.jpg", 155 | "https://lh6.googleusercontent.com/-4CN4X4t0M1k/URqufPozWzI/AAAAAAAAAbs/8wK41lg1KPs/s240-c/Caterpillar.jpg", 156 | "https://lh3.googleusercontent.com/-rrFnVC8xQEg/URqufdrLBaI/AAAAAAAAAbs/s69WYy_fl1E/s240-c/Chess.jpg", 157 | "https://lh5.googleusercontent.com/-WVpRptWH8Yw/URqugh-QmDI/AAAAAAAAAbs/E-MgBgtlUWU/s240-c/Chihuly.jpg", 158 | "https://lh5.googleusercontent.com/-0BDXkYmckbo/URquhKFW84I/AAAAAAAAAbs/ogQtHCTk2JQ/s240-c/Closed%252520Door.jpg", 159 | "https://lh3.googleusercontent.com/-PyggXXZRykM/URquh-kVvoI/AAAAAAAAAbs/hFtDwhtrHHQ/s240-c/Colorado%252520River%252520Sunset.jpg", 160 | "https://lh3.googleusercontent.com/-ZAs4dNZtALc/URquikvOCWI/AAAAAAAAAbs/DXz4h3dll1Y/s240-c/Colors%252520of%252520Autumn.jpg", 161 | "https://lh4.googleusercontent.com/-GztnWEIiMz8/URqukVCU7bI/AAAAAAAAAbs/jo2Hjv6MZ6M/s240-c/Countryside.jpg", 162 | "https://lh4.googleusercontent.com/-bEg9EZ9QoiM/URquklz3FGI/AAAAAAAAAbs/UUuv8Ac2BaE/s240-c/Death%252520Valley%252520-%252520Dunes.jpg", 163 | "https://lh6.googleusercontent.com/-ijQJ8W68tEE/URqulGkvFEI/AAAAAAAAAbs/zPXvIwi_rFw/s240-c/Delicate%252520Arch.jpg", 164 | "https://lh5.googleusercontent.com/-Oh8mMy2ieng/URqullDwehI/AAAAAAAAAbs/TbdeEfsaIZY/s240-c/Despair.jpg", 165 | "https://lh5.googleusercontent.com/-gl0y4UiAOlk/URqumC_KjBI/AAAAAAAAAbs/PM1eT7dn4oo/s240-c/Eagle%252520Fall%252520Sunrise.jpg", 166 | "https://lh3.googleusercontent.com/-hYYHd2_vXPQ/URqumtJa9eI/AAAAAAAAAbs/wAalXVkbSh0/s240-c/Electric%252520Storm.jpg", 167 | "https://lh5.googleusercontent.com/-PyY_yiyjPTo/URqunUOhHFI/AAAAAAAAAbs/azZoULNuJXc/s240-c/False%252520Kiva.jpg", 168 | "https://lh6.googleusercontent.com/-PYvLVdvXywk/URqunwd8hfI/AAAAAAAAAbs/qiMwgkFvf6I/s240-c/Fitzgerald%252520Streaks.jpg", 169 | "https://lh4.googleusercontent.com/-KIR_UobIIqY/URquoCZ9SlI/AAAAAAAAAbs/Y4d4q8sXu4c/s240-c/Foggy%252520Sunset.jpg", 170 | "https://lh6.googleusercontent.com/-9lzOk_OWZH0/URquoo4xYoI/AAAAAAAAAbs/AwgzHtNVCwU/s240-c/Frantic.jpg", 171 | "https://lh3.googleusercontent.com/-0X3JNaKaz48/URqupH78wpI/AAAAAAAAAbs/lHXxu_zbH8s/s240-c/Golden%252520Gate%252520Afternoon.jpg", 172 | "https://lh6.googleusercontent.com/-95sb5ag7ABc/URqupl95RDI/AAAAAAAAAbs/g73R20iVTRA/s240-c/Golden%252520Gate%252520Fog.jpg", 173 | "https://lh3.googleusercontent.com/-JB9v6rtgHhk/URqup21F-zI/AAAAAAAAAbs/64Fb8qMZWXk/s240-c/Golden%252520Grass.jpg", 174 | "https://lh4.googleusercontent.com/-EIBGfnuLtII/URquqVHwaRI/AAAAAAAAAbs/FA4McV2u8VE/s240-c/Grand%252520Teton.jpg", 175 | "https://lh4.googleusercontent.com/-WoMxZvmN9nY/URquq1v2AoI/AAAAAAAAAbs/grj5uMhL6NA/s240-c/Grass%252520Closeup.jpg", 176 | "https://lh3.googleusercontent.com/-6hZiEHXx64Q/URqurxvNdqI/AAAAAAAAAbs/kWMXM3o5OVI/s240-c/Green%252520Grass.jpg", 177 | "https://lh5.googleusercontent.com/-6LVb9OXtQ60/URquteBFuKI/AAAAAAAAAbs/4F4kRgecwFs/s240-c/Hanging%252520Leaf.jpg", 178 | "https://lh4.googleusercontent.com/-zAvf__52ONk/URqutT_IuxI/AAAAAAAAAbs/D_bcuc0thoU/s240-c/Highway%2525201.jpg", 179 | "https://lh6.googleusercontent.com/-H4SrUg615rA/URquuL27fXI/AAAAAAAAAbs/4aEqJfiMsOU/s240-c/Horseshoe%252520Bend%252520Sunset.jpg", 180 | "https://lh4.googleusercontent.com/-JhFi4fb_Pqw/URquuX-QXbI/AAAAAAAAAbs/IXpYUxuweYM/s240-c/Horseshoe%252520Bend.jpg", 181 | "https://lh5.googleusercontent.com/-UGgssvFRJ7g/URquueyJzGI/AAAAAAAAAbs/yYIBlLT0toM/s240-c/Into%252520the%252520Blue.jpg", 182 | "https://lh3.googleusercontent.com/-CH7KoupI7uI/URquu0FF__I/AAAAAAAAAbs/R7GDmI7v_G0/s240-c/Jelly%252520Fish%2525202.jpg", 183 | "https://lh4.googleusercontent.com/-pwuuw6yhg8U/URquvPxR3FI/AAAAAAAAAbs/VNGk6f-tsGE/s240-c/Jelly%252520Fish%2525203.jpg", 184 | "https://lh5.googleusercontent.com/-GoUQVw1fnFw/URquv6xbC0I/AAAAAAAAAbs/zEUVTQQ43Zc/s240-c/Kauai.jpg", 185 | "https://lh6.googleusercontent.com/-8QdYYQEpYjw/URquwvdh88I/AAAAAAAAAbs/cktDy-ysfHo/s240-c/Kyoto%252520Sunset.jpg", 186 | "https://lh4.googleusercontent.com/-vPeekyDjOE0/URquwzJ28qI/AAAAAAAAAbs/qxcyXULsZrg/s240-c/Lake%252520Tahoe%252520Colors.jpg", 187 | "https://lh4.googleusercontent.com/-xBPxWpD4yxU/URquxWHk8AI/AAAAAAAAAbs/ARDPeDYPiMY/s240-c/Lava%252520from%252520the%252520Sky.jpg", 188 | "https://lh3.googleusercontent.com/-897VXrJB6RE/URquxxxd-5I/AAAAAAAAAbs/j-Cz4T4YvIw/s240-c/Leica%25252050mm%252520Summilux.jpg", 189 | "https://lh5.googleusercontent.com/-qSJ4D4iXzGo/URquyDWiJ1I/AAAAAAAAAbs/k2pBXeWehOA/s240-c/Leica%25252050mm%252520Summilux.jpg", 190 | "https://lh6.googleusercontent.com/-dwlPg83vzLg/URquylTVuFI/AAAAAAAAAbs/G6SyQ8b4YsI/s240-c/Leica%252520M8%252520%252528Front%252529.jpg", 191 | "https://lh3.googleusercontent.com/-R3_EYAyJvfk/URquzQBv8eI/AAAAAAAAAbs/b9xhpUM3pEI/s240-c/Light%252520to%252520Sand.jpg", 192 | "https://lh3.googleusercontent.com/-fHY5h67QPi0/URqu0Cp4J1I/AAAAAAAAAbs/0lG6m94Z6vM/s240-c/Little%252520Bit%252520of%252520Paradise.jpg", 193 | "https://lh5.googleusercontent.com/-TzF_LwrCnRM/URqu0RddPOI/AAAAAAAAAbs/gaj2dLiuX0s/s240-c/Lone%252520Pine%252520Sunset.jpg", 194 | "https://lh3.googleusercontent.com/-4HdpJ4_DXU4/URqu046dJ9I/AAAAAAAAAbs/eBOodtk2_uk/s240-c/Lonely%252520Rock.jpg", 195 | "https://lh6.googleusercontent.com/-erbF--z-W4s/URqu1ajSLkI/AAAAAAAAAbs/xjDCDO1INzM/s240-c/Longue%252520Vue.jpg", 196 | "https://lh6.googleusercontent.com/-0CXJRdJaqvc/URqu1opNZNI/AAAAAAAAAbs/PFB2oPUU7Lk/s240-c/Look%252520Me%252520in%252520the%252520Eye.jpg", 197 | "https://lh3.googleusercontent.com/-D_5lNxnDN6g/URqu2Tk7HVI/AAAAAAAAAbs/p0ddca9W__Y/s240-c/Lost%252520in%252520a%252520Field.jpg", 198 | "https://lh6.googleusercontent.com/-flsqwMrIk2Q/URqu24PcmjI/AAAAAAAAAbs/5ocIH85XofM/s240-c/Marshall%252520Beach%252520Sunset.jpg", 199 | "https://lh4.googleusercontent.com/-Y4lgryEVTmU/URqu28kG3gI/AAAAAAAAAbs/OjXpekqtbJ4/s240-c/Mono%252520Lake%252520Blue.jpg", 200 | "https://lh4.googleusercontent.com/-AaHAJPmcGYA/URqu3PIldHI/AAAAAAAAAbs/lcTqk1SIcRs/s240-c/Monument%252520Valley%252520Overlook.jpg", 201 | "https://lh4.googleusercontent.com/-vKxfdQ83dQA/URqu31Yq_BI/AAAAAAAAAbs/OUoGk_2AyfM/s240-c/Moving%252520Rock.jpg", 202 | "https://lh5.googleusercontent.com/-CG62QiPpWXg/URqu4ia4vRI/AAAAAAAAAbs/0YOdqLAlcAc/s240-c/Napali%252520Coast.jpg", 203 | "https://lh6.googleusercontent.com/-wdGrP5PMmJQ/URqu5PZvn7I/AAAAAAAAAbs/m0abEcdPXe4/s240-c/One%252520Wheel.jpg", 204 | "https://lh6.googleusercontent.com/-6WS5DoCGuOA/URqu5qx1UgI/AAAAAAAAAbs/giMw2ixPvrY/s240-c/Open%252520Sky.jpg", 205 | "https://lh6.googleusercontent.com/-u8EHKj8G8GQ/URqu55sM6yI/AAAAAAAAAbs/lIXX_GlTdmI/s240-c/Orange%252520Sunset.jpg", 206 | "https://lh6.googleusercontent.com/-74Z5qj4bTDE/URqu6LSrJrI/AAAAAAAAAbs/XzmVkw90szQ/s240-c/Orchid.jpg", 207 | "https://lh6.googleusercontent.com/-lEQE4h6TePE/URqu6t_lSkI/AAAAAAAAAbs/zvGYKOea_qY/s240-c/Over%252520there.jpg", 208 | "https://lh5.googleusercontent.com/-cauH-53JH2M/URqu66v_USI/AAAAAAAAAbs/EucwwqclfKQ/s240-c/Plumes.jpg", 209 | "https://lh3.googleusercontent.com/-eDLT2jHDoy4/URqu7axzkAI/AAAAAAAAAbs/iVZE-xJ7lZs/s240-c/Rainbokeh.jpg", 210 | "https://lh5.googleusercontent.com/-j1NLqEFIyco/URqu8L1CGcI/AAAAAAAAAbs/aqZkgX66zlI/s240-c/Rainbow.jpg", 211 | "https://lh5.googleusercontent.com/-DRnqmK0t4VU/URqu8XYN9yI/AAAAAAAAAbs/LgvF_592WLU/s240-c/Rice%252520Fields.jpg", 212 | "https://lh3.googleusercontent.com/-hwh1v3EOGcQ/URqu8qOaKwI/AAAAAAAAAbs/IljRJRnbJGw/s240-c/Rockaway%252520Fire%252520Sky.jpg", 213 | "https://lh5.googleusercontent.com/-wjV6FQk7tlk/URqu9jCQ8sI/AAAAAAAAAbs/RyYUpdo-c9o/s240-c/Rockaway%252520Flow.jpg", 214 | "https://lh6.googleusercontent.com/-6cAXNfo7D20/URqu-BdzgPI/AAAAAAAAAbs/OmsYllzJqwo/s240-c/Rockaway%252520Sunset%252520Sky.jpg", 215 | "https://lh3.googleusercontent.com/-sl8fpGPS-RE/URqu_BOkfgI/AAAAAAAAAbs/Dg2Fv-JxOeg/s240-c/Russian%252520Ridge%252520Sunset.jpg", 216 | "https://lh6.googleusercontent.com/-gVtY36mMBIg/URqu_q91lkI/AAAAAAAAAbs/3CiFMBcy5MA/s240-c/Rust%252520Knot.jpg", 217 | "https://lh6.googleusercontent.com/-GHeImuHqJBE/URqu_FKfVLI/AAAAAAAAAbs/axuEJeqam7Q/s240-c/Sailing%252520Stones.jpg", 218 | "https://lh3.googleusercontent.com/-hBbYZjTOwGc/URqu_ycpIrI/AAAAAAAAAbs/nAdJUXnGJYE/s240-c/Seahorse.jpg", 219 | "https://lh3.googleusercontent.com/-Iwi6-i6IexY/URqvAYZHsVI/AAAAAAAAAbs/5ETWl4qXsFE/s240-c/Shinjuku%252520Street.jpg", 220 | "https://lh6.googleusercontent.com/-amhnySTM_MY/URqvAlb5KoI/AAAAAAAAAbs/pFCFgzlKsn0/s240-c/Sierra%252520Heavens.jpg", 221 | "https://lh5.googleusercontent.com/-dJgjepFrYSo/URqvBVJZrAI/AAAAAAAAAbs/v-F5QWpYO6s/s240-c/Sierra%252520Sunset.jpg", 222 | "https://lh4.googleusercontent.com/-Z4zGiC5nWdc/URqvBdEwivI/AAAAAAAAAbs/ZRZR1VJ84QA/s240-c/Sin%252520Lights.jpg", 223 | "https://lh4.googleusercontent.com/-_0cYiWW8ccY/URqvBz3iM4I/AAAAAAAAAbs/9N_Wq8MhLTY/s240-c/Starry%252520Lake.jpg", 224 | "https://lh3.googleusercontent.com/-A9LMoRyuQUA/URqvCYx_JoI/AAAAAAAAAbs/s7sde1Bz9cI/s240-c/Starry%252520Night.jpg", 225 | "https://lh3.googleusercontent.com/-KtLJ3k858eY/URqvC_2h_bI/AAAAAAAAAbs/zzEBImwDA_g/s240-c/Stream.jpg", 226 | "https://lh5.googleusercontent.com/-dFB7Lad6RcA/URqvDUftwWI/AAAAAAAAAbs/BrhoUtXTN7o/s240-c/Strip%252520Sunset.jpg", 227 | "https://lh5.googleusercontent.com/-at6apgFiN20/URqvDyffUZI/AAAAAAAAAbs/clABCx171bE/s240-c/Sunset%252520Hills.jpg", 228 | "https://lh4.googleusercontent.com/-7-EHhtQthII/URqvEYTk4vI/AAAAAAAAAbs/QSJZoB3YjVg/s240-c/Tenaya%252520Lake%2525202.jpg", 229 | "https://lh6.googleusercontent.com/-8MrjV_a-Pok/URqvFC5repI/AAAAAAAAAbs/9inKTg9fbCE/s240-c/Tenaya%252520Lake.jpg", 230 | "https://lh5.googleusercontent.com/-B1HW-z4zwao/URqvFWYRwUI/AAAAAAAAAbs/8Peli53Bs8I/s240-c/The%252520Cave%252520BW.jpg", 231 | "https://lh3.googleusercontent.com/-PO4E-xZKAnQ/URqvGRqjYkI/AAAAAAAAAbs/42nyADFsXag/s240-c/The%252520Fisherman.jpg", 232 | "https://lh4.googleusercontent.com/-iLyZlzfdy7s/URqvG0YScdI/AAAAAAAAAbs/1J9eDKmkXtk/s240-c/The%252520Night%252520is%252520Coming.jpg", 233 | "https://lh6.googleusercontent.com/-G-k7YkkUco0/URqvHhah6fI/AAAAAAAAAbs/_taQQG7t0vo/s240-c/The%252520Road.jpg", 234 | "https://lh6.googleusercontent.com/-h-ALJt7kSus/URqvIThqYfI/AAAAAAAAAbs/ejiv35olWS8/s240-c/Tokyo%252520Heights.jpg", 235 | "https://lh5.googleusercontent.com/-Hy9k-TbS7xg/URqvIjQMOxI/AAAAAAAAAbs/RSpmmOATSkg/s240-c/Tokyo%252520Highway.jpg", 236 | "https://lh6.googleusercontent.com/-83oOvMb4OZs/URqvJL0T7lI/AAAAAAAAAbs/c5TECZ6RONM/s240-c/Tokyo%252520Smog.jpg", 237 | "https://lh3.googleusercontent.com/-FB-jfgREEfI/URqvJI3EXAI/AAAAAAAAAbs/XfyweiRF4v8/s240-c/Tufa%252520at%252520Night.jpg", 238 | "https://lh4.googleusercontent.com/-vngKD5Z1U8w/URqvJUCEgPI/AAAAAAAAAbs/ulxCMVcU6EU/s240-c/Valley%252520Sunset.jpg", 239 | "https://lh6.googleusercontent.com/-DOz5I2E2oMQ/URqvKMND1kI/AAAAAAAAAbs/Iqf0IsInleo/s240-c/Windmill%252520Sunrise.jpg", 240 | "https://lh5.googleusercontent.com/-biyiyWcJ9MU/URqvKculiAI/AAAAAAAAAbs/jyPsCplJOpE/s240-c/Windmill.jpg", 241 | "https://lh4.googleusercontent.com/-PDT167_xRdA/URqvK36mLcI/AAAAAAAAAbs/oi2ik9QseMI/s240-c/Windmills.jpg", 242 | "https://lh5.googleusercontent.com/-kI_QdYx7VlU/URqvLXCB6gI/AAAAAAAAAbs/N31vlZ6u89o/s240-c/Yet%252520Another%252520Rockaway%252520Sunset.jpg", 243 | "https://lh4.googleusercontent.com/-e9NHZ5k5MSs/URqvMIBZjtI/AAAAAAAAAbs/1fV810rDNfQ/s240-c/Yosemite%252520Tree.jpg", 244 | }; 245 | } 246 | -------------------------------------------------------------------------------- /Application/src/main/java/com/example/android/displayingbitmaps/ui/ImageDetailActivity.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.example.android.displayingbitmaps.ui; 18 | 19 | import android.annotation.TargetApi; 20 | import android.app.ActionBar; 21 | import android.os.Build.VERSION_CODES; 22 | import android.os.Bundle; 23 | import android.support.v4.app.Fragment; 24 | import android.support.v4.app.FragmentActivity; 25 | import android.support.v4.app.FragmentManager; 26 | import android.support.v4.app.FragmentStatePagerAdapter; 27 | import android.support.v4.app.NavUtils; 28 | import android.support.v4.view.ViewPager; 29 | import android.util.DisplayMetrics; 30 | import android.view.Menu; 31 | import android.view.MenuItem; 32 | import android.view.View; 33 | import android.view.View.OnClickListener; 34 | import android.view.WindowManager.LayoutParams; 35 | import android.widget.Toast; 36 | 37 | import com.example.android.displayingbitmaps.BuildConfig; 38 | import com.example.android.displayingbitmaps.R; 39 | import com.example.android.displayingbitmaps.provider.Images; 40 | import com.example.android.displayingbitmaps.util.ImageCache; 41 | import com.example.android.displayingbitmaps.util.ImageFetcher; 42 | import com.example.android.displayingbitmaps.util.Utils; 43 | 44 | public class ImageDetailActivity extends FragmentActivity implements OnClickListener { 45 | private static final String IMAGE_CACHE_DIR = "images"; 46 | public static final String EXTRA_IMAGE = "extra_image"; 47 | 48 | private ImagePagerAdapter mAdapter; 49 | private ImageFetcher mImageFetcher; 50 | private ViewPager mPager; 51 | 52 | @TargetApi(VERSION_CODES.HONEYCOMB) 53 | @Override 54 | public void onCreate(Bundle savedInstanceState) { 55 | if (BuildConfig.DEBUG) { 56 | Utils.enableStrictMode(); 57 | } 58 | super.onCreate(savedInstanceState); 59 | setContentView(R.layout.image_detail_pager); 60 | 61 | // Fetch screen height and width, to use as our max size when loading images as this 62 | // activity runs full screen 63 | final DisplayMetrics displayMetrics = new DisplayMetrics(); 64 | getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); 65 | final int height = displayMetrics.heightPixels; 66 | final int width = displayMetrics.widthPixels; 67 | 68 | // For this sample we'll use half of the longest width to resize our images. As the 69 | // image scaling ensures the image is larger than this, we should be left with a 70 | // resolution that is appropriate for both portrait and landscape. For best image quality 71 | // we shouldn't divide by 2, but this will use more memory and require a larger memory 72 | // cache. 73 | final int longest = (height > width ? height : width) / 2; 74 | 75 | ImageCache.ImageCacheParams cacheParams = 76 | new ImageCache.ImageCacheParams(this, IMAGE_CACHE_DIR); 77 | cacheParams.setMemCacheSizePercent(0.25f); // Set memory cache to 25% of app memory 78 | 79 | // The ImageFetcher takes care of loading images into our ImageView children asynchronously 80 | mImageFetcher = new ImageFetcher(this, longest); 81 | mImageFetcher.addImageCache(getSupportFragmentManager(), cacheParams); 82 | mImageFetcher.setImageFadeIn(false); 83 | 84 | // Set up ViewPager and backing adapter 85 | mAdapter = new ImagePagerAdapter(getSupportFragmentManager(), Images.imageUrls.length); 86 | mPager = (ViewPager) findViewById(R.id.pager); 87 | mPager.setAdapter(mAdapter); 88 | mPager.setPageMargin((int) getResources().getDimension(R.dimen.horizontal_page_margin)); 89 | mPager.setOffscreenPageLimit(2); 90 | 91 | // Set up activity to go full screen 92 | getWindow().addFlags(LayoutParams.FLAG_FULLSCREEN); 93 | 94 | // Enable some additional newer visibility and ActionBar features to create a more 95 | // immersive photo viewing experience 96 | if (Utils.hasHoneycomb()) { 97 | final ActionBar actionBar = getActionBar(); 98 | 99 | // Hide title text and set home as up 100 | actionBar.setDisplayShowTitleEnabled(false); 101 | actionBar.setDisplayHomeAsUpEnabled(true); 102 | 103 | // Hide and show the ActionBar as the visibility changes 104 | mPager.setOnSystemUiVisibilityChangeListener( 105 | new View.OnSystemUiVisibilityChangeListener() { 106 | @Override 107 | public void onSystemUiVisibilityChange(int vis) { 108 | if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) { 109 | actionBar.hide(); 110 | } else { 111 | actionBar.show(); 112 | } 113 | } 114 | }); 115 | 116 | // Start low profile mode and hide ActionBar 117 | mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); 118 | actionBar.hide(); 119 | } 120 | 121 | // Set the current item based on the extra passed in to this activity 122 | final int extraCurrentItem = getIntent().getIntExtra(EXTRA_IMAGE, -1); 123 | if (extraCurrentItem != -1) { 124 | mPager.setCurrentItem(extraCurrentItem); 125 | } 126 | } 127 | 128 | @Override 129 | public void onResume() { 130 | super.onResume(); 131 | mImageFetcher.setExitTasksEarly(false); 132 | } 133 | 134 | @Override 135 | protected void onPause() { 136 | super.onPause(); 137 | mImageFetcher.setExitTasksEarly(true); 138 | mImageFetcher.flushCache(); 139 | } 140 | 141 | @Override 142 | protected void onDestroy() { 143 | super.onDestroy(); 144 | mImageFetcher.closeCache(); 145 | } 146 | 147 | @Override 148 | public boolean onOptionsItemSelected(MenuItem item) { 149 | switch (item.getItemId()) { 150 | case android.R.id.home: 151 | NavUtils.navigateUpFromSameTask(this); 152 | return true; 153 | case R.id.clear_cache: 154 | mImageFetcher.clearCache(); 155 | Toast.makeText( 156 | this, R.string.clear_cache_complete_toast,Toast.LENGTH_SHORT).show(); 157 | return true; 158 | } 159 | return super.onOptionsItemSelected(item); 160 | } 161 | 162 | @Override 163 | public boolean onCreateOptionsMenu(Menu menu) { 164 | getMenuInflater().inflate(R.menu.main_menu, menu); 165 | return true; 166 | } 167 | 168 | /** 169 | * Called by the ViewPager child fragments to load images via the one ImageFetcher 170 | */ 171 | public ImageFetcher getImageFetcher() { 172 | return mImageFetcher; 173 | } 174 | 175 | /** 176 | * The main adapter that backs the ViewPager. A subclass of FragmentStatePagerAdapter as there 177 | * could be a large number of items in the ViewPager and we don't want to retain them all in 178 | * memory at once but create/destroy them on the fly. 179 | */ 180 | private class ImagePagerAdapter extends FragmentStatePagerAdapter { 181 | private final int mSize; 182 | 183 | public ImagePagerAdapter(FragmentManager fm, int size) { 184 | super(fm); 185 | mSize = size; 186 | } 187 | 188 | @Override 189 | public int getCount() { 190 | return mSize; 191 | } 192 | 193 | @Override 194 | public Fragment getItem(int position) { 195 | return ImageDetailFragment.newInstance(Images.imageUrls[position]); 196 | } 197 | } 198 | 199 | /** 200 | * Set on the ImageView in the ViewPager children fragments, to enable/disable low profile mode 201 | * when the ImageView is touched. 202 | */ 203 | @TargetApi(VERSION_CODES.HONEYCOMB) 204 | @Override 205 | public void onClick(View v) { 206 | final int vis = mPager.getSystemUiVisibility(); 207 | if ((vis & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) { 208 | mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); 209 | } else { 210 | mPager.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); 211 | } 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /Application/src/main/java/com/example/android/displayingbitmaps/ui/ImageDetailFragment.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.example.android.displayingbitmaps.ui; 18 | 19 | import android.os.Bundle; 20 | import android.support.v4.app.Fragment; 21 | import android.view.LayoutInflater; 22 | import android.view.View; 23 | import android.view.View.OnClickListener; 24 | import android.view.ViewGroup; 25 | import android.widget.ImageView; 26 | 27 | import com.example.android.displayingbitmaps.R; 28 | import com.example.android.displayingbitmaps.util.ImageFetcher; 29 | import com.example.android.displayingbitmaps.util.ImageWorker; 30 | import com.example.android.displayingbitmaps.util.Utils; 31 | 32 | /** 33 | * This fragment will populate the children of the ViewPager from {@link ImageDetailActivity}. 34 | */ 35 | public class ImageDetailFragment extends Fragment { 36 | private static final String IMAGE_DATA_EXTRA = "extra_image_data"; 37 | private String mImageUrl; 38 | private ImageView mImageView; 39 | private ImageFetcher mImageFetcher; 40 | 41 | /** 42 | * Factory method to generate a new instance of the fragment given an image number. 43 | * 44 | * @param imageUrl The image url to load 45 | * @return A new instance of ImageDetailFragment with imageNum extras 46 | */ 47 | public static ImageDetailFragment newInstance(String imageUrl) { 48 | final ImageDetailFragment f = new ImageDetailFragment(); 49 | 50 | final Bundle args = new Bundle(); 51 | args.putString(IMAGE_DATA_EXTRA, imageUrl); 52 | f.setArguments(args); 53 | 54 | return f; 55 | } 56 | 57 | /** 58 | * Empty constructor as per the Fragment documentation 59 | */ 60 | public ImageDetailFragment() {} 61 | 62 | /** 63 | * Populate image using a url from extras, use the convenience factory method 64 | * {@link ImageDetailFragment#newInstance(String)} to create this fragment. 65 | */ 66 | @Override 67 | public void onCreate(Bundle savedInstanceState) { 68 | super.onCreate(savedInstanceState); 69 | mImageUrl = getArguments() != null ? getArguments().getString(IMAGE_DATA_EXTRA) : null; 70 | } 71 | 72 | @Override 73 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 74 | Bundle savedInstanceState) { 75 | // Inflate and locate the main ImageView 76 | final View v = inflater.inflate(R.layout.image_detail_fragment, container, false); 77 | mImageView = (ImageView) v.findViewById(R.id.imageView); 78 | return v; 79 | } 80 | 81 | @Override 82 | public void onActivityCreated(Bundle savedInstanceState) { 83 | super.onActivityCreated(savedInstanceState); 84 | 85 | // Use the parent activity to load the image asynchronously into the ImageView (so a single 86 | // cache can be used over all pages in the ViewPager 87 | if (ImageDetailActivity.class.isInstance(getActivity())) { 88 | mImageFetcher = ((ImageDetailActivity) getActivity()).getImageFetcher(); 89 | mImageFetcher.loadImage(mImageUrl, mImageView); 90 | } 91 | 92 | // Pass clicks on the ImageView to the parent activity to handle 93 | if (OnClickListener.class.isInstance(getActivity()) && Utils.hasHoneycomb()) { 94 | mImageView.setOnClickListener((OnClickListener) getActivity()); 95 | } 96 | } 97 | 98 | @Override 99 | public void onDestroy() { 100 | super.onDestroy(); 101 | if (mImageView != null) { 102 | // Cancel any pending image work 103 | ImageWorker.cancelWork(mImageView); 104 | mImageView.setImageDrawable(null); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Application/src/main/java/com/example/android/displayingbitmaps/ui/ImageGridActivity.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.example.android.displayingbitmaps.ui; 18 | 19 | import android.os.Bundle; 20 | import android.support.v4.app.FragmentActivity; 21 | import android.support.v4.app.FragmentTransaction; 22 | 23 | import org.deeplearning4j.datasets.iterator.DataSetIterator; 24 | import org.deeplearning4j.datasets.iterator.impl.MnistDataSetIterator; 25 | import org.deeplearning4j.eval.Evaluation; 26 | import org.deeplearning4j.nn.api.OptimizationAlgorithm; 27 | import org.deeplearning4j.nn.conf.GradientNormalization; 28 | import org.deeplearning4j.nn.conf.MultiLayerConfiguration; 29 | import org.deeplearning4j.nn.conf.NeuralNetConfiguration; 30 | import org.deeplearning4j.nn.conf.layers.DenseLayer; 31 | import org.deeplearning4j.nn.conf.layers.OutputLayer; 32 | import org.deeplearning4j.nn.multilayer.MultiLayerNetwork; 33 | import org.deeplearning4j.nn.weights.WeightInit; 34 | import org.deeplearning4j.optimize.api.IterationListener; 35 | import org.deeplearning4j.optimize.listeners.ScoreIterationListener; 36 | import org.nd4j.linalg.api.ndarray.INDArray; 37 | import org.nd4j.linalg.dataset.DataSet; 38 | import org.nd4j.linalg.dataset.SplitTestAndTrain; 39 | import org.nd4j.linalg.factory.Nd4j; 40 | import org.nd4j.linalg.lossfunctions.LossFunctions.LossFunction; 41 | import org.slf4j.Logger; 42 | import org.slf4j.LoggerFactory; 43 | 44 | import java.util.*; 45 | 46 | /** 47 | * Simple FragmentActivity to hold the main {@link ImageGridFragment} and not much else. 48 | */ 49 | public class ImageGridActivity extends FragmentActivity { 50 | private static final String TAG = "ImageGridActivity"; 51 | 52 | private static Logger log = LoggerFactory.getLogger(ImageGridActivity.class); 53 | 54 | @Override 55 | protected void onCreate(Bundle savedInstanceState) { 56 | // if (BuildConfig.DEBUG) { 57 | // Utils.enableStrictMode(); 58 | // } 59 | super.onCreate(savedInstanceState); 60 | 61 | if (getSupportFragmentManager().findFragmentByTag(TAG) == null) { 62 | final FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 63 | ft.add(android.R.id.content, new ImageGridFragment(), TAG); 64 | ft.commit(); 65 | } 66 | 67 | try { 68 | trainMLP(); 69 | } catch (Exception e) { 70 | e.printStackTrace(); 71 | } 72 | } 73 | 74 | public void trainMLP() throws Exception { 75 | Nd4j.ENFORCE_NUMERICAL_STABILITY = true; 76 | final int numRows = 28; 77 | final int numColumns = 28; 78 | int outputNum = 10; 79 | int numSamples = 10000; 80 | int batchSize = 500; 81 | int iterations = 10; 82 | int seed = 123; 83 | int listenerFreq = iterations / 5; 84 | int splitTrainNum = (int) (batchSize * .8); 85 | DataSet mnist; 86 | SplitTestAndTrain trainTest; 87 | DataSet trainInput; 88 | ListAsyncTask enables proper and easy use of the UI thread. This class allows to 56 | * perform background operations and publish results on the UI thread without 57 | * having to manipulate threads and/or handlers.
58 | * 59 | *AsyncTask is designed to be a helper class around {@link Thread} and {@link android.os.Handler}
60 | * and does not constitute a generic threading framework. AsyncTasks should ideally be
61 | * used for short operations (a few seconds at the most.) If you need to keep threads
62 | * running for long periods of time, it is highly recommended you use the various APIs
63 | * provided by the java.util.concurrent
pacakge such as {@link java.util.concurrent.Executor},
64 | * {@link java.util.concurrent.ThreadPoolExecutor} and {@link java.util.concurrent.FutureTask}.
An asynchronous task is defined by a computation that runs on a background thread and
67 | * whose result is published on the UI thread. An asynchronous task is defined by 3 generic
68 | * types, called Params
, Progress
and Result
,
69 | * and 4 steps, called onPreExecute
, doInBackground
,
70 | * onProgressUpdate
and onPostExecute
.
For more information about using tasks and threads, read the 75 | * Processes and 76 | * Threads developer guide.
77 | *AsyncTask must be subclassed to be used. The subclass will override at least 81 | * one method ({@link #doInBackground}), and most often will override a 82 | * second one ({@link #onPostExecute}.)
83 | * 84 | *Here is an example of subclassing:
85 | *86 | * private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { 87 | * protected Long doInBackground(URL... urls) { 88 | * int count = urls.length; 89 | * long totalSize = 0; 90 | * for (int i = 0; i < count; i++) { 91 | * totalSize += Downloader.downloadFile(urls[i]); 92 | * publishProgress((int) ((i / (float) count) * 100)); 93 | * // Escape early if cancel() is called 94 | * if (isCancelled()) break; 95 | * } 96 | * return totalSize; 97 | * } 98 | * 99 | * protected void onProgressUpdate(Integer... progress) { 100 | * setProgressPercent(progress[0]); 101 | * } 102 | * 103 | * protected void onPostExecute(Long result) { 104 | * showDialog("Downloaded " + result + " bytes"); 105 | * } 106 | * } 107 | *108 | * 109 | *
Once created, a task is executed very simply:
110 | *111 | * new DownloadFilesTask().execute(url1, url2, url3); 112 | *113 | * 114 | *
The three types used by an asynchronous task are the following:
116 | *Params
, the type of the parameters sent to the task upon
118 | * execution.Progress
, the type of the progress units published during
120 | * the background computation.Result
, the type of the result of the background
122 | * computation.Not all types are always used by an asynchronous task. To mark a type as unused, 125 | * simply use the type {@link Void}:
126 | *127 | * private class MyTask extends AsyncTask<Void, Void, Void> { ... } 128 | *129 | * 130 | *
When an asynchronous task is executed, the task goes through 4 steps:
132 | *A task can be cancelled at any time by invoking {@link #cancel(boolean)}. Invoking 156 | * this method will cause subsequent calls to {@link #isCancelled()} to return true. 157 | * After invoking this method, {@link #onCancelled(Object)}, instead of 158 | * {@link #onPostExecute(Object)} will be invoked after {@link #doInBackground(Object[])} 159 | * returns. To ensure that a task is cancelled as quickly as possible, you should always 160 | * check the return value of {@link #isCancelled()} periodically from 161 | * {@link #doInBackground(Object[])}, if possible (inside a loop for instance.)
162 | * 163 | *There are a few threading rules that must be followed for this class to 165 | * work properly:
166 | *AsyncTask guarantees that all callback calls are synchronized in such a way that the following 179 | * operations are safe without explicit synchronizations.
180 | *When first introduced, AsyncTasks were executed serially on a single background 189 | * thread. Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed 190 | * to a pool of threads allowing multiple tasks to operate in parallel. Starting with 191 | * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are executed on a single 192 | * thread to avoid common application errors caused by parallel execution.
193 | *If you truly want parallel execution, you can invoke 194 | * {@link #executeOnExecutor(java.util.concurrent.Executor, Object[])} with 195 | * {@link #THREAD_POOL_EXECUTOR}.
196 | */ 197 | public abstract class AsyncTaskRuns on the UI thread after {@link #doInBackground}. The 387 | * specified result is the value returned by {@link #doInBackground}.
388 | * 389 | *This method won't be invoked if the task was cancelled.
390 | * 391 | * @param result The result of the operation computed by {@link #doInBackground}. 392 | * 393 | * @see #onPreExecute 394 | * @see #doInBackground 395 | * @see #onCancelled(Object) 396 | */ 397 | @SuppressWarnings({"UnusedDeclaration"}) 398 | protected void onPostExecute(Result result) { 399 | } 400 | 401 | /** 402 | * Runs on the UI thread after {@link #publishProgress} is invoked. 403 | * The specified values are the values passed to {@link #publishProgress}. 404 | * 405 | * @param values The values indicating progress. 406 | * 407 | * @see #publishProgress 408 | * @see #doInBackground 409 | */ 410 | @SuppressWarnings({"UnusedDeclaration"}) 411 | protected void onProgressUpdate(Progress... values) { 412 | } 413 | 414 | /** 415 | *Runs on the UI thread after {@link #cancel(boolean)} is invoked and 416 | * {@link #doInBackground(Object[])} has finished.
417 | * 418 | *The default implementation simply invokes {@link #onCancelled()} and
419 | * ignores the result. If you write your own implementation, do not call
420 | * super.onCancelled(result)
.
Applications should preferably override {@link #onCancelled(Object)}. 435 | * This method is invoked by the default implementation of 436 | * {@link #onCancelled(Object)}.
437 | * 438 | *Runs on the UI thread after {@link #cancel(boolean)} is invoked and 439 | * {@link #doInBackground(Object[])} has finished.
440 | * 441 | * @see #onCancelled(Object) 442 | * @see #cancel(boolean) 443 | * @see #isCancelled() 444 | */ 445 | protected void onCancelled() { 446 | } 447 | 448 | /** 449 | * Returns true if this task was cancelled before it completed 450 | * normally. If you are calling {@link #cancel(boolean)} on the task, 451 | * the value returned by this method should be checked periodically from 452 | * {@link #doInBackground(Object[])} to end the task as soon as possible. 453 | * 454 | * @return true if task was cancelled before it completed 455 | * 456 | * @see #cancel(boolean) 457 | */ 458 | public final boolean isCancelled() { 459 | return mCancelled.get(); 460 | } 461 | 462 | /** 463 | *Attempts to cancel execution of this task. This attempt will 464 | * fail if the task has already completed, already been cancelled, 465 | * or could not be cancelled for some other reason. If successful, 466 | * and this task has not started when cancel is called, 467 | * this task should never run. If the task has already started, 468 | * then the mayInterruptIfRunning parameter determines 469 | * whether the thread executing this task should be interrupted in 470 | * an attempt to stop the task.
471 | * 472 | *Calling this method will result in {@link #onCancelled(Object)} being 473 | * invoked on the UI thread after {@link #doInBackground(Object[])} 474 | * returns. Calling this method guarantees that {@link #onPostExecute(Object)} 475 | * is never invoked. After invoking this method, you should check the 476 | * value returned by {@link #isCancelled()} periodically from 477 | * {@link #doInBackground(Object[])} to finish the task as early as 478 | * possible.
479 | * 480 | * @param mayInterruptIfRunning true if the thread executing this 481 | * task should be interrupted; otherwise, in-progress tasks are allowed 482 | * to complete. 483 | * 484 | * @return false if the task could not be cancelled, 485 | * typically because it has already completed normally; 486 | * true otherwise 487 | * 488 | * @see #isCancelled() 489 | * @see #onCancelled(Object) 490 | */ 491 | public final boolean cancel(boolean mayInterruptIfRunning) { 492 | mCancelled.set(true); 493 | return mFuture.cancel(mayInterruptIfRunning); 494 | } 495 | 496 | /** 497 | * Waits if necessary for the computation to complete, and then 498 | * retrieves its result. 499 | * 500 | * @return The computed result. 501 | * 502 | * @throws java.util.concurrent.CancellationException If the computation was cancelled. 503 | * @throws java.util.concurrent.ExecutionException If the computation threw an exception. 504 | * @throws InterruptedException If the current thread was interrupted 505 | * while waiting. 506 | */ 507 | public final Result get() throws InterruptedException, ExecutionException { 508 | return mFuture.get(); 509 | } 510 | 511 | /** 512 | * Waits if necessary for at most the given time for the computation 513 | * to complete, and then retrieves its result. 514 | * 515 | * @param timeout Time to wait before cancelling the operation. 516 | * @param unit The time unit for the timeout. 517 | * 518 | * @return The computed result. 519 | * 520 | * @throws java.util.concurrent.CancellationException If the computation was cancelled. 521 | * @throws java.util.concurrent.ExecutionException If the computation threw an exception. 522 | * @throws InterruptedException If the current thread was interrupted 523 | * while waiting. 524 | * @throws java.util.concurrent.TimeoutException If the wait timed out. 525 | */ 526 | public final Result get(long timeout, TimeUnit unit) throws InterruptedException, 527 | ExecutionException, TimeoutException { 528 | return mFuture.get(timeout, unit); 529 | } 530 | 531 | /** 532 | * Executes the task with the specified parameters. The task returns 533 | * itself (this) so that the caller can keep a reference to it. 534 | * 535 | *Note: this function schedules the task on a queue for a single background 536 | * thread or pool of threads depending on the platform version. When first 537 | * introduced, AsyncTasks were executed serially on a single background thread. 538 | * Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed 539 | * to a pool of threads allowing multiple tasks to operate in parallel. Starting 540 | * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are back to being 541 | * executed on a single thread to avoid common application errors caused 542 | * by parallel execution. If you truly want parallel execution, you can use 543 | * the {@link #executeOnExecutor} version of this method 544 | * with {@link #THREAD_POOL_EXECUTOR}; however, see commentary there for warnings 545 | * on its use. 546 | * 547 | *
This method must be invoked on the UI thread.
548 | *
549 | * @param params The parameters of the task.
550 | *
551 | * @return This instance of AsyncTask.
552 | *
553 | * @throws IllegalStateException If {@link #getStatus()} returns either
554 | * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
555 | *
556 | * @see #executeOnExecutor(java.util.concurrent.Executor, Object[])
557 | * @see #execute(Runnable)
558 | */
559 | public final AsyncTask This method is typically used with {@link #THREAD_POOL_EXECUTOR} to
568 | * allow multiple tasks to run in parallel on a pool of threads managed by
569 | * AsyncTask, however you can also use your own {@link java.util.concurrent.Executor} for custom
570 | * behavior.
571 | *
572 | * Warning: Allowing multiple tasks to run in parallel from
573 | * a thread pool is generally not what one wants, because the order
574 | * of their operation is not defined. For example, if these tasks are used
575 | * to modify any state in common (such as writing a file due to a button click),
576 | * there are no guarantees on the order of the modifications.
577 | * Without careful work it is possible in rare cases for the newer version
578 | * of the data to be over-written by an older one, leading to obscure data
579 | * loss and stability issues. Such changes are best
580 | * executed in serial; to guarantee such work is serialized regardless of
581 | * platform version you can use this function with {@link #SERIAL_EXECUTOR}.
582 | *
583 | * This method must be invoked on the UI thread.
584 | *
585 | * @param exec The executor to use. {@link #THREAD_POOL_EXECUTOR} is available as a
586 | * convenient process-wide thread pool for tasks that are loosely coupled.
587 | * @param params The parameters of the task.
588 | *
589 | * @return This instance of AsyncTask.
590 | *
591 | * @throws IllegalStateException If {@link #getStatus()} returns either
592 | * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
593 | *
594 | * @see #execute(Object[])
595 | */
596 | public final AsyncTask