From d180b5b4362e9483d92f48af503409470869db25 Mon Sep 17 00:00:00 2001 From: Kostya Charkin <93kostya@gmail.com> Date: Tue, 26 Jul 2016 02:09:31 +0300 Subject: [PATCH 1/5] task 2 (handler) --- app/src/main/java/ru/yandex/yamblz/App.java | 3 +- .../handler/StubCriticalSectionsHandler.java | 53 ++++++++++++++++--- dependencies.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +- 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/ru/yandex/yamblz/App.java b/app/src/main/java/ru/yandex/yamblz/App.java index e5f9972..20e82a7 100644 --- a/app/src/main/java/ru/yandex/yamblz/App.java +++ b/app/src/main/java/ru/yandex/yamblz/App.java @@ -7,6 +7,7 @@ import ru.yandex.yamblz.developer_settings.DevMetricsProxy; import ru.yandex.yamblz.developer_settings.DeveloperSettingsModel; import ru.yandex.yamblz.handler.CriticalSectionsManager; +import ru.yandex.yamblz.handler.StubCriticalSectionsHandler; import ru.yandex.yamblz.loader.CollageLoaderManager; import timber.log.Timber; @@ -35,7 +36,7 @@ public void onCreate() { } CollageLoaderManager.init(null); // add implementation - CriticalSectionsManager.init(null); // add implementation + CriticalSectionsManager.init(new StubCriticalSectionsHandler()); // add implementation } @NonNull diff --git a/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java b/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java index 0af9646..f2e6e4c 100644 --- a/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java +++ b/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java @@ -1,39 +1,78 @@ package ru.yandex.yamblz.handler; +import android.os.Handler; +import android.os.Looper; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Set; + public class StubCriticalSectionsHandler implements CriticalSectionsHandler { + private Set sections = new HashSet<>(); + private LinkedList taskQueue = new LinkedList<>(); + private Handler handler = new Handler(Looper.getMainLooper()); + private HashMap 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) { - + sections.add(id); + handler.removeCallbacks(callBack); } @Override public void stopSection(int id) { - + sections.remove(id); + if (sections.isEmpty()) { + handler.post(callBack); + } } @Override public void stopSections() { - + sections.clear(); + handler.post(callBack); } @Override public void postLowPriorityTask(Task task) { - + taskQueue.add(task); + if (taskQueue.size() == 1) { + 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(); } } diff --git a/dependencies.gradle b/dependencies.gradle index d9cb375..d340e7b 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -7,7 +7,7 @@ ext.versions = [ compileSdk : 23, buildTools : '23.0.3', - androidGradlePlugin : '2.2.0-alpha4', + androidGradlePlugin : '2.2.0-alpha6', aptGradlePlugin : '1.8', retrolambdaGradlePlugin : '3.2.5', lombokGradlePlugin : '0.2.3.a2', diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 86a3e94..95d21e6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon May 30 20:17:48 ICT 2016 +#Mon Jul 25 23:14:19 MSK 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-all.zip From bae9fee52be64b8b31ded8239ac9597a977815bf Mon Sep 17 00:00:00 2001 From: Kostya Charkin <93kostya@gmail.com> Date: Tue, 26 Jul 2016 22:34:39 +0300 Subject: [PATCH 2/5] task 1(loader) --- app/src/main/java/ru/yandex/yamblz/App.java | 3 +- .../handler/StubCriticalSectionsHandler.java | 2 + .../yandex/yamblz/loader/CollageLoader.java | 1 + .../yamblz/loader/CollageStrategyImpl.java | 41 ++++++++++ .../yamblz/loader/StubCollageLoader.java | 37 +++++++++ .../yamblz/ui/fragments/ContentFragment.java | 81 ++++++++++++++++++- .../yamblz/ui/fragments/Genre/Artist.java | 58 +++++++++++++ .../fragments/Genre/DownloadArtistsTask.java | 39 +++++++++ .../yamblz/ui/fragments/Genre/Genre.java | 47 +++++++++++ .../ui/fragments/Genre/GenreAdapter.java | 58 +++++++++++++ .../Genre/GenreOnScrollListener.java | 25 ++++++ .../ui/fragments/Genre/GenreViewHolder.java | 27 +++++++ app/src/main/res/layout/fragment_content.xml | 19 ++--- app/src/main/res/layout/list_row.xml | 27 +++++++ 14 files changed, 450 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/ru/yandex/yamblz/loader/CollageStrategyImpl.java create mode 100644 app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/Artist.java create mode 100644 app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/DownloadArtistsTask.java create mode 100644 app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/Genre.java create mode 100644 app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java create mode 100644 app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreOnScrollListener.java create mode 100644 app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreViewHolder.java create mode 100644 app/src/main/res/layout/list_row.xml diff --git a/app/src/main/java/ru/yandex/yamblz/App.java b/app/src/main/java/ru/yandex/yamblz/App.java index 20e82a7..fcefd03 100644 --- a/app/src/main/java/ru/yandex/yamblz/App.java +++ b/app/src/main/java/ru/yandex/yamblz/App.java @@ -9,6 +9,7 @@ import ru.yandex.yamblz.handler.CriticalSectionsManager; import ru.yandex.yamblz.handler.StubCriticalSectionsHandler; import ru.yandex.yamblz.loader.CollageLoaderManager; +import ru.yandex.yamblz.loader.StubCollageLoader; import timber.log.Timber; public class App extends Application { @@ -35,7 +36,7 @@ public void onCreate() { devMetricsProxy.apply(); } - CollageLoaderManager.init(null); // add implementation + CollageLoaderManager.init(new StubCollageLoader()); // add implementation CriticalSectionsManager.init(new StubCriticalSectionsHandler()); // add implementation } diff --git a/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java b/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java index f2e6e4c..7146504 100644 --- a/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java +++ b/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java @@ -2,6 +2,7 @@ import android.os.Handler; import android.os.Looper; +import android.util.Log; import java.util.HashMap; import java.util.HashSet; @@ -52,6 +53,7 @@ public void stopSections() { @Override public void postLowPriorityTask(Task task) { + Log.d("postLowPriorityTask", "post"); taskQueue.add(task); if (taskQueue.size() == 1) { handler.post(callBack); diff --git a/app/src/main/java/ru/yandex/yamblz/loader/CollageLoader.java b/app/src/main/java/ru/yandex/yamblz/loader/CollageLoader.java index dad5b76..b08b9e8 100644 --- a/app/src/main/java/ru/yandex/yamblz/loader/CollageLoader.java +++ b/app/src/main/java/ru/yandex/yamblz/loader/CollageLoader.java @@ -2,6 +2,7 @@ import android.widget.ImageView; +import java.lang.ref.WeakReference; import java.util.List; public interface CollageLoader { diff --git a/app/src/main/java/ru/yandex/yamblz/loader/CollageStrategyImpl.java b/app/src/main/java/ru/yandex/yamblz/loader/CollageStrategyImpl.java new file mode 100644 index 0000000..504ab25 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/loader/CollageStrategyImpl.java @@ -0,0 +1,41 @@ +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 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; + } + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java b/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java index 1dc051b..2ed76f4 100644 --- a/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java +++ b/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java @@ -1,9 +1,20 @@ package ru.yandex.yamblz.loader; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.util.Log; import android.widget.ImageView; +import java.io.IOException; +import java.io.InputStream; +import java.lang.ref.WeakReference; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; import java.util.List; +import ru.yandex.yamblz.handler.CriticalSectionsManager; + public class StubCollageLoader implements CollageLoader { @Override @@ -19,6 +30,19 @@ public void loadCollage(List urls, ImageTarget imageTarget) { @Override public void loadCollage(List urls, ImageView imageView, CollageStrategy collageStrategy) { + Log.d("loadCollage", "download"); + List bitmapList = new ArrayList<>(); + for (String url : + urls) { + bitmapList.add(getBitmapFromURL(url)); + } + Bitmap bitmap = collageStrategy.create(bitmapList); + CriticalSectionsManager.getHandler().postLowPriorityTask(() -> { + if (imageView != null) { + imageView.setImageBitmap(bitmap); + imageView.invalidate(); + } + }); } @@ -28,4 +52,17 @@ public void loadCollage(List urls, ImageTarget imageTarget, } + private static Bitmap getBitmapFromURL(String src) { + try { + URL url = new URL(src); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setDoInput(true); + connection.connect(); + InputStream input = connection.getInputStream(); + return BitmapFactory.decodeStream(input); + } catch (IOException e) { + // Log exception + return null; + } + } } diff --git a/app/src/main/java/ru/yandex/yamblz/ui/fragments/ContentFragment.java b/app/src/main/java/ru/yandex/yamblz/ui/fragments/ContentFragment.java index d46490f..32f7c92 100644 --- a/app/src/main/java/ru/yandex/yamblz/ui/fragments/ContentFragment.java +++ b/app/src/main/java/ru/yandex/yamblz/ui/fragments/ContentFragment.java @@ -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 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 getGenres() { + List genres = new ArrayList<>(); + List 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(); + } 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 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; } } diff --git a/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/Artist.java b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/Artist.java new file mode 100644 index 0000000..a7d58ef --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/Artist.java @@ -0,0 +1,58 @@ +package ru.yandex.yamblz.ui.fragments.Genre; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by kostya on 26.07.16. + */ +public class Artist { + private static final String DEFAULT_STR = "unknown"; + private static final String DEFAULT_URL = ""; + + private String name; + private String imgUrl; + private List genres = new ArrayList<>(); + + public List getGenres() { + return genres; + } + + public Artist(JSONObject jsonObject) { + try { this.name = jsonObject.getString("name"); } catch (JSONException e) { this.name = DEFAULT_STR; } + try { this.imgUrl = jsonObject.getJSONObject("cover").getString("small"); } catch (JSONException e) { this.imgUrl = DEFAULT_URL; } + try { + JSONArray jsonGenres = jsonObject.getJSONArray("genres"); + for (int i = 0; i < jsonGenres.length(); i++) { + genres.add((String) jsonGenres.get(i)); + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + + public static ArrayList fromJSON (JSONArray jsonArray) { + ArrayList list = new ArrayList<>(); + + for (int i = 0; i < jsonArray.length(); i++) { + try { + list.add(new Artist(jsonArray.getJSONObject(i))); + } catch (JSONException e) { + e.printStackTrace(); + } + } + return list; + } + + public String getName() { + return name; + } + + public String getImgUrl() { + return imgUrl; + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/DownloadArtistsTask.java b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/DownloadArtistsTask.java new file mode 100644 index 0000000..59adbaa --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/DownloadArtistsTask.java @@ -0,0 +1,39 @@ +package ru.yandex.yamblz.ui.fragments.Genre; + +import android.os.AsyncTask; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +/** + * Created by kostya on 26.07.16. + */ + +public class DownloadArtistsTask extends AsyncTask { + + @Override + protected String doInBackground(String... strings) { + HttpURLConnection urlConnection; + + StringBuilder stringBuilder = new StringBuilder(); + try { + URL url = new URL(strings[0]); + urlConnection = (HttpURLConnection) url.openConnection(); + InputStream in = new BufferedInputStream(urlConnection.getInputStream()); + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + String line; + while ((line = reader.readLine())!=null) { + stringBuilder.append(line); + } + } catch (IOException e) { + e.printStackTrace(); + } + + return stringBuilder.toString(); + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/Genre.java b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/Genre.java new file mode 100644 index 0000000..b20f289 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/Genre.java @@ -0,0 +1,47 @@ +package ru.yandex.yamblz.ui.fragments.Genre; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * Created by kostya on 26.07.16. + */ + +public class Genre { + private String name; + private List artists = new ArrayList<>(); + + public Genre(String name) { + this.name = name; + } + public String getDescription() { + StringBuilder stringBuilder = new StringBuilder(); + for (Artist artist: artists) { + stringBuilder.append(". "); + stringBuilder.append(artist.getName()); + } + return stringBuilder.toString(); + } + + public String getName() { + return name; + } + + public void addArtist(Artist artist) { + artists.add(artist); + } + + public List getImgUrls() { + List listUrls = new LinkedList<>(); + for (Artist artist: artists) { + listUrls.add(artist.getImgUrl()); + } + return listUrls; + } + + @Override + public int hashCode() { + return name.hashCode(); + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java new file mode 100644 index 0000000..242e6f1 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java @@ -0,0 +1,58 @@ +package ru.yandex.yamblz.ui.fragments.Genre; + +import android.support.v4.app.FragmentActivity; +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.ImageView; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; + +import ru.yandex.yamblz.R; +import ru.yandex.yamblz.handler.CriticalSectionsManager; +import ru.yandex.yamblz.loader.CollageLoaderManager; +import ru.yandex.yamblz.loader.CollageStrategyImpl; + +/** + * Created by kostya on 26.07.16. + */ + +public class GenreAdapter extends RecyclerView.Adapter { + private List genres = new ArrayList<>(); + private FragmentActivity context; + + public GenreAdapter(List genres, FragmentActivity context) { + this.genres = genres; + this.context = context; + } + + @Override + public GenreViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_row, parent, false); + return new GenreViewHolder(view); + } + + @Override + public void onBindViewHolder(GenreViewHolder holder, int position) { + Log.d("onBindViewHolder,pos = ", Integer.toString(position)); + Genre genre = genres.get(position); + holder.textInList.setText(genre.getDescription()); + new Thread(() -> { + Log.d("new Thread", "start: " + genre.getName()); + CollageLoaderManager + .getLoader() + .loadCollage(genre.getImgUrls(), + holder.imgInList, + new CollageStrategyImpl()); + }).start(); + } + + @Override + public int getItemCount() { + return genres.size(); + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreOnScrollListener.java b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreOnScrollListener.java new file mode 100644 index 0000000..f4d4bb9 --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreOnScrollListener.java @@ -0,0 +1,25 @@ +package ru.yandex.yamblz.ui.fragments.Genre; + +import android.support.v7.widget.RecyclerView; +import android.util.Log; + +import ru.yandex.yamblz.handler.CriticalSectionsManager; + +/** + * Created by kostya on 26.07.16. + */ + +public class GenreOnScrollListener extends RecyclerView.OnScrollListener { + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + super.onScrollStateChanged(recyclerView, newState); + if (newState == RecyclerView.SCROLL_STATE_DRAGGING) { + Log.d("nScrollStateChanged", "DRAGGING"); + CriticalSectionsManager.getHandler().startSection(42); + } + else if (newState == RecyclerView.SCROLL_STATE_IDLE) { + Log.d("nScrollStateChanged", "IDLE"); + CriticalSectionsManager.getHandler().stopSection(42); + } + } +} diff --git a/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreViewHolder.java b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreViewHolder.java new file mode 100644 index 0000000..bd60ffd --- /dev/null +++ b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreViewHolder.java @@ -0,0 +1,27 @@ +package ru.yandex.yamblz.ui.fragments.Genre; + +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import java.lang.ref.WeakReference; + +import ru.yandex.yamblz.R; + +/** + * Created by kostya on 26.07.16. + */ +public class GenreViewHolder extends RecyclerView.ViewHolder { + + ImageView imgInList; + TextView textInList; + + public GenreViewHolder(View itemView) { + super(itemView); + imgInList = (ImageView) itemView.findViewById(R.id.img_in_list); + textInList = (TextView) itemView.findViewById(R.id.text_in_list); + } + + +} diff --git a/app/src/main/res/layout/fragment_content.xml b/app/src/main/res/layout/fragment_content.xml index 81016ea..21583f5 100644 --- a/app/src/main/res/layout/fragment_content.xml +++ b/app/src/main/res/layout/fragment_content.xml @@ -1,14 +1,7 @@ - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/list_row.xml b/app/src/main/res/layout/list_row.xml new file mode 100644 index 0000000..b90ce0f --- /dev/null +++ b/app/src/main/res/layout/list_row.xml @@ -0,0 +1,27 @@ + + + + + + + + From bece8eb3dc1dd36b6c42bfaefd32f0a80b6c5292 Mon Sep 17 00:00:00 2001 From: Kostya Charkin <93kostya@gmail.com> Date: Thu, 28 Jul 2016 00:37:57 +0300 Subject: [PATCH 3/5] add remove old task if new task is coming --- .../yamblz/loader/StubCollageLoader.java | 28 +++++++++++++---- .../ui/fragments/Genre/GenreAdapter.java | 31 +++++++++++++------ 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java b/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java index 2ed76f4..0943c94 100644 --- a/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java +++ b/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java @@ -2,6 +2,9 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; import android.util.Log; import android.widget.ImageView; @@ -12,8 +15,10 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; +import java.util.Random; import ru.yandex.yamblz.handler.CriticalSectionsManager; +import ru.yandex.yamblz.handler.Task; public class StubCollageLoader implements CollageLoader { @@ -37,12 +42,14 @@ public void loadCollage(List urls, ImageView imageView, bitmapList.add(getBitmapFromURL(url)); } Bitmap bitmap = collageStrategy.create(bitmapList); - CriticalSectionsManager.getHandler().postLowPriorityTask(() -> { - if (imageView != null) { + if (imageView != null) { + imageView.post(() -> { + imageView.setImageBitmap(null); imageView.setImageBitmap(bitmap); imageView.invalidate(); - } - }); + }); + + } } @@ -54,6 +61,7 @@ public void loadCollage(List urls, ImageTarget imageTarget, private static Bitmap getBitmapFromURL(String src) { try { + //throw new IOException(); URL url = new URL(src); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); @@ -61,8 +69,16 @@ private static Bitmap getBitmapFromURL(String src) { InputStream input = connection.getInputStream(); return BitmapFactory.decodeStream(input); } catch (IOException e) { - // Log exception - return null; + Bitmap bitmap = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + int[] colors = {Color.BLACK, Color.BLUE, Color.GREEN, Color.RED}; + Random random = new Random(); + int ind = Math.abs(random.nextInt()) % colors.length; + Paint paint = new Paint(); + paint.setColor(colors[ind]); + canvas.drawCircle(150, 150, 150, paint); + canvas.save(); + return bitmap; } } } diff --git a/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java index 242e6f1..2d71187 100644 --- a/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java +++ b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java @@ -6,14 +6,13 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; -import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import ru.yandex.yamblz.R; import ru.yandex.yamblz.handler.CriticalSectionsManager; +import ru.yandex.yamblz.handler.Task; import ru.yandex.yamblz.loader.CollageLoaderManager; import ru.yandex.yamblz.loader.CollageStrategyImpl; @@ -41,14 +40,26 @@ public void onBindViewHolder(GenreViewHolder holder, int position) { Log.d("onBindViewHolder,pos = ", Integer.toString(position)); Genre genre = genres.get(position); holder.textInList.setText(genre.getDescription()); - new Thread(() -> { - Log.d("new Thread", "start: " + genre.getName()); - CollageLoaderManager - .getLoader() - .loadCollage(genre.getImgUrls(), - holder.imgInList, - new CollageStrategyImpl()); - }).start(); + + holder.imgInList.setImageBitmap(null); + + Object old_setter = holder.imgInList.getTag(); + if (old_setter != null) { + CriticalSectionsManager.getHandler().removeLowPriorityTask((Task) old_setter); + } + + Task setter = () -> { + new Thread(() -> { + Log.d("new Thread", "start: " + genre.getName()); + CollageLoaderManager + .getLoader() + .loadCollage(genre.getImgUrls(), + holder.imgInList, + new CollageStrategyImpl()); + }).start(); + }; + holder.imgInList.setTag(setter); + CriticalSectionsManager.getHandler().postLowPriorityTask(setter); } @Override From 96d8e11d4657433ef913223681b487e54e8f60fc Mon Sep 17 00:00:00 2001 From: Kostya Charkin <93kostya@gmail.com> Date: Thu, 28 Jul 2016 02:29:24 +0300 Subject: [PATCH 4/5] some fixes --- .../handler/StubCriticalSectionsHandler.java | 6 +++++- .../ru/yandex/yamblz/loader/CollageStrategy.java | 1 + .../yamblz/loader/CollageStrategyImpl.java | 5 +++++ .../yandex/yamblz/loader/StubCollageLoader.java | 16 ++++------------ .../yamblz/ui/fragments/Genre/GenreAdapter.java | 5 +++-- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java b/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java index 7146504..fa3e0b4 100644 --- a/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java +++ b/app/src/main/java/ru/yandex/yamblz/handler/StubCriticalSectionsHandler.java @@ -33,13 +33,17 @@ public void run() { @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); } @@ -55,7 +59,7 @@ public void stopSections() { public void postLowPriorityTask(Task task) { Log.d("postLowPriorityTask", "post"); taskQueue.add(task); - if (taskQueue.size() == 1) { + if (taskQueue.size() == 1 && sections.isEmpty()) { handler.post(callBack); } } diff --git a/app/src/main/java/ru/yandex/yamblz/loader/CollageStrategy.java b/app/src/main/java/ru/yandex/yamblz/loader/CollageStrategy.java index d81d52d..4909361 100644 --- a/app/src/main/java/ru/yandex/yamblz/loader/CollageStrategy.java +++ b/app/src/main/java/ru/yandex/yamblz/loader/CollageStrategy.java @@ -7,4 +7,5 @@ public interface CollageStrategy { Bitmap create(List bitmaps); + int numOfImage(); } diff --git a/app/src/main/java/ru/yandex/yamblz/loader/CollageStrategyImpl.java b/app/src/main/java/ru/yandex/yamblz/loader/CollageStrategyImpl.java index 504ab25..5accf27 100644 --- a/app/src/main/java/ru/yandex/yamblz/loader/CollageStrategyImpl.java +++ b/app/src/main/java/ru/yandex/yamblz/loader/CollageStrategyImpl.java @@ -38,4 +38,9 @@ else if (bitmaps.size() < 4) { return bitmap; } } + + @Override + public int numOfImage() { + return 4; + } } diff --git a/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java b/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java index 0943c94..9a6c5fa 100644 --- a/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java +++ b/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java @@ -10,16 +10,12 @@ import java.io.IOException; import java.io.InputStream; -import java.lang.ref.WeakReference; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Random; -import ru.yandex.yamblz.handler.CriticalSectionsManager; -import ru.yandex.yamblz.handler.Task; - public class StubCollageLoader implements CollageLoader { @Override @@ -37,20 +33,17 @@ public void loadCollage(List urls, ImageView imageView, CollageStrategy collageStrategy) { Log.d("loadCollage", "download"); List bitmapList = new ArrayList<>(); - for (String url : - urls) { - bitmapList.add(getBitmapFromURL(url)); + int size = Math.min(collageStrategy.numOfImage(), urls.size()); + for (int i = 0; i < size; i++) { + bitmapList.add(getBitmapFromURL(urls.get(i))); } Bitmap bitmap = collageStrategy.create(bitmapList); if (imageView != null) { imageView.post(() -> { - imageView.setImageBitmap(null); + imageView.setImageDrawable(null); imageView.setImageBitmap(bitmap); - imageView.invalidate(); }); - } - } @Override @@ -61,7 +54,6 @@ public void loadCollage(List urls, ImageTarget imageTarget, private static Bitmap getBitmapFromURL(String src) { try { - //throw new IOException(); URL url = new URL(src); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); diff --git a/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java index 2d71187..82c14a7 100644 --- a/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java +++ b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java @@ -39,12 +39,13 @@ public GenreViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public void onBindViewHolder(GenreViewHolder holder, int position) { Log.d("onBindViewHolder,pos = ", Integer.toString(position)); Genre genre = genres.get(position); - holder.textInList.setText(genre.getDescription()); + holder.textInList.setText(genre.getName() + "\n" + genre.getDescription()); - holder.imgInList.setImageBitmap(null); + holder.imgInList.setImageDrawable(null); Object old_setter = holder.imgInList.getTag(); if (old_setter != null) { + Log.d("onBindViewHolder", "removeLowPriorityTask"); CriticalSectionsManager.getHandler().removeLowPriorityTask((Task) old_setter); } From b36681d92c03d4c9df102d68da7ae79e1c1648d5 Mon Sep 17 00:00:00 2001 From: Kostya Charkin <93kostya@gmail.com> Date: Fri, 29 Jul 2016 00:22:59 +0300 Subject: [PATCH 5/5] add ThreadPool; hide creating threads behind implementation --- .../yamblz/loader/StubCollageLoader.java | 52 ++++++++++++++++--- .../ui/fragments/Genre/GenreAdapter.java | 29 +++-------- 2 files changed, 51 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java b/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java index 9a6c5fa..3b0662f 100644 --- a/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java +++ b/app/src/main/java/ru/yandex/yamblz/loader/StubCollageLoader.java @@ -15,9 +15,19 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.UUID; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import ru.yandex.yamblz.R; +import ru.yandex.yamblz.handler.CriticalSectionsManager; +import ru.yandex.yamblz.handler.Task; public class StubCollageLoader implements CollageLoader { + private final ExecutorService pool = Executors.newFixedThreadPool(10); + @Override public void loadCollage(List urls, ImageView imageView) { @@ -31,14 +41,46 @@ public void loadCollage(List urls, ImageTarget imageTarget) { @Override public void loadCollage(List urls, ImageView imageView, CollageStrategy collageStrategy) { - Log.d("loadCollage", "download"); + imageView.setImageDrawable(null); + + Object old_setter = imageView.getTag(); + if (old_setter != null) { + Log.d("onBindViewHlder", "removeLowPriorityTask"); + CriticalSectionsManager.getHandler().removeLowPriorityTask((Task) old_setter); + } + + UUID uuid = UUID.randomUUID(); + + Task setter = () -> { + pool.execute(() -> loadCollageImpl( + urls, + imageView, + collageStrategy, + uuid + )); + }; + + imageView.setTag(setter); + imageView.setTag(R.id.img_in_list, uuid); + CriticalSectionsManager.getHandler().postLowPriorityTask(setter); + } + + @Override + public void loadCollage(List urls, ImageTarget imageTarget, + CollageStrategy collageStrategy) { + + } + + private void loadCollageImpl(List urls, ImageView imageView, + CollageStrategy collageStrategy, UUID uuid) { + Log.d("loadCollageImpl", "download"); List bitmapList = new ArrayList<>(); int size = Math.min(collageStrategy.numOfImage(), urls.size()); for (int i = 0; i < size; i++) { bitmapList.add(getBitmapFromURL(urls.get(i))); } Bitmap bitmap = collageStrategy.create(bitmapList); - if (imageView != null) { + if (imageView != null && imageView.getTag(R.id.img_in_list).equals(uuid)) { imageView.post(() -> { imageView.setImageDrawable(null); imageView.setImageBitmap(bitmap); @@ -46,12 +88,6 @@ public void loadCollage(List urls, ImageView imageView, } } - @Override - public void loadCollage(List urls, ImageTarget imageTarget, - CollageStrategy collageStrategy) { - - } - private static Bitmap getBitmapFromURL(String src) { try { URL url = new URL(src); diff --git a/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java index 82c14a7..11ce4cc 100644 --- a/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java +++ b/app/src/main/java/ru/yandex/yamblz/ui/fragments/Genre/GenreAdapter.java @@ -13,6 +13,7 @@ import ru.yandex.yamblz.R; import ru.yandex.yamblz.handler.CriticalSectionsManager; import ru.yandex.yamblz.handler.Task; +import ru.yandex.yamblz.loader.CollageLoader; import ru.yandex.yamblz.loader.CollageLoaderManager; import ru.yandex.yamblz.loader.CollageStrategyImpl; @@ -37,30 +38,14 @@ public GenreViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { @Override public void onBindViewHolder(GenreViewHolder holder, int position) { - Log.d("onBindViewHolder,pos = ", Integer.toString(position)); Genre genre = genres.get(position); + Log.d("onBindViewHlder", "genre = " + genre.getName()); holder.textInList.setText(genre.getName() + "\n" + genre.getDescription()); - - holder.imgInList.setImageDrawable(null); - - Object old_setter = holder.imgInList.getTag(); - if (old_setter != null) { - Log.d("onBindViewHolder", "removeLowPriorityTask"); - CriticalSectionsManager.getHandler().removeLowPriorityTask((Task) old_setter); - } - - Task setter = () -> { - new Thread(() -> { - Log.d("new Thread", "start: " + genre.getName()); - CollageLoaderManager - .getLoader() - .loadCollage(genre.getImgUrls(), - holder.imgInList, - new CollageStrategyImpl()); - }).start(); - }; - holder.imgInList.setTag(setter); - CriticalSectionsManager.getHandler().postLowPriorityTask(setter); + CollageLoaderManager.getLoader().loadCollage( + genre.getImgUrls(), + holder.imgInList, + new CollageStrategyImpl() + ); } @Override