Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ dependencies {

compile libraries.timber

compile libraries.rxjava
compile libraries.rxandroid
compile libraries.solidstreams
compile libraries.solidcollections

// Developer tools (Developer Settings)
compile libraries.stetho
compile libraries.leakCanary
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
<activity
android:name="ru.yandex.yamblz.ui.activities.MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
android:theme="@style/AppTheme.NoActionBar"
android:screenOrientation="locked">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/ru/yandex/yamblz/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import ru.yandex.yamblz.developer_settings.DevMetricsProxy;
import ru.yandex.yamblz.developer_settings.DeveloperSettingsModel;
import ru.yandex.yamblz.handler.CriticalSectionsHandlerImpl;
import ru.yandex.yamblz.handler.CriticalSectionsManager;
import ru.yandex.yamblz.loader.CollageLoaderManager;
import timber.log.Timber;
Expand Down Expand Up @@ -35,7 +36,7 @@ public void onCreate() {
}

CollageLoaderManager.init(null); // add implementation
CriticalSectionsManager.init(null); // add implementation
CriticalSectionsManager.init(new CriticalSectionsHandlerImpl());
}

@NonNull
Expand Down
106 changes: 106 additions & 0 deletions app/src/main/java/ru/yandex/yamblz/data/Artist.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package ru.yandex.yamblz.data;

import android.database.Cursor;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import java.util.List;

/**
* Stores data about one artist.
*/
@SuppressWarnings("WeakerAccess")
public class Artist implements Parcelable {
public static final Creator<Artist> CREATOR = new Creator<Artist>() {
@Override
public Artist createFromParcel(Parcel in) {
return new Artist(in);
}

@Override
public Artist[] newArray(int size) {
return new Artist[size];
}
};
public int id;
public String name;
public List<String> genres;
public int tracks, albums;
public String link;
public String description;
public String smallCover, bigCover;

public Artist() {
}

/**
* Creates an instance from parcel.
* @param in parcel.
*/
protected Artist(Parcel in) {
id = in.readInt();
name = in.readString();
genres = in.createStringArrayList();
tracks = in.readInt();
albums = in.readInt();
link = in.readString();
description = in.readString();
smallCover = in.readString();
bigCover = in.readString();
}

/**
* Returns link to small cover at current row of cursor,
*/
public static String getSmallCover(Cursor cursor) {
return cursor.getString(7);
}

/**
* Returns link to big cover at current row of cursor,
*/
public static String getBigCover(Cursor cursor) {
return cursor.getString(8);
}

/**
* Returns genres as a comma-separated string.
*/
public String getGenres() {
return TextUtils.join(", ", genres);
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(name);
dest.writeStringList(genres);
dest.writeInt(tracks);
dest.writeInt(albums);
dest.writeString(link);
dest.writeString(description);
dest.writeString(smallCover);
dest.writeString(bigCover);
}

@Override
public int describeContents() {
return 0;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

Artist artist = (Artist) o;

return id == artist.id;
}

@Override
public int hashCode() {
return id;
}
}
106 changes: 106 additions & 0 deletions app/src/main/java/ru/yandex/yamblz/data/InfoObservable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package ru.yandex.yamblz.data;

import android.util.JsonReader;
import android.util.Log;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import rx.Observable;

public class InfoObservable {

private static final String jsonURL = "http://cache-spb03.cdn.yandex.net/" +
"download.cdn.yandex.net/mobilization-2016/artists.json";
private static final String TAG = InfoObservable.class.getSimpleName();

public static Observable<List<Artist>> getObservable() {
return Observable.fromCallable(InfoObservable::download);
}

private static List<Artist> download() throws IOException {
try (JsonReader reader = new JsonReader(
new InputStreamReader(
new URL(jsonURL)
.openStream(),
"UTF-8"))) {
Log.d(TAG, "downloading");
List<Artist> artists = new ArrayList<>();
reader.beginArray();

while (reader.hasNext()) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А с помощью GSON почему не сериализовал или как то более проще?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Этот код у меня уже был :)

Artist artist = new Artist();
reader.beginObject();

while (reader.hasNext()) {
String name = reader.nextName();
switch (name) {
case "id":
artist.id = reader.nextInt();
break;
case "name":
artist.name = reader.nextString();
break;
case "genres":
List<String> genres = new ArrayList<>();
reader.beginArray();
while (reader.hasNext()) {
genres.add(reader.nextString());
}
reader.endArray();
artist.genres = genres;
break;
case "tracks":
artist.tracks = reader.nextInt();
break;
case "albums":
artist.albums = reader.nextInt();
break;
case "link":
artist.link = reader.nextString();
break;
case "description":
artist.description = reader.nextString();
break;
case "cover":
reader.beginObject();
for (int i = 0; i < 2; ++i) {
String size = reader.nextName();
String cover = reader.nextString();
switch (size) {
case "small":
artist.smallCover = cover;
break;
case "big":
artist.bigCover = cover;
break;
default:
Log.d(TAG, "Unknown cover size " + size);
break;
}
}
reader.endObject();
break;
default:
Log.w(TAG, "Unknown name '" + name + "'");
reader.skipValue();
break;
}
}

reader.endObject();
artists.add(artist);
}

reader.endArray();

Log.d(TAG, "downloaded");

return artists;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public interface CriticalSectionsHandler {

void postLowPriorityTask(Task task);

void postLowPriorityTaskDelayed(Task task, int delay);
void postLowPriorityTaskDelayed(Task task, int delayMillis);

void removeLowPriorityTask(Task task);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package ru.yandex.yamblz.handler;

import android.os.Handler;
import android.os.Looper;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

/**
* Non thread-safe implementation of {@link CriticalSectionsHandler}.
*/
@SuppressWarnings("WeakerAccess")
public class CriticalSectionsHandlerImpl implements CriticalSectionsHandler {

private final Handler handler;
private final Set<Integer> sections;

private final Runnable executeTask;
private final Set<Task> taskQueue;

private final Map<Task, Runnable> delayedTasks;


public CriticalSectionsHandlerImpl() {
handler = new Handler(Looper.getMainLooper());
sections = new HashSet<>();

executeTask = buildExecuteTask();
taskQueue = new LinkedHashSet<>();

delayedTasks = new HashMap<>();
}

private Runnable buildExecuteTask() {
return () -> {
Task currentTask = null;
currentTask = taskQueue.iterator().next();
taskQueue.remove(currentTask);

// This runnable is in execution queue iff taskQueue is not empty.
assert currentTask != null;
currentTask.run();

if (!taskQueue.isEmpty() && sections.isEmpty()) {
handler.post(executeTask);
}
};
}

@Override
public void startSection(int id) {
sections.add(id);
if (!taskQueue.isEmpty()) {
handler.removeCallbacks(executeTask);
}
}

@Override
public void stopSection(int id) {
sections.remove(id);
if (sections.isEmpty()) {
if (!taskQueue.isEmpty()) {
handler.post(executeTask);
}
}
}

@Override
public void stopSections() {
sections.clear();
if (!taskQueue.isEmpty()) {
handler.post(executeTask);
}
}

@Override
public void postLowPriorityTask(Task task) {
if (taskQueue.add(task) && sections.isEmpty() && taskQueue.size() == 1) {
handler.post(executeTask);
}
delayedTasks.remove(task);
}

@Override
public void postLowPriorityTaskDelayed(Task task, int delayMillis) {
if (taskQueue.contains(task)) {
return;
}

Runnable runnable = () -> {
if (delayedTasks.containsKey(task)) {
postLowPriorityTask(task);
}
};
delayedTasks.put(task, runnable);
handler.postDelayed(runnable, delayMillis);
}

@Override
public void removeLowPriorityTask(Task task) {
if (taskQueue.contains(task)) {
taskQueue.remove(task);
if (taskQueue.isEmpty()) {
handler.removeCallbacks(executeTask);
}
}
if (delayedTasks.containsKey(task)) {
delayedTasks.remove(task);
}
}

@Override
public void removeLowPriorityTasks() {
taskQueue.clear();
delayedTasks.clear();
handler.removeCallbacks(executeTask);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public static void init(CriticalSectionsHandler criticalSectionsHandler) {

public static CriticalSectionsHandler getHandler() {
if (sCriticalSectionsHandler == null) {
sCriticalSectionsHandler = new StubCriticalSectionsHandler();
sCriticalSectionsHandler = new CriticalSectionsHandlerImpl();
}
return sCriticalSectionsHandler;
}
Expand Down
Loading