Skip to content

Conversation

@TimofeyTalenfeld
Copy link

@TimofeyTalenfeld TimofeyTalenfeld commented Aug 10, 2016

ContentProvider + SQLite + Fragments
Demo: https://yadi.sk/i/rD5ggFFQu7hwo (телефон)

Планшета нет, эмулятор мой ноут не потянул. В принципе архитектура там схожая, есть разветвление только на самом первом фрагменте (в java коде) на ArtistsFragment и ArtistsLargeFragment, далее они коммитят одни и те же фрагменты, поэтому поведение должно быть почти одинаково.

public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db);
db.rawQuery("PRAGMA foreign_keys = ON", null);
db.rawQuery("PRAGMA journal_mode = WAL", null);

Choose a reason for hiding this comment

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

есть встроенные методы в SQLiteDatabase для этих прагм, попробуй их заюзать.

@matreshkin
Copy link

matreshkin commented Aug 11, 2016

ЖДУ ОБНОВЛЕНИЙ

@TimofeyTalenfeld
Copy link
Author

Замечания исправлены.

@zagayevskiy
Copy link
Contributor

Падает при старте без провайдера:

FATAL EXCEPTION: AsyncTask #1
Process: ru.yandex.yamblz.debug, PID: 25333
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void android.database.Cursor.close()' on a null object reference
at ru.yandex.yamblz.util.asynctask.GettingArtistsAsyncTask.doInBackground(GettingArtistsAsyncTask.java:59)
at ru.yandex.yamblz.util.asynctask.GettingArtistsAsyncTask.doInBackground(GettingArtistsAsyncTask.java:20)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818) 

/**
* Created by root on 8/9/16.
*/
public class GettingArtistsAsyncTask extends AsyncTask<Void, Void, Artist[]> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Для этого специально есть Loader'ы.

Copy link
Author

Choose a reason for hiding this comment

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

А чем в этом случае плох AsyncTask? Я не настаиваю на нем, просто пытаюсь понять, как делать правильно. Просто у нас была лекция по background, и мы выяснили, что для небольших задач вполне себе можно использовать AsyncTask, если правильно с ним работать.

Copy link
Contributor

Choose a reason for hiding this comment

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

Он не привязан к жизненному циклу. И он не плох, просто лоадеры - чуть более высокая абстракция. Там есть AsyncTaskLoader, который основан на асинктаске. Плюс ты из коробки получаешь нотификации и апдейт данных при их изменении.

@zagayevskiy
Copy link
Contributor

С провайдером как-то тоже не всё хорошо. Список не показывает.

Error inserting genre_id=3 artist_id=122
android.database.sqlite.SQLiteException: foreign key mismatch - "artist_genre" referencing "genre" (code 1): , while compiling: INSERT INTO artist_genre(genre_id,artist_id) VALUES (?,?)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:887)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:498)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1469)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1341)
at ru.yandex.provider.database.ArtistDbBackend.createArtistGenreRelation(ArtistDbBackend.java:107)
at ru.yandex.provider.database.ArtistDbBackend.insertGenres(ArtistDbBackend.java:90)
at ru.yandex.provider.database.ArtistDbBackend.insertArtist(ArtistDbBackend.java:58)
at ru.yandex.provider.ArtistProvider.loadFromNetwork(ArtistProvider.java:73)
at ru.yandex.provider.ArtistProvider.query(ArtistProvider.java:56)
at android.content.ContentProvider.query(ContentProvider.java:1017)
at android.content.ContentProvider$Transport.query(ContentProvider.java:238)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
at android.os.Binder.execTransact(Binder.java:453)
08-11 22:06:39.117 25442-25463/ru.yandex.provider.debug E/SQLiteLog: (1) foreign key mismatch - "artist_genre" referencing "genre"

@TimofeyTalenfeld
Copy link
Author

Странно, у меня не падает провайдер, хотя я даже специально БД удаляю при запуске.

super.onActivityCreated(savedInstanceState);

if(!(getActivity() instanceof OnDetailClickListener)) {
throw new IllegalStateException("Host activity must implement " + OnDetailClickListener.class.getCanonicalName());
Copy link
Contributor

Choose a reason for hiding this comment

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

Лучше делать это намного раньше - когда активити впервые доступна, т.е. в onAttach. Тогда практически во всех методах жц ты можешь быть уверен, что активити реализует то, что ты хочешь.


public ArtistDbOpenHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
context.deleteDatabase(DB_NAME);

Choose a reason for hiding this comment

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

АААА! Зачем? Каждый раз пересобирать БД??

Copy link
Author

@TimofeyTalenfeld TimofeyTalenfeld Aug 12, 2016

Choose a reason for hiding this comment

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

Ты не понял, эту строку я добавил для проверки того, падает ли SQLite при создании или нет. Т.е. это был временный эксперимент, а удалить строку я забыл)

Choose a reason for hiding this comment

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

ок

@matreshkin
Copy link

ПОСМОТРЕНО, можно обновлять

Чет удаление БД повергло меня в шок.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants