Сохранение данных из BroadcastReceiver. Очередной баг?

SQLite, Preferences, файлы, SD, Content Provider, XML, JSON
Tamachi
Сообщения: 203
Зарегистрирован: 17 апр 2013, 00:08

Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение Tamachi » 02 ноя 2013, 20:56

Вот класс:

Код: Выделить всё

package ru.tamachi.pacer;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import android.widget.Toast;

public class IncommingCommandDBHelper extends SQLiteOpenHelper {
	
	final static String INCOMMING_COMMAND_DB_NAME = "incommingcommand";
	final static String INCOMMING_COMMAND_BODY_COLUMN_NAME = "cmdbody";
	final static String INCOMMING_COMMAND_TIME_COLUMN_NAME = "cmdtime";
	final static String INCOMMING_COMMAND_ANSWER_TO_PHONE_COLUMN_NAME = "cmdanswertophone";
	final static String INCOMMING_COMMAND_ID_COLUMN_NAME   = "_id";	
	
	private SQLiteDatabase m_readableDB = null;
	
	public IncommingCommandDBHelper(Context context) {
		super(context, INCOMMING_COMMAND_DB_NAME, null, 1);  
        if (!(m_readableDB==null)) {
            m_readableDB.close();
        }
		m_readableDB = getReadableDatabase(); 
		System.gc();		
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL("create table " + INCOMMING_COMMAND_DB_NAME + " ( " + INCOMMING_COMMAND_ID_COLUMN_NAME
				+ " integer primary key autoincrement, " 
				+ INCOMMING_COMMAND_TIME_COLUMN_NAME + " integer, " 
				+ INCOMMING_COMMAND_BODY_COLUMN_NAME + " text, " 
				+ INCOMMING_COMMAND_ANSWER_TO_PHONE_COLUMN_NAME + " text);");
	}
	
	public long add(final String cmdBody, final String answerToPhone) {
		if (commandExists(cmdBody, answerToPhone)) {
			return -1;
		}
		long result = -1;
		try {
			SQLiteDatabase db = getWritableDatabase(); 
		    ContentValues contentValues = new ContentValues();
		  	    contentValues.put(INCOMMING_COMMAND_BODY_COLUMN_NAME, cmdBody); 
		  	    contentValues.put(INCOMMING_COMMAND_TIME_COLUMN_NAME, System.currentTimeMillis()); 
		  	    contentValues.put(INCOMMING_COMMAND_ANSWER_TO_PHONE_COLUMN_NAME, answerToPhone); 
			    result = db.insert(INCOMMING_COMMAND_DB_NAME, null, contentValues);
			db.close();
			
		} catch(Exception e) {
		
		}	
		return result;
	}
	
	public Boolean commandExists(String cmdBody, String answerToPhone) {
		String where ="("+INCOMMING_COMMAND_BODY_COLUMN_NAME+"=?) and ("+INCOMMING_COMMAND_ANSWER_TO_PHONE_COLUMN_NAME+"=?)";
		Cursor cursor = m_readableDB.query(INCOMMING_COMMAND_DB_NAME, null, where, new String[] { cmdBody, answerToPhone }, null, null, null);
		if (cursor==null) {
			return false;
		} else {
		  Boolean result = cursor.moveToFirst();
		  cursor.close();
		  return result;	
		}
	}
	
	public Cursor getCursor() {
		String orderby = INCOMMING_COMMAND_TIME_COLUMN_NAME+" asc";
		Cursor cursor = null;
		try {
			cursor = m_readableDB.query(INCOMMING_COMMAND_DB_NAME, null, null, null, null, null, orderby);
		} catch (Exception e) {
			cursor = null;
		}
		return cursor;
	}	
	
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
		
	}
}


Вот обращение к этому классу из BroadcastReceiver:

Код: Выделить всё

	
         private static void storeSomething(final Context context, final String phoneNumber, final String body) {
		if (!(m_dbHelper==null)) {
			m_dbHelper = new IncommingCommandDBHelper(context);
		}
		Toast.makeText(context, "DEBUG POINT A", 6000).show();
    	        m_dbHelper.add(body, phoneNumber);
    	        Toast.makeText(context, "DEBUG POINT B", 6000).show();
	}

Однако практика показывает, что приложение падает при выполнении лексемы
m_dbHelper.add(body, phoneNumber);

Сообщение "DEBUG POINT A" отображается, но сообщение "DEBUG POINT B" не отображается.

У же неделю пытаюсь найти причину!

Подскажите, кто знает, в чём фишка?

Очередной баг или я что-то не так делаю.

Аватара пользователя
trew
Сообщения: 450
Зарегистрирован: 28 сен 2013, 17:34

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение trew » 02 ноя 2013, 21:10

m_dbHelper.add(body, phoneNumber);
Выведи в Log значение переменных body и phoneNumber.

Если значения есть, добавляй логирование в public long add и по цепочке в остальные методы.
Когда выкладываете код на форум - код оформляйте. Редактор - поищите слова Geshi Syntax -Java. (или xml)
Свои сообщения можно редактировать - кнопка edit.

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение neoksi » 02 ноя 2013, 23:22

1) Ну как бы напрямую работать с БД - это плохой тон. Нужно все делать через ContentProvider или на худой случай через синглтон.
2) Время жизни и выполнения BroadcastReciver ограничено и большие по длительности операции, в нем выполнять не рекомендуется.

Посоветовать могу в лог вывести Exception из метода аdd, чтоб понять что происходит именно сейчас.

П.С. Но архитектурный подход вам нужно менять в корне.

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение Foenix » 02 ноя 2013, 23:33

Как можно неделю искать причину, если она написана в логе? там даже строчка с ошибкой указана. И при этом гадать..?
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Tamachi
Сообщения: 203
Зарегистрирован: 17 апр 2013, 00:08

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение Tamachi » 03 ноя 2013, 09:12

neoksi писал(а):1) Ну как бы напрямую работать с БД - это плохой тон. Нужно все делать через ContentProvider или на худой случай через синглтон.
2) Время жизни и выполнения BroadcastReciver ограничено и большие по длительности операции, в нем выполнять не рекомендуется.

Посоветовать могу в лог вывести Exception из метода аdd, чтоб понять что происходит именно сейчас.

П.С. Но архитектурный подход вам нужно менять в корне.
После официального обновления прошивок двух телефонов (LG705 и FLYIQ505) в них перестали писаться логи.

То есть если я в коде напишу Log.d("MyTag", "MyComment") --- в лог ничего записано не будет!

А на смартфоне FLY404 возможность записи в лог была с самого начала отключена!

Tamachi
Сообщения: 203
Зарегистрирован: 17 апр 2013, 00:08

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение Tamachi » 03 ноя 2013, 09:14

neoksi писал(а):1) Ну как бы напрямую работать с БД - это плохой тон. Нужно все делать через ContentProvider или на худой случай через синглтон.
2) Время жизни и выполнения BroadcastReciver ограничено и большие по длительности операции, в нем выполнять не рекомендуется.

Посоветовать могу в лог вывести Exception из метода аdd, чтоб понять что происходит именно сейчас.

П.С. Но архитектурный подход вам нужно менять в корне.

ContentProvider нужен только для того чтобы стучаться к базе из разных приложений.
А если этого не требуется, то рекоммендуется DBHelper. Собственно я и делаю как рекоммендуется!


Кстати, Синглтон тоже считается плохим тоном для андроид. Реализация синглтона в андроид чревата утечками памяти, курсора и пр... В ОС андроид временем жизни приложения (или его части) управляет не программист, а операционная система. Поэтому синглтон для андроид -- это не просто скверный тон: это верная смерть всего приложения!

Tamachi
Сообщения: 203
Зарегистрирован: 17 апр 2013, 00:08

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение Tamachi » 03 ноя 2013, 09:23

Foenix писал(а):Как можно неделю искать причину, если она написана в логе? там даже строчка с ошибкой указана. И при этом гадать..?
Я ж говорю: после официпльного обновления прошивок телефонов ведение логов стало невозможным.

Кстати, причину я нашел: она оказалась в манифесте.

Вот почему структура файла манифеста так плохо докумментировна!!!

Аватара пользователя
trew
Сообщения: 450
Зарегистрирован: 28 сен 2013, 17:34

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение trew » 03 ноя 2013, 10:35

Tamachi писал(а):Вот почему структура файла манифеста так плохо докумментировна!!!
что там не написано?
http://developer.android.com/guide/topi ... intro.html
Когда выкладываете код на форум - код оформляйте. Редактор - поищите слова Geshi Syntax -Java. (или xml)
Свои сообщения можно редактировать - кнопка edit.

Tamachi
Сообщения: 203
Зарегистрирован: 17 апр 2013, 00:08

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение Tamachi » 03 ноя 2013, 12:12

trew писал(а):
Tamachi писал(а):Вот почему структура файла манифеста так плохо докумментировна!!!
что там не написано?
http://developer.android.com/guide/topi ... intro.html

Вот сейчас обнаружил, следующее:

Если изнутри BroadcastReceiver сделать startService (запустить службу),
то поток BroadcastReceiver не завершится до тех пор пока не завершится служба.

У меня BroadcastReceiver делает только одно действие: запускает службу!
По идее он (receiver) должен после этого сразу завершаться!
Но практика показывает, что это не так!
Подскажите, куда рыть?

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение neoksi » 03 ноя 2013, 17:49

Tamachi писал(а):...

ContentProvider нужен только для того чтобы стучаться к базе из разных приложений.
А если этого не требуется, то рекоммендуется DBHelper. Собственно я и делаю как рекоммендуется!
Ты не забыл, что SQLite однопоточная БД и очередью запросов должен управлять сам программист? Если у тебя произойдет одновременное открытие нескольких копий DBHelper одной базы в разных частях приложения, то это черевато вылетами и ошибками записи в БД, чтоб не мучаться с реализацией очереди, CP используется не только для передачи инфы между приложениями, но и внутри одного приложения, в манифесте просто запрещаем экспорт. Так что теорию ты понял не очень верно.
Tamachi писал(а): Кстати, Синглтон тоже считается плохим тоном для андроид. Реализация синглтона в андроид чревата утечками памяти, курсора и пр... В ОС андроид временем жизни приложения (или его части) управляет не программист, а операционная система. Поэтому синглтон для андроид -- это не просто скверный тон: это верная смерть всего приложения!
Неверная реализация синглтона, да. Но ты опять же забываешь теорию, когда на данные все ссылки убиты, то они удаляются GC из памяти.

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение Foenix » 03 ноя 2013, 21:08

Tamachi писал(а): Кстати, Синглтон тоже считается плохим тоном для андроид. Реализация синглтона в андроид чревата утечками памяти, курсора и пр... В ОС андроид временем жизни приложения (или его части) управляет не программист, а операционная система. Поэтому синглтон для андроид -- это не просто скверный тон: это верная смерть всего приложения!
В синглтоне, действительно, не рекомендуют хранить данные. Данные. Т.к. при определенных обстоятельсвах объект может быть удален из памяти. Но при реализации там хранится только ссылка на экземпляр хэлпера, в случае чего он сам пересоздатся, так что это можно сказать одно из идеалных использований синглтона.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Tamachi
Сообщения: 203
Зарегистрирован: 17 апр 2013, 00:08

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение Tamachi » 04 ноя 2013, 11:15

Foenix писал(а):
Tamachi писал(а): Кстати, Синглтон тоже считается плохим тоном для андроид. Реализация синглтона в андроид чревата утечками памяти, курсора и пр... В ОС андроид временем жизни приложения (или его части) управляет не программист, а операционная система. Поэтому синглтон для андроид -- это не просто скверный тон: это верная смерть всего приложения!
В синглтоне, действительно, не рекомендуют хранить данные. Данные. Т.к. при определенных обстоятельсвах объект может быть удален из памяти. Но при реализации там хранится только ссылка на экземпляр хэлпера, в случае чего он сам пересоздатся, так что это можно сказать одно из идеалных использований синглтона.
Вы не учитываете того, что объект может потребоваться одновременно и в Activity и в BroadcastReceiver. И тогда будут сразу две копии объекта Вашего синглтона!

Шаблоны С++ в андроиде плохо работают!

Tamachi
Сообщения: 203
Зарегистрирован: 17 апр 2013, 00:08

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение Tamachi » 04 ноя 2013, 11:35

При правильной организации DBHelper проблем с двойным открытием можно легко избежать.

ContentProvider -- слишком тяжеловесное решение. Да, гугль его рекоммендует, но исключительно для того, чтобы с его помощью формализовать данные пользователей для своих поисковых целей (как-никак гугль это поисковая система и его интересы не всегда совпадают с интересами программиста)

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение rezak90 » 04 ноя 2013, 12:29

Tamachi писал(а):При правильной организации DBHelper проблем с двойным открытием можно легко избежать.

ContentProvider -- слишком тяжеловесное решение. Да, гугль его рекоммендует, но исключительно для того, чтобы с его помощью формализовать данные пользователей для своих поисковых целей (как-никак гугль это поисковая система и его интересы не всегда совпадают с интересами программиста)
ContentProvider выгоден тем что система руководит открытием и закрытием бд, в таком случае у вас не будет ошибок и колизий.
R.id.team
Политика на форуме запрещена

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение Foenix » 04 ноя 2013, 13:26

Tamachi писал(а):При правильной организации DBHelper проблем с двойным открытием можно легко избежать.

ContentProvider -- слишком тяжеловесное решение. Да, гугль его рекоммендует, но исключительно для того, чтобы с его помощью формализовать данные пользователей для своих поисковых целей (как-никак гугль это поисковая система и его интересы не всегда совпадают с интересами программиста)
ну откройте тайну, что значит "правильная организация DBHelper"

Иначе, если при использовании BroadcastReceiver синглтон не подходит, единственный выход - использовать C.P., ничего там "тяжеловестного" как выяснилось, нет.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение neoksi » 05 ноя 2013, 11:59

Да ладно, давайте дадим человеку набить свои шишки и потом переписать тонну кода =).

Если серьезно брать, все мы изначально невзлюбили CP, но каждый своими путями пришел к тому, что все равно пишет через CP.

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение rezak90 » 05 ноя 2013, 12:01

neoksi писал(а):Если серьезно брать, все мы изначально невзлюбили CP, но каждый своими путями пришел к тому, что все равно пишет через CP.
Я и до сех пор не люблю СР. Но увы, люди убедили использовать его.
R.id.team
Политика на форуме запрещена

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение neoksi » 05 ноя 2013, 12:10

rezak90 писал(а):
neoksi писал(а):Если серьезно брать, все мы изначально невзлюбили CP, но каждый своими путями пришел к тому, что все равно пишет через CP.
Я и до сех пор не люблю СР. Но увы, люди убедили использовать его.
Ну ты любишь ORMLite =)

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение Foenix » 05 ноя 2013, 12:16

Я к нему две недели привыкала :-D
Зато теперь когда знаешь как, то просто реализовываешь и все.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Сохранение данных из BroadcastReceiver. Очередной баг?

Сообщение rezak90 » 05 ноя 2013, 12:24

neoksi писал(а):Ну ты любишь ORMLite =)
я его любил только за удобство, я вообще обёртки и либы не люблю, потому что в них трудно найти ошибку, когда сам пишешь свой велосипед то и найти ошибку проще
R.id.team
Политика на форуме запрещена

Ответить