Skip to content
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

@guliash & Artem Gilmudinov #5

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 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
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ dependencies {
compile libraries.supportDesign
compile libraries.supportRecyclerView
compile libraries.supportCardView
compile libraries.picasso

compile libraries.butterKnife
apt libraries.butterKnifeCompiler
Expand All @@ -104,6 +105,7 @@ dependencies {
compile libraries.tinyDancer
compile libraries.lynx
compile libraries.processPhoenix
compile project(':singerscontracts')

testCompile libraries.junit
testCompile libraries.robolectric
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="ru.yandex.yamblz">

<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="ru.yandex.yamblz.provider.READ_SINGERS"/>
<uses-permission android:name="ru.yandex.yamblz.provider.WRITE_SINGERS"/>
<application
tools:replace="android:allowBackup"
android:name="ru.yandex.yamblz.App"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
Expand Down
12 changes: 12 additions & 0 deletions app/src/main/java/ru/yandex/yamblz/ApplicationComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
import ru.yandex.yamblz.developer_settings.DeveloperSettingsModule;
import ru.yandex.yamblz.developer_settings.LeakCanaryProxy;
import ru.yandex.yamblz.ui.activities.MainActivity;
import ru.yandex.yamblz.ui.fragments.DescFragment;
import ru.yandex.yamblz.ui.fragments.ListFragment;
import ru.yandex.yamblz.ui.fragments.PreviewFragment;
import ru.yandex.yamblz.ui.fragments.TabsFragment;

@Singleton
@Component(modules = {
Expand All @@ -36,4 +40,12 @@ public interface ApplicationComponent {
Handler mainThreadHandler();

void inject(@NonNull MainActivity mainActivity);

void inject(DescFragment descFragment);

void inject(PreviewFragment previewFragment);

void inject(ListFragment listFragment);

void inject(TabsFragment tabsFragment);
}
51 changes: 51 additions & 0 deletions app/src/main/java/ru/yandex/yamblz/ApplicationModule.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
package ru.yandex.yamblz;

import android.app.Application;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;

import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.inject.Named;
import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import ru.yandex.yamblz.provider.CPDataProvider;
import ru.yandex.yamblz.provider.CPDataTransformer;
import ru.yandex.yamblz.provider.DataProvider;
import ru.yandex.yamblz.provider.DataTransformer;

@Module
public class ApplicationModule {

public static final String MAIN_THREAD_HANDLER = "main_thread_handler";
public static final String WORK_EXECUTOR = "worker";
public static final String POST_EXECUTOR = "poster";

@NonNull
private final Application application;
Expand All @@ -33,4 +45,43 @@ public Handler provideMainThreadHandler() {
return new Handler(Looper.getMainLooper());
}

@Provides
@Singleton
Context provideContext() {
return application;
}

@Provides
@Singleton
@Named(WORK_EXECUTOR)
Executor provideWorker() {
return new ThreadPoolExecutor(4, 10, 120, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
}

@Provides
@Singleton
@Named(POST_EXECUTOR)
Executor providePoster(@Named(MAIN_THREAD_HANDLER) final Handler uiHandler) {
return new Executor() {
@Override
public void execute(Runnable command) {
uiHandler.post(command);
}
};
}

@Provides
@Singleton
DataTransformer provideDataTransformer() {
return new CPDataTransformer();
}

@Provides
@Singleton
DataProvider provideDataProvider(Context context, DataTransformer dataTransformer,
@Named(WORK_EXECUTOR) Executor worker,
@Named(POST_EXECUTOR) Executor poster) {
return new CPDataProvider(context, dataTransformer, worker, poster);
}

}
94 changes: 94 additions & 0 deletions app/src/main/java/ru/yandex/yamblz/provider/CPDataProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package ru.yandex.yamblz.provider;

import android.content.ContentUris;
import android.content.Context;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executor;

import ru.yandex.yamblz.performance.AnyThread;
import ru.yandex.yamblz.singerscontracts.Singer;

import static ru.yandex.yamblz.singerscontracts.SingersContract.Singers;

/**
* Content provider based {@link DataProvider}.
* Executes long methods on a background thread, posts result back to the main thread
*/
public class CPDataProvider implements DataProvider {
Copy link

@matreshkin matreshkin Aug 12, 2016

Choose a reason for hiding this comment

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

Понял, о каком провайдере ты говорил)
Это немного другой провайдер, о котором я говорил.
Их функционалы практически одинаковы, разница лишь в месте, в котором они находятся.
Здесь он тоже уместен и выполняет задачи, мне нравится.


private Context mContext;
private DataTransformer mDataTransformer;
private Executor mWorker, mPoster;
private Set<Callback> mCallbacks = new HashSet<>(0);

@MainThread
public CPDataProvider(Context context, DataTransformer dataTransformer, Executor worker,
Executor poster) {
mContext = context;
mDataTransformer = dataTransformer;
mWorker = worker;
mPoster = poster;
}

@MainThread
private void persistCallback(Callback callback) {
mCallbacks.add(callback);
}

@MainThread
private boolean checkIfSubscribed(Callback callback) {
return mCallbacks.contains(callback);
}

@MainThread
@Override
public void getSingers(final Callback<List<Singer>> callback) {
persistCallback(callback);
mWorker.execute(new Runnable() {
@Override
public void run() {
List<Singer> singers = mDataTransformer.toSingers(mContext.getContentResolver().query(
Singers.CONTENT_URI, null, null, null, null));
postResult(callback, singers);
}
});
}

@Override
public void getSinger(final int singerId, @NonNull final Callback<Singer> callback) {
persistCallback(callback);
mWorker.execute(new Runnable() {
@Override
public void run() {
Singer singer = mDataTransformer.toSinger(mContext.getContentResolver().query(
ContentUris.withAppendedId(Singers.CONTENT_URI, singerId),
null, null, null, null));
postResult(callback, singer);
}
});
}

@MainThread
@Override
public void cancel(Callback callback) {
mCallbacks.remove(callback);
}

@AnyThread
private <T> void postResult(final Callback<T> callback, final T result) {
mPoster.execute(new Runnable() {
@Override
public void run() {
if(checkIfSubscribed(callback)) {
callback.postResult(result);
cancel(callback);
}
}
});
}
}
44 changes: 44 additions & 0 deletions app/src/main/java/ru/yandex/yamblz/provider/CPDataTransformer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package ru.yandex.yamblz.provider;

import android.database.Cursor;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;

import ru.yandex.yamblz.singerscontracts.Singer;

/**
* Transforms data from Cursor formed by {@link ru.yandex.yamblz.singerscontracts.SingersContract}
*/
public class CPDataTransformer implements DataTransformer {

@Override
@NonNull
public List<Singer> toSingers(@Nullable Cursor cursor) {
List<Singer> singers = new ArrayList<>();
if(cursor == null) {
return singers;
}
cursor.moveToFirst();
do {
singers.add(Singer.readSinger(cursor));
} while(cursor.moveToNext());
cursor.close();
return singers;
}

@Nullable
@Override
public Singer toSinger(@Nullable Cursor cursor) {
if(cursor == null) {
return null;
}
cursor.moveToFirst();

Singer singer = Singer.readSinger(cursor);
cursor.close();
return singer;
}
}
22 changes: 22 additions & 0 deletions app/src/main/java/ru/yandex/yamblz/provider/DataProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ru.yandex.yamblz.provider;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import java.util.List;

import ru.yandex.yamblz.singerscontracts.Singer;

public interface DataProvider {

interface Callback<T>{
void postResult(@Nullable T result);
}

void getSingers(@NonNull Callback<List<Singer>> callback);

void getSinger(int singerId, @NonNull Callback<Singer> callback);

void cancel(@NonNull Callback callback);

}
22 changes: 22 additions & 0 deletions app/src/main/java/ru/yandex/yamblz/provider/DataTransformer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ru.yandex.yamblz.provider;

import android.database.Cursor;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import java.util.List;

import ru.yandex.yamblz.singerscontracts.Singer;

/**
* Transforms data from Cursor formed by some contract
*/
public interface DataTransformer {

@NonNull
List<Singer> toSingers(@Nullable Cursor cursor);

@Nullable
Singer toSinger(@Nullable Cursor cursor);

}
Loading