8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 dodola
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BubbleCloudView(Beta)
2 | Like apple watch launcher view(仿苹果表应用表盘界面)
3 |
4 |
5 |
6 | ## Screenshots
7 |
8 | 
9 |
10 | # Thanks
11 | - [Apple-Watch-Spring-Board](https://github.com/Dzinlife/Apple-Watch-Spring-Board)
12 | - [CircularImageView](https://github.com/Pkmmte/CircularImageView)
13 |
14 |
15 | License
16 | --------
17 |
18 | The MIT License (MIT)
19 |
20 | Copyright (c) 2015 dodola
21 |
22 | Permission is hereby granted, free of charge, to any person obtaining a copy
23 | of this software and associated documentation files (the "Software"), to deal
24 | in the Software without restriction, including without limitation the rights
25 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26 | copies of the Software, and to permit persons to whom the Software is
27 | furnished to do so, subject to the following conditions:
28 |
29 | The above copyright notice and this permission notice shall be included in all
30 | copies or substantial portions of the Software.
31 |
32 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38 | SOFTWARE.
39 |
40 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
AsyncTask 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 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 Executor},
64 | * {@link ThreadPoolExecutor} and {@link FutureTask}.
65 | *
66 | *
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.
71 | *
72 | *
73 | *
Developer Guides
74 | *
For more information about using tasks and threads, read the
75 | * Processes and
76 | * Threads developer guide.
77 | *
78 | *
79 | *
Usage
80 | *
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}.)
When an asynchronous task is executed, the task goes through 4 steps:
132 | *
133 | *
{@link #onPreExecute()}, invoked on the UI thread immediately after the task
134 | * is executed. This step is normally used to setup the task, for instance by
135 | * showing a progress bar in the user interface.
136 | *
{@link #doInBackground}, invoked on the background thread
137 | * immediately after {@link #onPreExecute()} finishes executing. This step is used
138 | * to perform background computation that can take a long time. The parameters
139 | * of the asynchronous task are passed to this step. The result of the computation must
140 | * be returned by this step and will be passed back to the last step. This step
141 | * can also use {@link #publishProgress} to publish one or more units
142 | * of progress. These values are published on the UI thread, in the
143 | * {@link #onProgressUpdate} step.
144 | *
{@link #onProgressUpdate}, invoked on the UI thread after a
145 | * call to {@link #publishProgress}. The timing of the execution is
146 | * undefined. This method is used to display any form of progress in the user
147 | * interface while the background computation is still executing. For instance,
148 | * it can be used to animate a progress bar or show logs in a text field.
149 | *
{@link #onPostExecute}, invoked on the UI thread after the background
150 | * computation finishes. The result of the background computation is passed to
151 | * this step as a parameter.
152 | *
153 | *
154 | *
Cancelling a task
155 | *
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 | *
Threading rules
164 | *
There are a few threading rules that must be followed for this class to
165 | * work properly:
166 | *
167 | *
The AsyncTask class must be loaded on the UI thread. This is done
168 | * automatically as of {@link android.os.Build.VERSION_CODES#JELLY_BEAN}.
169 | *
The task instance must be created on the UI thread.
170 | *
{@link #execute} must be invoked on the UI thread.
171 | *
Do not call {@link #onPreExecute()}, {@link #onPostExecute},
172 | * {@link #doInBackground}, {@link #onProgressUpdate} manually.
173 | *
The task can be executed only once (an exception will be thrown if
174 | * a second execution is attempted.)
175 | *
176 | *
177 | *
Memory observability
178 | *
AsyncTask guarantees that all callback calls are synchronized in such a way that the following
179 | * operations are safe without explicit synchronizations.
180 | *
181 | *
Set member fields in the constructor or {@link #onPreExecute}, and refer to them
182 | * in {@link #doInBackground}.
183 | *
Set member fields in {@link #doInBackground}, and refer to them in
184 | * {@link #onProgressUpdate} and {@link #onPostExecute}.
185 | *
186 | *
187 | *
Order of execution
188 | *
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(Executor, Object[])} with
195 | * {@link #THREAD_POOL_EXECUTOR}.
196 | */
197 | public abstract class AsyncTask {
198 | private static final String LOG_TAG = "AsyncTask";
199 |
200 | private static final int CORE_POOL_SIZE = 5;
201 | private static final int MAXIMUM_POOL_SIZE = 128;
202 | private static final int KEEP_ALIVE = 1;
203 |
204 | private static final ThreadFactory sThreadFactory = new ThreadFactory() {
205 | private final AtomicInteger mCount = new AtomicInteger(1);
206 |
207 | public Thread newThread(Runnable r) {
208 | return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
209 | }
210 | };
211 |
212 | private static final BlockingQueue sPoolWorkQueue =
213 | new LinkedBlockingQueue(10);
214 |
215 | /**
216 | * An {@link Executor} that can be used to execute tasks in parallel.
217 | */
218 | public static final Executor THREAD_POOL_EXECUTOR
219 | = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
220 | TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory,
221 | new ThreadPoolExecutor.DiscardOldestPolicy());
222 |
223 | /**
224 | * An {@link Executor} that executes tasks one at a time in serial
225 | * order. This serialization is global to a particular process.
226 | */
227 | public static final Executor SERIAL_EXECUTOR = Utils.hasHoneycomb() ? new SerialExecutor() :
228 | Executors.newSingleThreadExecutor(sThreadFactory);
229 |
230 | public static final Executor DUAL_THREAD_EXECUTOR =
231 | Executors.newFixedThreadPool(2, sThreadFactory);
232 |
233 | private static final int MESSAGE_POST_RESULT = 0x1;
234 | private static final int MESSAGE_POST_PROGRESS = 0x2;
235 |
236 | private static final InternalHandler sHandler = new InternalHandler();
237 |
238 | private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
239 | private final WorkerRunnable mWorker;
240 | private final FutureTask mFuture;
241 |
242 | private volatile Status mStatus = Status.PENDING;
243 |
244 | private final AtomicBoolean mCancelled = new AtomicBoolean();
245 | private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
246 |
247 | @TargetApi(11)
248 | private static class SerialExecutor implements Executor {
249 | final ArrayDeque mTasks = new ArrayDeque();
250 | Runnable mActive;
251 |
252 | public synchronized void execute(final Runnable r) {
253 | mTasks.offer(new Runnable() {
254 | public void run() {
255 | try {
256 | r.run();
257 | } finally {
258 | scheduleNext();
259 | }
260 | }
261 | });
262 | if (mActive == null) {
263 | scheduleNext();
264 | }
265 | }
266 |
267 | protected synchronized void scheduleNext() {
268 | if ((mActive = mTasks.poll()) != null) {
269 | THREAD_POOL_EXECUTOR.execute(mActive);
270 | }
271 | }
272 | }
273 |
274 | /**
275 | * Indicates the current status of the task. Each status will be set only once
276 | * during the lifetime of a task.
277 | */
278 | public enum Status {
279 | /**
280 | * Indicates that the task has not been executed yet.
281 | */
282 | PENDING,
283 | /**
284 | * Indicates that the task is running.
285 | */
286 | RUNNING,
287 | /**
288 | * Indicates that {@link AsyncTask#onPostExecute} has finished.
289 | */
290 | FINISHED,
291 | }
292 |
293 | /** @hide Used to force static handler to be created. */
294 | public static void init() {
295 | sHandler.getLooper();
296 | }
297 |
298 | /** @hide */
299 | public static void setDefaultExecutor(Executor exec) {
300 | sDefaultExecutor = exec;
301 | }
302 |
303 | /**
304 | * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
305 | */
306 | public AsyncTask() {
307 | mWorker = new WorkerRunnable() {
308 | public Result call() throws Exception {
309 | mTaskInvoked.set(true);
310 |
311 | Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
312 | //noinspection unchecked
313 | return postResult(doInBackground(mParams));
314 | }
315 | };
316 |
317 | mFuture = new FutureTask(mWorker) {
318 | @Override
319 | protected void done() {
320 | try {
321 | postResultIfNotInvoked(get());
322 | } catch (InterruptedException e) {
323 | android.util.Log.w(LOG_TAG, e);
324 | } catch (ExecutionException e) {
325 | throw new RuntimeException("An error occured while executing doInBackground()",
326 | e.getCause());
327 | } catch (CancellationException e) {
328 | postResultIfNotInvoked(null);
329 | }
330 | }
331 | };
332 | }
333 |
334 | private void postResultIfNotInvoked(Result result) {
335 | final boolean wasTaskInvoked = mTaskInvoked.get();
336 | if (!wasTaskInvoked) {
337 | postResult(result);
338 | }
339 | }
340 |
341 | private Result postResult(Result result) {
342 | @SuppressWarnings("unchecked")
343 | Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
344 | new AsyncTaskResult(this, result));
345 | message.sendToTarget();
346 | return result;
347 | }
348 |
349 | /**
350 | * Returns the current status of this task.
351 | *
352 | * @return The current status.
353 | */
354 | public final Status getStatus() {
355 | return mStatus;
356 | }
357 |
358 | /**
359 | * Override this method to perform a computation on a background thread. The
360 | * specified parameters are the parameters passed to {@link #execute}
361 | * by the caller of this task.
362 | *
363 | * This method can call {@link #publishProgress} to publish updates
364 | * on the UI thread.
365 | *
366 | * @param params The parameters of the task.
367 | *
368 | * @return A result, defined by the subclass of this task.
369 | *
370 | * @see #onPreExecute()
371 | * @see #onPostExecute
372 | * @see #publishProgress
373 | */
374 | protected abstract Result doInBackground(Params... params);
375 |
376 | /**
377 | * Runs on the UI thread before {@link #doInBackground}.
378 | *
379 | * @see #onPostExecute
380 | * @see #doInBackground
381 | */
382 | protected void onPreExecute() {
383 | }
384 |
385 | /**
386 | *
Runs 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 CancellationException If the computation was cancelled.
503 | * @throws 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 CancellationException If the computation was cancelled.
521 | * @throws ExecutionException If the computation threw an exception.
522 | * @throws InterruptedException If the current thread was interrupted
523 | * while waiting.
524 | * @throws 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 Status#RUNNING} or {@link Status#FINISHED}.
555 | *
556 | * @see #executeOnExecutor(Executor, Object[])
557 | * @see #execute(Runnable)
558 | */
559 | public final AsyncTask execute(Params... params) {
560 | return executeOnExecutor(sDefaultExecutor, params);
561 | }
562 |
563 | /**
564 | * Executes the task with the specified parameters. The task returns
565 | * itself (this) so that the caller can keep a reference to it.
566 | *
567 | *
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 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 Status#RUNNING} or {@link Status#FINISHED}.
593 | *
594 | * @see #execute(Object[])
595 | */
596 | public final AsyncTask executeOnExecutor(Executor exec,
597 | Params... params) {
598 | if (mStatus != Status.PENDING) {
599 | switch (mStatus) {
600 | case RUNNING:
601 | throw new IllegalStateException("Cannot execute task:"
602 | + " the task is already running.");
603 | case FINISHED:
604 | throw new IllegalStateException("Cannot execute task:"
605 | + " the task has already been executed "
606 | + "(a task can be executed only once)");
607 | }
608 | }
609 |
610 | mStatus = Status.RUNNING;
611 |
612 | onPreExecute();
613 |
614 | mWorker.mParams = params;
615 | exec.execute(mFuture);
616 |
617 | return this;
618 | }
619 |
620 | /**
621 | * Convenience version of {@link #execute(Object...)} for use with
622 | * a simple Runnable object. See {@link #execute(Object[])} for more
623 | * information on the order of execution.
624 | *
625 | * @see #execute(Object[])
626 | * @see #executeOnExecutor(Executor, Object[])
627 | */
628 | public static void execute(Runnable runnable) {
629 | sDefaultExecutor.execute(runnable);
630 | }
631 |
632 | /**
633 | * This method can be invoked from {@link #doInBackground} to
634 | * publish updates on the UI thread while the background computation is
635 | * still running. Each call to this method will trigger the execution of
636 | * {@link #onProgressUpdate} on the UI thread.
637 | *
638 | * {@link #onProgressUpdate} will note be called if the task has been
639 | * canceled.
640 | *
641 | * @param values The progress values to update the UI with.
642 | *
643 | * @see #onProgressUpdate
644 | * @see #doInBackground
645 | */
646 | protected final void publishProgress(Progress... values) {
647 | if (!isCancelled()) {
648 | sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
649 | new AsyncTaskResult