├── .gitignore ├── ICDispatch ├── AndroidManifest.xml ├── ic_launcher-web.png ├── proguard-project.txt ├── project.properties ├── res │ ├── drawable-hdpi │ │ └── ic_launcher.png │ ├── drawable-mdpi │ │ └── ic_launcher.png │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ ├── drawable-xxhdpi │ │ └── ic_launcher.png │ └── values │ │ ├── strings.xml │ │ └── styles.xml └── src │ └── ICDispatch │ ├── ICBlock.java │ ├── ICConCurrentQueue.java │ ├── ICDispatachMainQueue.java │ ├── ICDispatch.java │ ├── ICDispatchApplication.java │ ├── ICForkJoinQueue.java │ └── ICQueue.java └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Eclipse project files 19 | .classpath 20 | .project 21 | -------------------------------------------------------------------------------- /ICDispatch/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 9 | 10 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ICDispatch/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johanrisch/ICDispatch/b1f5a8d4015bd946ae47cc7e4057755b72fe1abf/ICDispatch/ic_launcher-web.png -------------------------------------------------------------------------------- /ICDispatch/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /ICDispatch/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-8 15 | android.library=true 16 | -------------------------------------------------------------------------------- /ICDispatch/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johanrisch/ICDispatch/b1f5a8d4015bd946ae47cc7e4057755b72fe1abf/ICDispatch/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /ICDispatch/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johanrisch/ICDispatch/b1f5a8d4015bd946ae47cc7e4057755b72fe1abf/ICDispatch/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /ICDispatch/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johanrisch/ICDispatch/b1f5a8d4015bd946ae47cc7e4057755b72fe1abf/ICDispatch/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ICDispatch/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johanrisch/ICDispatch/b1f5a8d4015bd946ae47cc7e4057755b72fe1abf/ICDispatch/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ICDispatch/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ICDispatch 4 | 5 | 6 | -------------------------------------------------------------------------------- /ICDispatch/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /ICDispatch/src/ICDispatch/ICBlock.java: -------------------------------------------------------------------------------- 1 | package ICDispatch; 2 | /** 3 | * Copyright 2013 Johan Risch (johan.risch@gmail.com) and Simon Evertsson (simon.evertsson2@gmail.com) 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 19 | /** 20 | * Created by johanrisch on 6/18/13. 21 | *
22 | * This is the smallest stone of ICDispatch. An ICBlock contains the code to be executed 23 | * on a selected Queue. 24 | */ 25 | public interface ICBlock extends Runnable{ 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /ICDispatch/src/ICDispatch/ICConCurrentQueue.java: -------------------------------------------------------------------------------- 1 | package ICDispatch; 2 | /** 3 | * Copyright 2013 Johan Risch (johan.risch@gmail.com) and Simon Evertsson (simon.evertsson2@gmail.com) 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | import java.util.concurrent.BlockingQueue; 18 | import java.util.concurrent.ExecutorService; 19 | import java.util.concurrent.Executors; 20 | 21 | /** 22 | * 23 | * @author johanrisch Concurrent version of the ICQueue All ICBlocks sent to 24 | * this queue will be scheduled for execution immediately. There is 25 | * absolutely no guarantee that the blocks will be executed in the order 26 | * they where added. 27 | */ 28 | 29 | public class ICConCurrentQueue extends ICQueue { 30 | 31 | private ExecutorService mExecutor; 32 | 33 | public ICConCurrentQueue(BlockingQueue queue, int maxThreads) { 34 | super(queue); 35 | 36 | int cores = maxThreads; 37 | if (cores == 0) { 38 | Runtime.getRuntime().availableProcessors(); 39 | } 40 | this.mExecutor = Executors.newFixedThreadPool(4); 41 | } 42 | 43 | @Override 44 | public void run() { 45 | ICBlock currentBlock = null; 46 | 47 | while (running) { 48 | try { 49 | currentBlock = mQueue.take(); 50 | mExecutor.execute(currentBlock); 51 | } catch (InterruptedException e) { 52 | e.printStackTrace(); 53 | } 54 | 55 | } 56 | 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /ICDispatch/src/ICDispatch/ICDispatachMainQueue.java: -------------------------------------------------------------------------------- 1 | package ICDispatch; 2 | /** 3 | * Copyright 2013 Johan Risch (johan.risch@gmail.com) and Simon Evertsson (simon.evertsson2@gmail.com) 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | import java.util.concurrent.BlockingQueue; 18 | import java.util.concurrent.LinkedBlockingQueue; 19 | 20 | import android.os.Handler; 21 | /** 22 | * 23 | * @author johanrisch 24 | * ICDispatachMainQueue is the queue that runs blocks on the main thread. 25 | * In order to improve the FPS performance there is a parameter that limits the amount of new Blocks to be sent 26 | * each iteration of the run loop. This is done by having a {@link MainRunnablePool} containing {@link MainRunnable} that 27 | * will add itself back to the pool once they've been executed. 28 | */ 29 | public class ICDispatachMainQueue extends ICQueue { 30 | private Handler mHandler; 31 | private MainRunnablePool mRunnablePool; 32 | private int mMaxNumberPerLoop; 33 | 34 | public ICDispatachMainQueue(BlockingQueue queue, Handler mainThreadHandler, int maxNumberPerLoop) { 35 | super(queue); 36 | this.mMaxNumberPerLoop = maxNumberPerLoop; 37 | this.mHandler = mainThreadHandler; 38 | } 39 | 40 | @Override 41 | public void run() { 42 | mRunnablePool = new MainRunnablePool(mMaxNumberPerLoop); 43 | ICBlock currentBlock = null; 44 | 45 | while (running) { 46 | try { 47 | currentBlock = mQueue.take(); 48 | mHandler.post(mRunnablePool.getRunnable(currentBlock)); 49 | } catch (InterruptedException e) { 50 | e.printStackTrace(); 51 | } 52 | 53 | } 54 | } 55 | 56 | private class MainRunnable implements Runnable { 57 | private ICBlock mBlock; 58 | private MainRunnablePool mPool; 59 | 60 | public MainRunnable(MainRunnablePool mainRunnablePool) { 61 | this.mPool = mainRunnablePool; 62 | } 63 | 64 | public void setBlock(ICBlock block) { 65 | this.mBlock = block; 66 | } 67 | 68 | @Override 69 | public void run() { 70 | mBlock.run(); 71 | mPool.returnRunnable(this); 72 | 73 | } 74 | 75 | } 76 | 77 | private class MainRunnablePool { 78 | private LinkedBlockingQueue mPool; 79 | 80 | public MainRunnablePool(int poolSize) { 81 | this.mPool = new LinkedBlockingQueue(); 82 | for (int i = 0; i < poolSize; i++) { 83 | mPool.add(new MainRunnable(this)); 84 | } 85 | } 86 | 87 | public MainRunnable getRunnable(ICBlock block) { 88 | try { 89 | MainRunnable ret = mPool.take(); 90 | ret.setBlock(block); 91 | return ret; 92 | } catch (InterruptedException e) { 93 | // TODO Auto-generated catch block 94 | e.printStackTrace(); 95 | } 96 | return null; 97 | } 98 | 99 | public void returnRunnable(MainRunnable r) { 100 | mPool.add(r); 101 | } 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /ICDispatch/src/ICDispatch/ICDispatch.java: -------------------------------------------------------------------------------- 1 | package ICDispatch; 2 | /** 3 | * Copyright 2013 Johan Risch (johan.risch@gmail.com) and Simon Evertsson (simon.evertsson2@gmail.com) 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | import java.lang.reflect.InvocationTargetException; 18 | import java.lang.reflect.Method; 19 | import java.util.Collection; 20 | import java.util.HashMap; 21 | import java.util.concurrent.LinkedBlockingQueue; 22 | 23 | import android.os.Handler; 24 | import android.os.Looper; 25 | 26 | /** 27 | * Created by johanrisch on 6/18/13. 28 | */ 29 | public class ICDispatch { 30 | /** 31 | * The normal priority thread. 32 | */ 33 | private static ICQueue mNormalThread; 34 | /** 35 | * The low priority thread 36 | */ 37 | private ICQueue mLowThread; 38 | /** 39 | * the high priority thread. 40 | */ 41 | private ICQueue mHighThread; 42 | 43 | private ICDispatachMainQueue mMainQueue; 44 | 45 | private ICConCurrentQueue mConcurrentThread; 46 | 47 | /** 48 | * Static int telling {@see ICDispatch} to execute on the high priority 49 | * thread Constant value = 0 50 | */ 51 | public static final int HIGH = 0; 52 | /** 53 | * Static int telling {@see ICDispatch} to execute on the normal priority 54 | * thread Constant value = 1 55 | */ 56 | public static final int NORMAL = 1; 57 | /** 58 | * Static int telling {@see ICDispatch} to execute on the low priority 59 | * thread Constant value = 2 60 | */ 61 | public static final int LOW = 2; 62 | /** 63 | * Static int telling {@see ICDispatch} to execute on the UI thread Constant 64 | * value = 3 65 | */ 66 | public static final int MAIN = 3; 67 | 68 | public static final int CONCURRENT = 4; 69 | /** 70 | * Handler used to execute on UI thread. 71 | */ 72 | private Handler mMainHandler; 73 | /** 74 | * Map used to cache method mappings. 75 | */ 76 | private HashMap mMethodMap; 77 | /** 78 | * This parameter sets the maximum messages to be queued per UI thread run 79 | * loop. Default is 10. 80 | */ 81 | private int mMaxMessagesOnUILoop = 10; 82 | 83 | /** 84 | * This parameter sets the maximum number of hashed methods. Default is 250 85 | */ 86 | private int mMaxMethodsHashed = 250; 87 | /** 88 | * This parameter sets the maximum number of threads in the concurrent 89 | * queue. The default (0) is number of cores. 90 | */ 91 | private int mMaxThreadsInConcurrent = 0; 92 | 93 | private boolean isInitialized = false; 94 | 95 | /** 96 | * initiates ICDispatch. MUST be called at before scheduling blocks. 97 | */ 98 | public void initICDispatch() { 99 | 100 | mConcurrentThread = new ICConCurrentQueue(new LinkedBlockingQueue(), 101 | mMaxThreadsInConcurrent); 102 | mConcurrentThread.setPriority(Thread.NORM_PRIORITY); 103 | mConcurrentThread.start(); 104 | 105 | mHighThread = new ICQueue(new LinkedBlockingQueue()); 106 | mHighThread.setPriority(Thread.MAX_PRIORITY); 107 | mHighThread.start(); 108 | 109 | mMainHandler = new Handler(); 110 | mMainQueue = new ICDispatachMainQueue(new LinkedBlockingQueue(), mMainHandler, 111 | mMaxMessagesOnUILoop); 112 | mMainQueue.setPriority(Thread.MAX_PRIORITY); 113 | mMainQueue.start(); 114 | 115 | mNormalThread = new ICQueue(new LinkedBlockingQueue()); 116 | mNormalThread.setPriority(Thread.NORM_PRIORITY); 117 | mNormalThread.start(); 118 | 119 | mLowThread = new ICQueue(new LinkedBlockingQueue()); 120 | mLowThread.setPriority(Thread.MIN_PRIORITY); 121 | mLowThread.start(); 122 | 123 | mMethodMap = new HashMap(mMaxMethodsHashed); 124 | 125 | isInitialized = true; 126 | } 127 | 128 | public int getMaxMessagesOnUILoop() { 129 | return mMaxMessagesOnUILoop; 130 | } 131 | /** 132 | * Sets the maximum number of messages per UI run loop. If more than max {@link ICBlock} is 133 | * dispatched to the main thread in one run loop the blocks will wait on a separate thread until next run loop. 134 | * @param max the maximum number of {@link ICBlock} in queue on the main thread. Default = 10 135 | * @throws RuntimeException if this method is called from the main thread OR before ICDispatch.initICDispatch has been called. 136 | */ 137 | public void setMaxMessagesOnUILoop(int max) throws RuntimeException{ 138 | checkForThreadException("setMaxMessagesOnUILoop"); 139 | checkForInitException("setMaxMessagesOnUILoop"); 140 | mMaxMessagesOnUILoop = max; 141 | } 142 | 143 | public int getMaxMethodsHashed() { 144 | return mMaxMethodsHashed; 145 | } 146 | /** 147 | * Sets the maximum number of hashed methods. 148 | * @param max number of hashed methods. default = 250 149 | * @throws RuntimeException if this method is called from the main thread OR before ICDispatch.initICDispatch has been called. 150 | */ 151 | public void setMaxMethodsHashed(int max) throws RuntimeException { 152 | checkForThreadException("setMaxMethodsHashed"); 153 | checkForInitException("setMaxMethodsHashed"); 154 | mMaxMethodsHashed = max; 155 | } 156 | 157 | public int getMaxThreadsInConcurrent() { 158 | return mMaxThreadsInConcurrent; 159 | } 160 | /** 161 | * Sets the maximum number of threads in the concurrent queue. 162 | * @param max number of threads in the concurrent queue. Default is the number of cores on the current device. 163 | * @throws RuntimeException if this method is called from the main thread OR before ICDispatch.initICDispatch has been called. 164 | */ 165 | public void setMaxThreadsInConcurrent(int max) throws RuntimeException{ 166 | checkForThreadException("setMaxThreadsInConcurrent"); 167 | checkForInitException("setMaxThreadsInConcurrent"); 168 | mMaxThreadsInConcurrent = max; 169 | } 170 | 171 | private void checkForInitException(String method) throws RuntimeException { 172 | if (isInitialized) { 173 | throw new RuntimeException("Method " + method + " called after initialisation"); 174 | } 175 | } 176 | private void checkForThreadException(String method){ 177 | if (Looper.myLooper() != Looper.getMainLooper()) { 178 | throw new RuntimeException("Method setMaxMethodsHashed not called from UI thread."); 179 | } 180 | } 181 | 182 | /** 183 | * Schedules a block for execution on the given queue. 184 | * 185 | * @param block 186 | * the block to be executed on the chosen queue 187 | * @param queue 188 | * the queue to execute the supplied block on. 189 | * @return true if the enqueueing was successfull. 190 | * @throws RuntimeException 191 | * if the supplied queue does not exist. 192 | */ 193 | public boolean executeOn(int queue, final ICBlock block) { 194 | switch (queue) { 195 | case HIGH: 196 | mHighThread.putBlock(block); 197 | break; 198 | case NORMAL: 199 | mNormalThread.putBlock(block); 200 | break; 201 | case LOW: 202 | mLowThread.putBlock(block); 203 | break; 204 | case MAIN: 205 | mMainQueue.putBlock(block); 206 | break; 207 | case CONCURRENT: 208 | mConcurrentThread.putBlock(block); 209 | break; 210 | default: 211 | throw new RuntimeException("Invalid thread ID, " + queue + 212 | " please supply one of LOW, NORMAL, HIGH, MAIN or CONCURRENT"); 213 | } 214 | return true; 215 | } 216 | 217 | public void executeAllOn(int queue, Collection blocks) { 218 | switch (queue) { 219 | case HIGH: 220 | mHighThread.putAll(blocks); 221 | break; 222 | case NORMAL: 223 | mNormalThread.putAll(blocks); 224 | break; 225 | case LOW: 226 | mLowThread.putAll(blocks); 227 | break; 228 | case MAIN: 229 | mMainQueue.putAll(blocks); 230 | break; 231 | case CONCURRENT: 232 | mConcurrentThread.putAll(blocks); 233 | break; 234 | default: 235 | throw new RuntimeException("Invalid thread ID, " + queue + 236 | " please supply one of LOW, NORMAL, HIGH, MAIN or CONCURRENT"); 237 | } 238 | } 239 | 240 | /** 241 | * Schedules a method for execution on the supplied thread. ICDispatch keeps 242 | * an internal Hashmap of method name and containing class in order to speed 243 | * up consecutive calls to the method. At the moment polymorphism is not 244 | * supported. 245 | * 246 | * @param queue 247 | * that the method execution should be put in. 248 | * @param instance 249 | * the instance of the object that the method should be executed 250 | * on. 251 | * @param name 252 | * the name of the method to execute. 253 | * @param args 254 | * the arguments for the method. 255 | * @return true if the execution was successful. 256 | * @throws NoSuchMethodException 257 | */ 258 | @SuppressWarnings("rawtypes") 259 | public boolean executeMethodOn(int queue, final Object instance, String name, 260 | final Object... args) throws NoSuchMethodException { 261 | Method m = mMethodMap.get(instance.getClass().getName() + name); 262 | if (m == null) { 263 | // Method is not cached find the method... 264 | // TODO- handle case when hashmap of methods is too large. 265 | Class[] classes = null; 266 | if (args.length > 0) { 267 | classes = new Class[args.length]; 268 | for (int i = 0; i < classes.length; i++) { 269 | classes[i] = args[i].getClass(); 270 | } 271 | } 272 | m = instance.getClass().getMethod(name, classes); 273 | 274 | mMethodMap.put(instance.getClass().getName() + name, m); 275 | } 276 | final Method finalM = m; 277 | executeOn(queue, new ICBlock() { 278 | @Override 279 | public void run() { 280 | try { 281 | finalM.invoke(instance, args); 282 | } catch (IllegalAccessException e) { 283 | e.printStackTrace(); 284 | } catch (InvocationTargetException e) { 285 | e.printStackTrace(); 286 | } 287 | } 288 | }); 289 | 290 | return true; 291 | } 292 | } 293 | -------------------------------------------------------------------------------- /ICDispatch/src/ICDispatch/ICDispatchApplication.java: -------------------------------------------------------------------------------- 1 | package ICDispatch; 2 | /** 3 | * Copyright 2013 Johan Risch (johan.risch@gmail.com) and Simon Evertsson (simon.evertsson2@gmail.com) 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | import android.app.Application; 18 | 19 | /** 20 | * Created by johanrisch on 6/21/13. 21 | */ 22 | public class ICDispatchApplication extends Application{ 23 | protected static ICDispatch sICDispatch; 24 | 25 | @Override 26 | public void onCreate() { 27 | super.onCreate(); 28 | sICDispatch = new ICDispatch(); 29 | initICDispatch(); 30 | sICDispatch.initICDispatch(); 31 | } 32 | public static boolean executeOn(int queue, ICBlock block){ 33 | return sICDispatch.executeOn(queue,block); 34 | } 35 | public static boolean executeMethodOn(int queue,Object instance, String methodName, Object... args) throws NoSuchMethodException{ 36 | return sICDispatch.executeMethodOn(queue,instance,methodName,args); 37 | } 38 | /** 39 | * Override this method if you want to initialize {@link ICDispatch} with custom params. 40 | * 41 | */ 42 | protected void initICDispatch(){ 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ICDispatch/src/ICDispatch/ICForkJoinQueue.java: -------------------------------------------------------------------------------- 1 | package ICDispatch; 2 | 3 | import java.util.concurrent.BlockingQueue; 4 | 5 | public class ICForkJoinQueue extends ICConCurrentQueue { 6 | 7 | public ICForkJoinQueue(BlockingQueue queue, int maxThreads) { 8 | super(queue, maxThreads); 9 | } 10 | 11 | 12 | } 13 | -------------------------------------------------------------------------------- /ICDispatch/src/ICDispatch/ICQueue.java: -------------------------------------------------------------------------------- 1 | package ICDispatch; 2 | /** 3 | * Copyright 2013 Johan Risch (johan.risch@gmail.com) and Simon Evertsson (simon.evertsson2@gmail.com) 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | import java.util.Collection; 19 | import java.util.concurrent.BlockingQueue; 20 | 21 | /** 22 | * Created by johanrisch on 6/18/13. 23 | */ 24 | 25 | /** 26 | * The thread class used by {@see ICDispatch} to execute {@see ICBlock} on. 27 | */ 28 | public class ICQueue extends Thread{ 29 | /** 30 | * The internal {@see BlockingQueue} for the thread. 31 | */ 32 | protected BlockingQueue mQueue; 33 | /** 34 | * Boolean used to determine if the thread should continue. 35 | */ 36 | protected boolean running = true; 37 | 38 | /** 39 | * Creates a new ICThread with the specified Queue. 40 | * @param queue the queue to contain all{@see ICBlock}s. 41 | */ 42 | public ICQueue(BlockingQueue queue) { 43 | mQueue = queue; 44 | } 45 | 46 | /** 47 | * Puts a block into the Queue 48 | * @param block the block to push. 49 | */ 50 | synchronized void putBlock(ICBlock block) { 51 | mQueue.add(block); 52 | 53 | } 54 | 55 | synchronized void putAll(Collection blocks){ 56 | mQueue.addAll(blocks); 57 | } 58 | 59 | /** 60 | * Retrieves the next block to be executed from the queue. 61 | * @return the next {@see ICBlock} to be executed on this thread. 62 | */ 63 | synchronized ICBlock getBlock() { 64 | return mQueue.poll(); 65 | } 66 | 67 | 68 | 69 | 70 | /** 71 | * This method loops until running == false. Retrieving one block per loop, waiting if necessary. 72 | */ 73 | @Override 74 | public void run() { 75 | ICBlock currentBlock = null; 76 | 77 | while (running) { 78 | try { 79 | currentBlock = mQueue.take(); 80 | currentBlock.run(); 81 | } catch (InterruptedException e) { 82 | e.printStackTrace(); 83 | } 84 | 85 | 86 | } 87 | 88 | 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ICDispatch 2 | ICDispatch stands for InnocreateDispatch and is a framework designed to let android developers use similar syntax for executing tasks on background threads as Grand Central Dispatch (GCD) uses on iOS. 3 | 4 | In order to use ICDispatch you must declare an application class that extends ICDispatchApplication. ICDispatch will then set itself up with default settings. 5 | App.java 6 | ```java 7 | public class App extends ICDispatchApplication{ 8 | 9 | } 10 | ``` 11 | And please remember to modify the manifest to recognize the App.java as the application class ;) 12 | 13 | After this the App.java class will have two important methods. 14 | ```java 15 | public static boolean executeOn(int queue, ICBlock block) 16 | public static boolean executeMethodOn(int queue, Object instance, String methodName, Object… args) 17 | ``` 18 | 19 | The `queue`parameter may have one of the following values: 20 | 21 | - ICDispatch.LOW, for low priority blocks. 22 | - ICDispatch.NORMAL, for normal priority blocks. 23 | - ICDispatch.HIGH, for high priority blocks. 24 | - ICDispatch.MAIN, for execution on the UI thread. 25 | - ICDispatch.CONCURRENT, for concurrent execution of blocks. 26 | 27 | Please note that all values for queue except for ICDispatch.CONCURRENT will guarantee that if block A is put on queue X before block B then block A will be fully executed before block B will be executed. 28 | 29 | Example on how to use it: 30 | ```java 31 | public void doStuff(){ 32 | App.executeOn(ICDispatch.NORMAL, new ICBlock(){ 33 | public void run(){ 34 | int counter = 0; 35 | for(int i = 0; i < 10000; i++){ 36 | counter += i % 2; 37 | } 38 | App.executeOn(ICDispatch.MAIN, new ICBlock(){ 39 | change UI appropriately. 40 | }); 41 | } 42 | }); 43 | } 44 | ``` 45 | You may queue new blocks inside a block on any queue. 46 | 47 | ICDispatch is under early development and will receive a lot of updates the coming months. 48 | 49 | Future features include: 50 | 51 | - support for fork-join queues. 52 | - Automatic calibration in order to use optimal number of threads in the CONCURRENT queue per device. 53 | - Possibility to customize settings. There are some up now but they are not tested. 54 | - much more. 55 | 56 | #License 57 | ICDispatch uses the Apache 2.0 license, a copy of it can be found at: 58 | 59 | 60 | --------------------------------------------------------------------------------