-
Notifications
You must be signed in to change notification settings - Fork 20
@aleien, Манюхина #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
699187b
ba18683
fd1c4f1
496229c
bf35399
a26d7b1
7863142
0f24ca9
54b9c5a
73c11c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package ru.yandex.yamblz.data; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class Artist { | ||
| public final int id; | ||
| public final String name; | ||
| public final List<String> genres; | ||
| private final int tracks; | ||
| private final int albums; | ||
| private final String link; | ||
| private final String description; | ||
| final Cover cover; | ||
|
|
||
| public Artist(int id, String name, List<String> genres, int tracks, int albums, String link, String description, Cover cover) { | ||
| this.id = id; | ||
| this.name = name; | ||
| this.genres = genres; | ||
| this.tracks = tracks; | ||
| this.albums = albums; | ||
| this.link = link; | ||
| this.description = description; | ||
| this.cover = cover; | ||
| } | ||
|
|
||
| static class Cover { | ||
| final String small; | ||
| final String big; | ||
|
|
||
| public Cover(String small, String big) { | ||
| this.small = small; | ||
| this.big = big; | ||
| } | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package ru.yandex.yamblz.data; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import retrofit2.http.GET; | ||
| import rx.Single; | ||
|
|
||
| public interface ArtistsApi { | ||
| @GET("artists.json") | ||
| Single<List<Artist>> getArtists(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package ru.yandex.yamblz.data; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class Genre { | ||
| private final String name; | ||
| private final List<Artist> artists; | ||
|
|
||
| public Genre(String name, List<Artist> artists) { | ||
| this.name = name; | ||
| this.artists = artists; | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
|
|
||
| public List<String> getCollageUrls() { | ||
| List<String> urls = new ArrayList<>(); | ||
| for (Artist artist : artists) { | ||
| urls.add(artist.cover.small); | ||
| if (urls.size() >= 4) return urls; | ||
| } | ||
|
|
||
| return urls; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| package ru.yandex.yamblz.handler; | ||
|
|
||
| import android.os.Handler; | ||
| import android.os.Looper; | ||
| import android.os.MessageQueue; | ||
|
|
||
| import java.lang.ref.WeakReference; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
| import java.util.Set; | ||
| import java.util.concurrent.ConcurrentHashMap; | ||
| import java.util.concurrent.CopyOnWriteArrayList; | ||
|
|
||
| public class DisableScrollLoadingHandler implements CriticalSectionsHandler, MessageQueue.IdleHandler { | ||
| private final Set<Integer> runningSections = Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>()); | ||
| private final List<Task> tasks = new CopyOnWriteArrayList<>(); | ||
| private final WeakReference<MessageQueue> listenableQueue; | ||
|
|
||
| public DisableScrollLoadingHandler(MessageQueue queue) { | ||
| listenableQueue = new WeakReference<>(queue); | ||
| } | ||
|
|
||
| @Override | ||
| public void startSection(int id) { | ||
| runningSections.add(id); | ||
| } | ||
|
|
||
| @Override | ||
| public void stopSection(int id) { | ||
| if (runningSections.contains(id)) { | ||
| runningSections.remove(id); | ||
| } | ||
| addIdleHandler(); | ||
| } | ||
|
|
||
| @Override | ||
| public void stopSections() { | ||
| runningSections.clear(); | ||
| addIdleHandler(); | ||
| } | ||
|
|
||
| private void runTasks() { | ||
| for (Task task : tasks) { | ||
| if (runningSections.size() == 0) { | ||
| task.run(); | ||
| removeLowPriorityTask(task); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Вот тут я хз, честно. | ||
| // Вот вроде по дяде Бобу это неправильно написано, а с другой стороны вроде логично выглядит | ||
| private boolean addIdleHandler() { | ||
| if (listenableQueue.get() != null) { | ||
| if (tasks.size() != 0 && !queueIdle()) { | ||
| listenableQueue.get().addIdleHandler(this); | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| @Override | ||
| public void postLowPriorityTask(Task task) { | ||
| if (addIdleHandler()) tasks.add(task); | ||
| // throw exception? | ||
| } | ||
|
|
||
| @Override | ||
| public void postLowPriorityTaskDelayed(Task task, int delay) { | ||
| new Handler(Looper.getMainLooper()).postDelayed(() -> postLowPriorityTask(task), delay); | ||
| } | ||
|
|
||
| @Override | ||
| public void removeLowPriorityTask(Task task) { | ||
| tasks.remove(task); | ||
| } | ||
|
|
||
| @Override | ||
| public void removeLowPriorityTasks() { | ||
| tasks.clear(); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean queueIdle() { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. С точки зрения ООП не очень хорошо получилось)
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Не понимаю, как тогда передавать idleHandler в MessageQueue (: У нас же менеджер возвращает интерфейс, значит, доступны только методы из него.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Но да, с точки зрения ООП плохо)
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. При создании обьекта реализующего интерфейс, в конструкторе. |
||
| if (runningSections.size() == 0) runTasks(); | ||
| return runningSections.size() == 0 && tasks.size() != 0; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| package ru.yandex.yamblz.loader; | ||
|
|
||
| import android.graphics.Bitmap; | ||
| import android.support.annotation.NonNull; | ||
| import android.util.LruCache; | ||
| import android.widget.ImageView; | ||
|
|
||
| import java.util.List; | ||
| import java.util.WeakHashMap; | ||
|
|
||
| import ru.yandex.yamblz.handler.CriticalSectionsManager; | ||
| import ru.yandex.yamblz.utils.Utils; | ||
| import rx.Observable; | ||
| import rx.Subscription; | ||
| import rx.android.schedulers.AndroidSchedulers; | ||
| import rx.schedulers.Schedulers; | ||
| import rx.subscriptions.CompositeSubscription; | ||
| import timber.log.Timber; | ||
|
|
||
|
|
||
| public class ParallelCollageLoader implements CollageLoader { | ||
| @NonNull private final WeakHashMap<ImageTarget, Subscription> subscriptionTargets; | ||
| @NonNull private final CompositeSubscription subs; | ||
| @NonNull private final CollageStrategy collageStrategy; | ||
| @NonNull private final LruCache<List<String>, Bitmap> memoryCache; | ||
|
|
||
| public ParallelCollageLoader() { | ||
| subscriptionTargets = new WeakHashMap<>(); | ||
| subs = new CompositeSubscription(); | ||
| collageStrategy = new SimpleCollageStrategy(); | ||
| final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); | ||
| final int cacheSize = maxMemory / 8; | ||
| memoryCache = new LruCache<>(cacheSize); | ||
| } | ||
|
|
||
| @Override | ||
| public void loadCollage(List<String> urls, ImageView imageView) { | ||
| loadCollage(urls, imageView, this.collageStrategy); | ||
| } | ||
|
|
||
| @Override | ||
| public void loadCollage(List<String> urls, ImageTarget imageTarget) { | ||
| loadCollage(urls, imageTarget, this.collageStrategy); | ||
| } | ||
|
|
||
| @Override | ||
| public void loadCollage(List<String> urls, final ImageView imageView, CollageStrategy collageStrategy) { | ||
| ImageTarget target = bitmap -> { | ||
| imageView.setAlpha(0f); | ||
| imageView.setImageBitmap(bitmap); | ||
| imageView.animate().alpha(1); | ||
| }; | ||
| loadCollage(urls, target, collageStrategy); | ||
| } | ||
|
|
||
| private void loadBitmap(ImageTarget imageTarget, Bitmap cachedCollage) { | ||
| CriticalSectionsManager.getHandler().postLowPriorityTask(() -> imageTarget.onLoadBitmap(cachedCollage)); | ||
| } | ||
|
|
||
| @Override | ||
| public void loadCollage(List<String> urls, ImageTarget imageTarget, CollageStrategy collageStrategy) { | ||
| Subscription s = subscriptionTargets.get(imageTarget); | ||
| if (s != null) { | ||
| subs.remove(s); | ||
| } | ||
| Bitmap cachedCollage = memoryCache.get(urls); | ||
| if (cachedCollage != null) { | ||
| Timber.d("Cache hit! Adding task to handler"); | ||
| loadBitmap(imageTarget, cachedCollage); | ||
| } else { | ||
| Subscription subscription = Observable.from(urls) | ||
| .flatMap(url -> Utils.loadBitmapAsync(url).subscribeOn(Schedulers.io())) | ||
| .toList() | ||
| .map(collageStrategy::create) | ||
| .doOnNext(collage -> memoryCache.put(urls, collage)) | ||
| .observeOn(AndroidSchedulers.mainThread()) | ||
| .subscribe(collage -> loadBitmap(imageTarget, collage), | ||
| Throwable::printStackTrace | ||
| ); | ||
| subs.add(subscription); | ||
| subscriptionTargets.put(imageTarget, subscription); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void destroyAll() { | ||
| subs.clear(); | ||
| subscriptionTargets.clear(); | ||
| } | ||
|
|
||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Если во время перебора началась критическая секция?