Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Обмен данными между Activity (одна глобальная переменная)

Добрый день, товарищи.
Мой путь в андроиде только начинается, поэтому элементарные для Вас вещи кажутся непонятными для меня.

Есть три Activity. есть переменная int x = 5;
В первой Activity кнопка, по нажатию на которую снимается одна единица от переменной. x--;
Во второй Activity есть кнопка с возможностью увеличить эту переменную на единицу. x++;
В третьей Activity есть TextView который показывает чему равна переменная на данный момент.

Вопрос - как обмениваться этой переменной между окнами? Все стандартные уроки в интернете советуют использовать Интент для передачи информации в другой активити(вроде как, набираем в этом окне циферку 1, нажимаем кнопочку и вот она наша циферка в другом окне.). но перебрасывать их через Intent туда-сюда - вроде ерунда. вдруг у меня переменных будет 50? и нажимать кнопочку не надо, что б переходить в другое окно.

может существует возможность сделать эту переменную глобальной на все Activity? в одном окне изменил значение и оно изменилось для всех.
или какой-то метод, который группирует все переменные и сообщает их значения другим активити, и при переходе на новое окно - сразу видно результат?

Заранее благодарен.
Ответ:
Сообщение от madcat600
метод, который группирует все переменные
все верно есть такая тема, надо написать application
и хранить значение переменной там раз много активити
Вопрос: Хранение переменных

Доброго времени суток, уважаемые.

Имеется около сотни переменных (не больше) которые будут изменяться раз 10-20 в день. Многие из них зависят друг от друга, т.е. при изменении одной - меняются значения нескольких других.
Сейчас они хранятся просто в памяти которая выделяется при запуске приложения. Но хочется обезопасить себя на случай краша или от какой-то программы по очистке оперативной памяти. Как вообще хранить данные этих переменных?
Я создал БД и с SQLite записал часть переменных, которые изменяются раз в сутки (в порядке эксперимента и обучения, так как опыт программирования невелик). Но для записи пришлось создать отдельную кнопку.
А как вообще лучше сохранять всё? Может какой-то автосейв на каждые 15 минут можно сделать? Или запись в БД моих переменных это вообще фиговая идея и есть более правильные методы?
Ответ:
Сообщение от madcat600
Но хочется обезопасить себя на случай краша или от какой-то программы по очистке оперативной памяти
На счёт очистки памяти можете не волноваться. Это надо очень постараться чтоб потерять данные по этой причине.
Сообщение от madcat600
Как вообще хранить данные этих переменных?
В памяти и храните
Сообщение от madcat600
автосейв на каждые 15 минут
Сохранение делайте только когда данные поменялись.
Сообщение от madcat600
Или запись в БД моих переменных это вообще фиговая идея
Не фиговая. Но лично я бы поступил так:
1) Сделал бы отдельный класс внутри которого хранились бы все 30 переменных.
2) Сделал бы этот класс serializable
3) Когда нужно сохранить данные - просто писал бы экземпляр этого класса его в файл при помощи ObjectOutputStream (ну и читал соответственно при помощи ObjectInputStream)
Вопрос: Потоки. Доступ к переменным

Помогите с вопросом о видимости переменных. Я создал поток внутри класса Activity. Теперь не могу обратиться из потока к объявленым переменным во внешнем классе(Activity). Вот код:

Код Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
       public class MainActivity extends Activity {
 
 
       public boolean FORM_OPEN = false;
 
       protected void onStart() {
 
        FORM_OPEN = true;
        getMesFromServices threadMesClass = new getMesFromServices();
        threadMes = new Thread(threadMesClass);
        threadMes.start();
        
        super.onStart();
        
    }
 
        class getMesFromServices implements Runnable {
 
        @Override
        public void run() {
            
 
            if (FORM_OPEN) { // эту переменную поток не понимает. я присваиваю ей true перед вызовом потока, а в потоке она false
                           // тут код
            }
 
        }
    }
}
До этого я ссылался на правило что ВНУТРЕННИЙ КЛАСС ИМЕЕТ ДОСТУП К ПЕРЕМЕННЫМ ВНЕШНЕГО. но походу к потокам это не относится. Спасибо за помощь!
Ответ: Попробую! завтра отпишусь о результате. Спасибо Mikalai!

Добавлено через 20 часов 17 минут
Этот код сработал на ура. теперь поток видит переменные.
Код Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class MainActivity extends Activity implements Runnable {
 
 
public boolean FORM_OPEN = false;
 
protected void onStart() {
 
FORM_OPEN = true;
threadMes = new Thread(this);
threadMes.start();
 
super.onStart();
 
}
 
 
@Override
public void run() {
 
 
if (FORM_OPEN) { // эту переменную поток не понимает. я присваиваю ей true перед вызовом потока, а в потоке она false
// тут код
}
 
}
 
}
Еще раз спасибо Mikalai!
Вопрос: Где хранить переменные которые используются по всему проекту

Есть переменные :
a = 23;
b = "text";
c = "text2"
их я использую по всему проекту, к примеру переменную "а" я использую в 4х классах и в каждом 3 раза.
Когда нужно это значение поменять приходится искать эти классы и менять их все, это заставило задуматься нет ли способа захватить планету и построить коммунизм вынести эти переменные в отдельную структуру.
Первым на ум пришло создать класс и создать в нем поля с этими переменными.
Вторым создать singleton и унаследоваться от Application для создания единственного экземпляра, но не знаю с потоками он будет работать или нет.

Какие есть общее рекомендации для хранения таких данных?
Ответ: powowstal, 1 и 2 - нормальный вариант. будет работать с потоками. если переменные будете менять то нужно обеспечить неразрушающий доступ + в этом случае лучше наследник Application
Вопрос: Что обозначает синий цвет у переменной в отладчике

Ребят кто нибудь сталкивался с таким.
Ставлю точку остановки и вижу в дебагере переменную синего цвета.. что то мне подсказывает что с ней что то не то ))
Вот так выглядит
Или наоборот с ней все то... а с красными не то )
Хочется узнать, что означает окрас переменной.
Спасибо.

ЗЫ у гугла спрашивал )
Ответ:
Сообщение от asttoxa
ЗЫ у гугла спрашивал
ну если бы правильно спрашивали то нашли бы такой ответ на
в общем красный это стандартный цвет для переменной, а в синий окрашиваются те переменные, которые изменились в процессе "шагания" по коду.
Вопрос: Как в отдельном классе сохранять переменные?

Добрый день!

есть класс, в нем сотни переменных, их значения меняются.

как сохранять их значения и как вызывать из другого класса напр. MainActivity и т.п.?

т.е. понимаю что мне SharPrefs надо, но как вынести в другой класс и этим пользоваться не понимаю...
Ответ: Думаю здесь вам поможет SQLite
Класс для работы с бд.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
public class DataBaseHelper extends SQLiteOpenHelper {
 
    String DB_PATH = null;
    private static String DB_NAME = "DB_Tank_info16";
    private SQLiteDatabase myDataBase;
    private final Context myContext;
 
    public DataBaseHelper(Context context) {
        super(context, DB_NAME, null, 10);
        this.myContext = context;
        this.DB_PATH = "/data/data/" + context.getPackageName() + "/" + "databases/";
        Log.e("Path 1", DB_PATH);
 
 
    }
 
 
    public void createDataBase() throws IOException {
        boolean dbExist = checkDataBase();
        if (dbExist) {
        } else {
            this.getReadableDatabase();
            try {
                copyDataBase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }
    }
 
    private boolean checkDataBase() {
        SQLiteDatabase checkDB = null;
        try {
            String myPath = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
        } catch (SQLiteException e) {
        }
        if (checkDB != null) {
            checkDB.close();
        }
        return checkDB != null ? true : false;
    }
 
    private void copyDataBase() throws IOException {
        InputStream myInput = myContext.getAssets().open(DB_NAME);
        String outFileName = DB_PATH + DB_NAME;
        OutputStream myOutput = new FileOutputStream(outFileName);
        byte[] buffer = new byte[10];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }
        myOutput.flush();
        myOutput.close();
        myInput.close();
 
    }
 
    public void openDataBase() throws SQLException {
        String myPath = DB_PATH + DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
 
    }
 
    @Override
    public synchronized void close() {
        if (myDataBase != null)
            myDataBase.close();
        super.close();
    }
 
 
    @Override
    public void onCreate(SQLiteDatabase db) {
    }
 
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (newVersion > oldVersion)
            try {
                copyDataBase();
            } catch (IOException e) {
                e.printStackTrace();
 
            }
    }
 
    //Добавление данных
    public long setInsert(String table, String nullColumnHack, ContentValues values)
    {
        return myDataBase.insert(table, nullColumnHack, values);
    }
 
 
    public  Cursor rawQuery()
 
    {
        Cursor c = myDataBase.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
        return c;
    }
 
    //Удаление данных
    public  void delete(String table)
    {
        myDataBase.delete(table, null, null);
        myDataBase.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" + table + "'");
    }
    //Чтение данных
    public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
        return myDataBase.query(table, null, null, null, null, null, null);
    }
}

В MainActivity
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
DataBaseHelper myDbHelper;
 
myDbHelper = new DataBaseHelper(getBaseContext());
        try {
            myDbHelper.createDataBase();
        } catch (IOException ioe) {
            throw new Error("Unable to create database");
        }
        try {
            myDbHelper.openDataBase();
        } catch (SQLException sqle) {
            try {
                throw sqle;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
 
 
   ///Запись в бд (тут ваши переменные с класса)
                ContentValues contentValuesAll = new ContentValues();
                contentValuesAll.put("avg_damage_assisted", personaly_dannie.getStatistics().getAll().getAvg_damage_assisted());
                contentValuesAll.put("avg_damage_assisted_radio", personaly_dannie.getStatistics().getAll().getAvg_damage_assisted_radio());
             
 
                myDbHelper.delete("NicknameAll"); // очищаем таблицу
                myDbHelper.setInsert("NicknameAll", null, contentValuesAll); //Записываем данные

А так же чтения данных с бд
Java
1
2
3
4
5
 Cursor c = null;
        c = myDbHelper.query("NicknameAll", null, null, null, null, null, null);
        c.moveToFirst();
        setAvg_damage_assisted(c.getDouble(1));
        setAvg_damage_assisted_radio(c.getDouble(2));
Я бы на вашем месте реализовал так. При запуске приложения считывать данные с бд(если их еще нету), то указать нулевые значения. Все эти данные хранить в классе, который я указал вам выше. Чтоб не было необходимости вызывать все время БД для изменения данных. И при завершение работы приложения данные записывать в БД с того класса.
Вопрос: BroadcastReceiver + static переменная

Работая с бродкаст ресивером задался вопросом, как же он всё-таки работает?) Есть следующий код, который фиксирует состояние телефонного звонка, в первую очередь, входящего:

Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class CallReceiver extends BroadcastReceiver {
 
    private static String mLastState="Unknown last state";
    private String phoneState="Unknown phone state";
    private static boolean incomingCall=false;
 
 
    @Override
    public void onReceive(Context context, Intent intent) {
       phoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
        if(intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")){
            LOG.debug("Outgoing call");
        }else {
            LOG.debug("Incoming call"+" "+String.valueOf(incomingCall));
        if(!mLastState.equals(phoneState)){
         switch (phoneState){
            case("RINGING"):
                incomingCall=true;
                mLastState="RINGING";
                LOG.debug("RINGING");
                break;
            case("OFFHOOK"):
                if(incomingCall) {
                    mLastState = "OFFHOOK";
                    LOG.debug("OFFHOOK");
                }
                break;
            case("IDLE"):
                if(incomingCall){
                     mLastState="IDLE";                   
                     incomingCall=false;
                     LOG.debug("IDLE");
                }
                break;
          }
         }
        }
    }
}
Если абонент звонит, мы получаем следующие логи:

main: [Incoming call false]
main: [RINGING] - звонит телефон
main: [Incoming call true]
main: [OFFHOOK] - подняли трубку и разговаривают
main: [Incoming call true]
main: [IDLE] - завершили разговор
main: [Incoming call false]

И вот, что меня смутило это состояние статичной переменной incomingCall. Когда первый раз срабатывает бродкаст ([RINGING]) он все переменные инициализирует (incomingCall=false) и затем выполняется onReceive и мы получаем incomingCall=true. При втором срабатывании ([OFFHOOK]) он уже берёт из статичной переменной, а не инициализирует static поле (incomingCall=false); хотя между этими событиями может пройти время и дальше тоже самое происходит с третьим срабатыванием ([IDLE]).

Отсюда вопрос как происходит инициализация переменных при срабатывании броадкастресивера? Что будет со статичными переменными? Инициализирует ли броадкаст переменные каждый раз или срабатывает только метод onReceive?
Ответ: Delphian, SharedPreference можно смело использовать в BroadcastReceiver, он достаточно быстрый. А для действительно длительных операций можно и сервис завести.
Вопрос: Как объявить переменную в Андроид Студио?

Не кидайте тапками, если вопрос сильно глупый) Осваиваю Андроид Студио по урокам Александра Климова (), и такая загвоздка: требуется объявить переменную mInfoTextView по аналогии с другой переменной, объявленной ранее. Но не получается, Студия ее не находит и пишет: cannot resolve symbol "mInfoTextView".
Из урока:
Ранее мы объявили переменную helloTextView внутри метода onClick(), из которого она недоступна в других методах. Поэтому поступим с ней так же, как с кнопкой - объявим текстовую метку на уровне класса и инициализируем её в методе onCreate(). Сделайте это самостоятельно, создав переменную с именем mInfoTextView.
Первую переменную объявляли так:
public void onClick(View view){
TextView helloTextView = (TextView)findViewById(R.id.textView);
helloTextView.setText("Hello Kitty!");
}
Вторую я попыталась определить также:
public void onClick(View view) {
TextView helloTextView = (TextView)findViewById(R.id.textView);
helloTextView.setText("Hello Kitty!");
TextView mInfoTextView = (TextView)findViewById(R.id.textView);
mInfoTextView.setText("Я насчитал " + ++mCount + " ворон");

}
Но в обработчике щелчка кнопки mInfoTextView все равно красного цвета и выдает cannot resolve symbol "mInfoTextView". Обработчик выглядит так:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCrowsCounterButton = (Button)findViewById(R.id.buttonCrowsCounter);
mCrowsCounterButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mInfoTextView.setText("Я насчитал " + ++mCount + " ворон");
}
});
}
Что делать?
Ответ: Большое спасибо, все получилось)
Вопрос: Взять символы с EditText и прировнять их к переменным.Как это можно сделать?

Java(TM) 2 Platform Standard Edition 5.0
1
2
3
4
5
6
7
8
9
10
11
Кто знает как можно осуществить вот это.
Например: Есть поле editText 
__02.__08.__1994__
Как взять строку и разделит на символы.
т.е 0 прировнять к переменной А
2 прировнять к переменной B
0 прировнять к переменной C
8 прировнять к переменной A1
 
что бы потом все переменные сложить и получить результат?
Или только можно если для каждого символа создавать edit?
Ответ: Elias_smith,
Java(TM) 2 Platform Standard Edition 5.0
1
String result = data.replace("_","").replace (".","");
Вопрос: Время жизни переменной в Application

В Классе Application до какого времени живет переменная?

Наблюдаю следующее: создаю класс наследник Application, там есть переменная int i = -1, записываю туда данные (например 2).

Сворачиваю приложение, далее обратно к нему возвращаюсь и вижу что:

Случай 1: Все нормально, все данные в классе сохранились (активность жива, т.е. система ее не выгрузила (открывается тот фрагмент который был в момент сворачивания)) int i = 2;
Случай 2: После длительного "перерыва" возвращаюсь в приложение и вижу что в классе все данные обнулились, моя переменная int равна стандартному -1 (активность жива, т.е. система ее не выгрузила (открывается тот фрагмент который был в момент сворачивания))

Что такое? Чего я не знаю?))


p.s. класс наследник и переменная не static
Ответ: Добавить логи в онкриейт и онломемори, онконфигчейнж
и узнать причину надо