-
Notifications
You must be signed in to change notification settings - Fork 20
Чаркин Константин(@kostya_charkin), HW background #4
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
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 |
|---|---|---|
| @@ -1,39 +1,84 @@ | ||
| package ru.yandex.yamblz.handler; | ||
|
|
||
| import android.os.Handler; | ||
| import android.os.Looper; | ||
| import android.util.Log; | ||
|
|
||
| import java.util.HashMap; | ||
| import java.util.HashSet; | ||
| import java.util.LinkedList; | ||
| import java.util.Set; | ||
|
|
||
| public class StubCriticalSectionsHandler implements CriticalSectionsHandler { | ||
|
|
||
| private Set<Integer> sections = new HashSet<>(); | ||
| private LinkedList<Task> taskQueue = new LinkedList<>(); | ||
| private Handler handler = new Handler(Looper.getMainLooper()); | ||
| private HashMap<Task, Runnable> delayedTask = new HashMap<>(); | ||
| private Runnable callBack = new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| if (taskQueue.isEmpty()) { | ||
| return; | ||
| } | ||
|
|
||
| Task firstTask = taskQueue.pop(); | ||
| firstTask.run(); | ||
|
|
||
| if (sections.isEmpty()) { | ||
| handler.post(callBack); | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| @Override | ||
| public void startSection(int id) { | ||
|
|
||
| Log.d("startSection", Integer.toString(sections.size())); | ||
| sections.add(id); | ||
| Log.d("startSection", Integer.toString(sections.size())); | ||
| handler.removeCallbacks(callBack); | ||
| } | ||
|
|
||
| @Override | ||
| public void stopSection(int id) { | ||
|
|
||
| Log.d("stopSection", Integer.toString(sections.size())); | ||
| sections.remove(id); | ||
| Log.d("stopSection", Integer.toString(sections.size())); | ||
| if (sections.isEmpty()) { | ||
| handler.post(callBack); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void stopSections() { | ||
|
|
||
| sections.clear(); | ||
| handler.post(callBack); | ||
| } | ||
|
|
||
| @Override | ||
| public void postLowPriorityTask(Task task) { | ||
|
|
||
| Log.d("postLowPriorityTask", "post"); | ||
| taskQueue.add(task); | ||
| if (taskQueue.size() == 1 && sections.isEmpty()) { | ||
|
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. Почему длина очереди должна быть равна 1?
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. @metrologma Ну если до этого этот callback выполнил все таски, то он себя не запушит заново, и если пришла новая таска в этот момент, то нужно это сделать. |
||
| handler.post(callBack); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void postLowPriorityTaskDelayed(Task task, int delay) { | ||
|
|
||
| Runnable runnable = () -> postLowPriorityTask(task); | ||
| delayedTask.put(task, runnable); | ||
| handler.postDelayed(runnable, delay); | ||
| } | ||
|
|
||
| @Override | ||
| public void removeLowPriorityTask(Task task) { | ||
|
|
||
| taskQueue.remove(task); | ||
| handler.removeCallbacks(delayedTask.get(task)); | ||
| } | ||
|
|
||
| @Override | ||
| public void removeLowPriorityTasks() { | ||
|
|
||
| taskQueue.clear(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,4 +7,5 @@ | |
| public interface CollageStrategy { | ||
|
|
||
| Bitmap create(List<Bitmap> bitmaps); | ||
| int numOfImage(); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| package ru.yandex.yamblz.loader; | ||
|
|
||
| import android.graphics.Bitmap; | ||
| import android.graphics.Canvas; | ||
| import android.util.Log; | ||
|
|
||
| import java.util.List; | ||
| import java.util.Random; | ||
|
|
||
| /** | ||
| * Created by kostya on 26.07.16. | ||
| */ | ||
|
|
||
| public class CollageStrategyImpl implements CollageStrategy { | ||
| private static final int WIDTH = 600; | ||
| private static final int HEIGHT = 600; | ||
| @Override | ||
| public Bitmap create(List<Bitmap> bitmaps) { | ||
| Log.d("Bitmap create, size = ", Integer.toString(bitmaps.size())); | ||
| if (bitmaps.isEmpty()) { | ||
| return null; | ||
| } | ||
| else if (bitmaps.size() < 4) { | ||
| Bitmap bitmap = Bitmap.createBitmap(WIDTH/2, HEIGHT/2, Bitmap.Config.ARGB_8888); | ||
| Canvas canvas = new Canvas(bitmap); | ||
| canvas.drawBitmap(bitmaps.get(0), 0f, 0f, null); | ||
| canvas.save(); | ||
| return bitmap; | ||
| } | ||
| else { | ||
| Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888); | ||
| Canvas canvas = new Canvas(bitmap); | ||
| canvas.drawBitmap(bitmaps.get(0), 0f, 0f, null); | ||
| canvas.drawBitmap(bitmaps.get(1), WIDTH/2, 0, null); | ||
| canvas.drawBitmap(bitmaps.get(2), 0f, HEIGHT/2, null); | ||
| canvas.drawBitmap(bitmaps.get(3), WIDTH/2, HEIGHT/2, null); | ||
| canvas.save(); | ||
| return bitmap; | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public int numOfImage() { | ||
| return 4; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,97 @@ | ||
| package ru.yandex.yamblz.ui.fragments; | ||
|
|
||
| import android.content.SharedPreferences; | ||
| import android.graphics.Bitmap; | ||
| import android.graphics.Canvas; | ||
| import android.graphics.Color; | ||
| import android.graphics.Paint; | ||
| import android.os.Bundle; | ||
| import android.support.annotation.NonNull; | ||
| import android.support.annotation.Nullable; | ||
| import android.support.v7.widget.LinearLayoutManager; | ||
| import android.support.v7.widget.RecyclerView; | ||
| import android.util.Log; | ||
| import android.view.LayoutInflater; | ||
| import android.view.View; | ||
| import android.view.ViewGroup; | ||
| import android.widget.FrameLayout; | ||
| import android.widget.ImageView; | ||
|
|
||
| import org.json.JSONArray; | ||
| import org.json.JSONException; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.HashMap; | ||
| import java.util.LinkedHashSet; | ||
| import java.util.LinkedList; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.Set; | ||
| import java.util.concurrent.ExecutionException; | ||
|
|
||
| import ru.yandex.yamblz.R; | ||
| import ru.yandex.yamblz.loader.CollageStrategyImpl; | ||
| import ru.yandex.yamblz.ui.fragments.Genre.Artist; | ||
| import ru.yandex.yamblz.ui.fragments.Genre.DownloadArtistsTask; | ||
| import ru.yandex.yamblz.ui.fragments.Genre.Genre; | ||
| import ru.yandex.yamblz.ui.fragments.Genre.GenreAdapter; | ||
| import ru.yandex.yamblz.ui.fragments.Genre.GenreOnScrollListener; | ||
|
|
||
| public class ContentFragment extends BaseFragment { | ||
| private static final String urlStr = "http://download.cdn.yandex.net/mobilization-2016/artists.json"; | ||
| ImageView imageView; | ||
|
|
||
| @NonNull | ||
| @Override | ||
| public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { | ||
| return inflater.inflate(R.layout.fragment_content, container, false); | ||
| RecyclerView recyclerView = (RecyclerView)inflater.inflate(R.layout.fragment_content, container, false); | ||
| List<Genre> genres = getGenres(); | ||
| RecyclerView.Adapter adapter = new GenreAdapter(genres, super.getActivity()); | ||
| recyclerView.setAdapter(adapter); | ||
| recyclerView.addOnScrollListener(new GenreOnScrollListener()); | ||
| recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); | ||
| return recyclerView; | ||
| } | ||
|
|
||
| private List<Genre> getGenres() { | ||
|
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. Заюзай method profiling, посмотри на сколько этот метод блокирует main thread |
||
| List<Genre> genres = new ArrayList<>(); | ||
| List<Artist> artists = null; | ||
| SharedPreferences sharedPreferences = getActivity().getApplicationContext().getSharedPreferences("genres", 0); | ||
| String artistsJSON = sharedPreferences.getString("artistsJSON", null); | ||
| if (artistsJSON == null) { | ||
| Log.d("Main list fragment", "download"); | ||
| DownloadArtistsTask downloadArtists = new DownloadArtistsTask(); | ||
| downloadArtists.execute(urlStr); | ||
| try { | ||
| artistsJSON = downloadArtists.get(); | ||
|
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. @metrologma Да, но это только при первом запуске, просто непонятно ,что тогда показывать, если у нас еще нет списка артистов. Последующие запуски будут брать из sharedPreferences. И я там запушил примерно в тоже время, пока ты смотрел, к примеру сейчас я уже отменяю таски, если приходят новые на теже вьюхи. Можешь сейчас посмотреть, падает ли по OutOfMemoryError ? Просто сейчас я у себя запускаю, больше 10Мб Allocated не бывает.
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. Самое главное в задании с лоадером - чтобы не мелькали картинки (отменять операции), не падать на оом, спрятать всю логику за интерфейсом (поток должен внутри создаваться) |
||
| } catch (InterruptedException | ExecutionException e) { | ||
| e.printStackTrace(); | ||
| } | ||
| SharedPreferences.Editor editor = sharedPreferences.edit(); | ||
| editor.putString("artistsJSON", artistsJSON); | ||
| editor.apply(); | ||
| } | ||
| try { | ||
| artists = Artist.fromJSON(new JSONArray(artistsJSON)); | ||
| } catch (JSONException e) { | ||
| e.printStackTrace(); | ||
| } | ||
|
|
||
| Map<String, Genre> genreMap = new HashMap<>(); | ||
|
|
||
| assert artists != null; | ||
| for (Artist artist: artists) { | ||
| for(String genre: artist.getGenres()) { | ||
| if (!genreMap.containsKey(genre)) { | ||
| Genre genreObj = new Genre(genre); | ||
| genreMap.put(genre, genreObj); | ||
| } | ||
| genreMap.get(genre).addArtist(artist); | ||
| } | ||
| } | ||
|
|
||
| genres.addAll(genreMap.values()); | ||
|
|
||
| return genres; | ||
| } | ||
| } | ||
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.
У тебя в очереди 10 тасков, один из них начал выполняться. В это время сказали что началась критическая секция. Ты удалил ранбл, но он уже выполнялся параллельно в другом потоке и добавил сам себя опять в хендлер. И получается что съел таким образом твое удаление при старте секции критической
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.
@metrologma Он же проверяет, перед тем, как запушить на
if (sections.isEmpty()) {