• 0
Rusland

Одновременное обращение к БД Sqlite из программы и из сервиса

Вопросы

Можно ли работать с одной базой одновременно и из программы и из сервиса?

PS. Android

Изменено пользователем Rusland

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 ответов на этот вопрос

  • 0

Совсем забыл, из сервиса никак к БД не обратиться - иначе валится с ошибкой Segment fault и валит вместе с собой основное приложение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 1
В 01.04.2016 в 15:01, Rusland сказал:

Совсем забыл, из сервиса никак к БД не обратиться - иначе валится с ошибкой Segment fault и валит вместе с собой основное приложение.

А как ты connection к БД прописываешь с апликухи и из сервиса?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

 

SQLite может быть собран в однопоточном варианте (параметр компиляции SQLITE_THREADSAFE = 0). 

Подробнее:

https://m.habrahabr.ru/post/149635/

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 02.04.2016 в 23:29, umkes сказал:

А как ты connection к БД прописываешь с апликухи и из сервиса?

Через TFDConnection, указав путь к файлу

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

 

2 часа назад, Rusland сказал:

Через TFDConnection, указав путь к файлу

Rusland, может конечно бредовая версия, т.к. слишком просто :-)  где файл БД лежит? есть ли у сервиса доступ к нему?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 1
3 часа назад, Belov.V. сказал:

 

Rusland, может конечно бредовая версия, т.к. слишком просто :-)  где файл БД лежит? есть ли у сервиса доступ к нему?

БД кладу в TPath.GetDocumentsPath.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Я так же мучался с ини файлом. В конце концов прописал путь напрямую. Думаю что с БД так же прокатит.

Пример:

В апликации фаил создавался по такому пути:

System.IOUtils.TPath.Combine(System.IOUtils.TPath.GetDocumentsPath, 'KDGConfig.ini');

А в сервисе задавался такой путь:

'/data/data/com.embarcadero.KDGPhoneCallApplication/files/KDGConfig.ini'

Изменено пользователем umkes

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Rusland, удалось решить эту проблему?

Еще есть эта ветка про такое.

На Stackoverflow создал вопрос, ждем ответа.

Изменено пользователем Pax Beach

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

в PlatformSDK есть helper SQLiteOpenHelper.java, в нем метод getWritableDatabase(). Осталось научиться в сервисе работать с SQLite таким образом.

Может есть из вас, кто хорошо разобрался, как импортировать JAVA код в Delphi?

    /**
     * Create and/or open a database that will be used for reading and writing.
     * The first time this is called, the database will be opened and
     * {@link #onCreate}, {@link #onUpgrade} and/or {@link #onOpen} will be
     * called.
     *
     * <p>Once opened successfully, the database is cached, so you can
     * call this method every time you need to write to the database.
     * (Make sure to call {@link #close} when you no longer need the database.)
     * Errors such as bad permissions or a full disk may cause this method
     * to fail, but future attempts may succeed if the problem is fixed.</p>
     *
     * <p class="caution">Database upgrade may take a long time, you
     * should not call this method from the application main thread, including
     * from {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.
     *
     * @throws SQLiteException if the database cannot be opened for writing
     * @return a read/write database object valid until {@link #close} is called
     */
    public synchronized SQLiteDatabase getWritableDatabase() {
        if (mDatabase != null) {
            if (!mDatabase.isOpen()) {
                // darn! the user closed the database by calling mDatabase.close()
                mDatabase = null;
            } else if (!mDatabase.isReadOnly()) {
                return mDatabase;  // The database is already open for business
            }
        }

        if (mIsInitializing) {
            throw new IllegalStateException("getWritableDatabase called recursively");
        }

        // If we have a read-only database open, someone could be using it
        // (though they shouldn't), which would cause a lock to be held on
        // the file, and our attempts to open the database read-write would
        // fail waiting for the file lock.  To prevent that, we acquire the
        // lock on the read-only database, which shuts out other users.

        boolean success = false;
        SQLiteDatabase db = null;
        if (mDatabase != null) mDatabase.lock();
        try {
            mIsInitializing = true;
            if (mName == null) {
                db = SQLiteDatabase.create(null);
            } else {
                db = mContext.openOrCreateDatabase(mName, 0, mFactory, mErrorHandler);
            }

            int version = db.getVersion();
            if (version != mNewVersion) {
                db.beginTransaction();
                try {
                    if (version == 0) {
                        onCreate(db);
                    } else {
                        if (version > mNewVersion) {
                            onDowngrade(db, version, mNewVersion);
                        } else {
                            onUpgrade(db, version, mNewVersion);
                        }
                    }
                    db.setVersion(mNewVersion);
                    db.setTransactionSuccessful();
                } finally {
                    db.endTransaction();
                }
            }

            onOpen(db);
            success = true;
            return db;
        } finally {
            mIsInitializing = false;
            if (success) {
                if (mDatabase != null) {
                    try { mDatabase.close(); } catch (Exception e) { }
                    mDatabase.unlock();
                }
                mDatabase = db;
            } else {
                if (mDatabase != null) mDatabase.unlock();
                if (db != null) db.close();
            }
        }
    }

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • -1

Возможный выход из ситуации не держать постоянный коннект к базе? Открыл, прочитал или записал, закрыл. Можно перед открытием проверку на доступ сделать с ожиданием.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Я нашел решение, к сожалению, пока только для работы с UniDAC:

Обновил UniDAC компоненты для Berlin до последней версии (6.3.12).

Компоненты TUniConnection и TUniQuery отлично работают с SQLite в Android Service. FireDAC в Android Service пока запустить не удалось, но у меня такой задачи нет.

В Deployment host приложения добавляю файл базы данных, Remote Path задаю ".\assets\internal\". И спокойно из сервиса получаю к нему доступ. Мой сервис локальный в одном потоке с приложением. Если делать Intent Service или Remote — наверное, придется помещать файл в другой, доступный каталог, или общаться через намерения (Intents).

Надеюсь мой код будет полезен для вас.

procedure TDM.conSQLiteBeforeConnect(Sender: TObject);
begin
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
  conSQLite.Database := TPath.Combine(TPath.GetDocumentsPath, 'mybase.sqlite');
{$ENDIF}
end;

procedure TDM.conSQLiteError(Sender: TObject; E: EDAError; var Fail: Boolean);
begin
  Log('--- DB error: %s:', [E.Message]);
  Fail := False;
end;

function TDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
  Log('+ START with Intent: ' + JStringToString(Intent.getAction.toString), []);
  if Intent.getAction.equalsIgnoreCase(StringToJString('StopIntent')) then
  begin
    try
      conSQLite.Disconnect;
      Log('- DB disconnected', []);
    except
      on E: Exception do
        Log('- can not to disconnect DB', [E.Message]);
    end;

    Log('... service to be stoped', []);
    JavaService.stopSelf;

    Result := TJService.JavaClass.START_NOT_STICKY; // don't reload service
  end
  else
  begin
    Log('... service started', []);

    try
      conSQLite.Connect;
      Log('+ DB connected', []);

      UniQuery.SQL.Text := 'select count(*) as ALLREC from orders';
      UniQuery.Open;
      if UniQuery.RecordCount > 0 then
      begin
        UniQuery.First;
        Log('... record count: %s', [UniQuery.FieldByName('ALLREC').AsString]);
      end;
      UniQuery.Close;
    except
      on E: Exception do
        Log('- can not to connect DB: %s', [E.Message]);
    end;

    Result := TJService.JavaClass.START_STICKY; // rerun service if it stops
  end;
end;
Изменено пользователем Pax Beach

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

... Продолжаем исследование по теме:

Оказывается в модуле Androidapi.JNI.GraphicsContentViewText есть класс TJSQLiteDatabase, который реализует возможность работы с SQLite на Android.

Пример использования этого класса на JAVA я писал выше, осталось просто перенести пример реализацию работы с классом на Delphi.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Похожий контент

    • От gutalin79
      Почему при добавлении MapView в пример Android Service, приложение перестает работать?
      AndroidSimpleService.zip
       
       
       
      Пример делал по этому видео: 
       
    • От Astghik
      Hello !!!
      I want onButtonClick create popup. I use TPopup component. All good, but on android "Back button" click closing forma. But I want close popup (when popup is shown).

       
      //---------------------------------------------------------------------------------
      void __fastcall  btn3PointsClick(TObject *Sender)
      {
          PopUpSettings->IsOpen = true;
          PopUpSettings->PlacementTarget = btn3Points;
          PopUpSettings->BringToFront();
      }
      //-------------------------------------------------------------------------------------
      void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose)
      {
          try {
              if (PopUpSettings->IsOpen == true) {
                  CanClose = false;
              }
              else {
                  CanClose = true;
              }
          } __finally {
              PopUpSettings->IsOpen = false;
          }
      }
      //-------------------------------------------------------------------
       
    • От Rokweb
      Таймер с интервалом 1мс заметно подтормаживает во время выполнения анимации TFloatAnimation в Tokyo. У всех так или только у меня?
    • От Rokweb
      Здравствуйте.
      Речь пойдёт об Android.
      Использовал в Berlin данный unit для проигрывания звуков (TMediaPlayer не подходит) и все отлично работало. Сейчас перешел на Tokyo и происходит зависание в цикле:
       
      while not GLoaded do begin Sleep(10); Application.ProcessMessages; end;  
      Модуль прикрепил в сообщении.
       
      Так же интересует - возможно ли, использовать стиль, созданный в процессе разработки Android приложения - в iOS и если да - то как это правильно реализовать (почти каждый контрол имеет сейчас свой стиль)?
       
      Прошу помощи.
      GameAudioManager.zip
    • От zekelive
      Товарищи, здравствуйте. Хотел бы проконсультироваться с вами на довольно сложно для меня тему. Имеется клиентское мобильное приложение на Андроид. Принцип его просто, загружает фирмы из БД в scrollbox. За счёт того, что сразу загрузка всех данных из сервера занимает длительное время, было принято решение загружать с сервера только ключевую информацию (название фирмы), а остальную информацию загружать из локальной БД. При этом, т.к. файл БД можно легко вытащить из apk файла любому человеку, размещать всю БД на локалке нельзя. Только информацию в целом не представляющую большой значимости в отдельности от названия фирмы и не только. 
      Вопрос, правильная ли схему построения была выбрана с точки зрения защиты данных (если это так можно назвать), и оптимизации загрузки информации. 
      Приветствуются ваши советы, как лучше построить схему взаимодействия приложения с БД, или как лучше защитить данные. В идеале для быстродействия, загнать побольше данных в локальную БД. 
    • От Edward Tarasov
      Привет всем. кто сталкивался с такой ерундой, что в webbrowser вместо сайта тупо белый экран?? причем сам сайт отображаеться норм, и на том же планшете, но в стандартном бразуере и на компе... и именно этот сайт не пашет из приложения
    • От zekelive
      Друзья, первый раз столкнулся с картами и не пойму в чем дело. Приложение подписано, релизная версия. Добавил карты на форму и запустил на компиляцию, все отлично. Запускаю на смартфоне - приложение сразу вылетает. Ничего не прописывал связанное с картами, просто добавил компонент на форму. Что не так ?
    • От Алексей Алексеев
      Здравствуйте! Помогите начинающему, всё перелазил, всё что мог и всё безрезультатно.
      Такая проблема: 
      Стоит задача убрать перенос строки в Memo:
      Из 
      "1строка"
      "2строка" 
      сделать:
      "1строка 2строка" .
      Казалось бы все просто:
      memo1.Text:=memo1.Text.Replace(#13#10,' '); И на Windows всё работает, но на Android отказывается!
      Просто не реагирует, ошибок не выдает. Проверял на XE8 и на 10.2.
      Может дело в смартфоне Xiomi miMax? Так как вообще memo на нём глючит...
    • От x11
      При попытке подключиться к базе данных SQLite на эмуляторе с Android  7 получаю исключение:
      Delphi Tokyo + UniDAC 7.
      Эмулятор какой-то неполноценный?
    • От gutalin79
      Доброго времени суток!
      Хотел у Вас спросить. Есть ли возможность сделать на Delphi под Android кнопку которая была бы доступна в режиме блокировки? То есть чтобы я мог её нажать и включить фонарик или ещё что-нибудь и при этом не пришлось разблокировать телефон. Заранее благодарю, за ответ!  

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу