Вызов элементов activity в подключаемом классе
Вызов элементов activity в подключаемом классе
В общем сделал машинку с управлением от акселерометра по Bluetooth. Все работает, но теперь хочу сделать также с управлением от кнопок. Я сделал второе активити и тут встал вопрос повторного использования кода для Bluetooth (создание соединения, передача данных и т.п.). Я решил все, что касается Bluetooth вынести в отдельный класс - файл. Но у меня там в коде используются Toast.makeText(), а также запрос на включение блютуза при его отсутствии: startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); И Eclipse ругается на эти строки
Если прописать public class Bluetooth extends Activity {... то Eclipse не ругается, но приложение крашиться. Да и как я понимаю это неправильно. Как тут быть? Почитал немного про intent думал туда может надо копать, но вроде не то.
Если прописать public class Bluetooth extends Activity {... то Eclipse не ругается, но приложение крашиться. Да и как я понимаю это неправильно. Как тут быть? Почитал немного про intent думал туда может надо копать, но вроде не то.
Re: Вызов элементов activity в подключаемом классе
Toast'y нужен будет контекст, так что просто в свой класс передавайте текущий контекст. startActivityForResult это метод который относится к классу Activity, соответственно оно и будет крешится потому что это велосипед, зачем вам возвращать что то из вашего простого класса? есть сеты и геты вот геты пускай и возвращают вам то что нужно.
Например:
MyBluetooth.isConnect() - возвращает текущее подключение true или false.
Например:
MyBluetooth.isConnect() - возвращает текущее подключение true или false.
R.id.team
Политика на форуме запрещена
Политика на форуме запрещена
Re: Вызов элементов activity в подключаемом классе
Я в принципе тоже так думал сделать, но в связи с тем, что плохо понимаю принципы ООП (прграммирую микроконтроллеры и PHP без ООП), то не могу понять как тогда реализовать вызов функций в подключаемом классе, из основного класса.
Т.е. можно ли так сделать: класс А - основной с активити, а класс Б - вспомогательный без активити с Bluetooth функциями. Из класса А я вызываю методы и функции класса Б. А вот можно ли мне из класса Б вызывать методы класса A? И как тогда import тоже прописывать в начале файла?
Еще раз сорри за мою тупизну, книгу Java раздел про ООП прочитал, половину не понял, видимо выросшим на бейсике и паскале в начале 90-х не суждено уже допетрить в полной мере принципы ООП мне условные и безусловные переходы как-то ближе
Т.е. можно ли так сделать: класс А - основной с активити, а класс Б - вспомогательный без активити с Bluetooth функциями. Из класса А я вызываю методы и функции класса Б. А вот можно ли мне из класса Б вызывать методы класса A? И как тогда import тоже прописывать в начале файла?
Еще раз сорри за мою тупизну, книгу Java раздел про ООП прочитал, половину не понял, видимо выросшим на бейсике и паскале в начале 90-х не суждено уже допетрить в полной мере принципы ООП мне условные и безусловные переходы как-то ближе
Re: Вызов элементов activity в подключаемом классе
вот так правильноИз класса А я вызываю методы и функции класса Б
можно, но это не правильно, а не правильно потому что архитектурно вы не правильно проектируете приложение. Язык так построен что есть активити и вокруг неё всё крутится, не может так что бы какой то класс крутил активностю. Но мне больше интересно какие методы вы собрались вызывать, если эти методы используют компоненты экрана то это сразу креш приложения, если же обычные переменные то в любом случае придётся их делать статическими, и опять таки зачем если эти все данные можно передать в ваш класс Б и там уже их юзать.А вот можно ли мне из класса Б вызывать методы класса A?
R.id.team
Политика на форуме запрещена
Политика на форуме запрещена
Re: Вызов элементов activity в подключаемом классе
Ну сам вызов возможен, через Броадкасты. У меня к примеру сервис может посылать моим активити броадкасты, чтоб они закрылись и вызвали активити логина.rezak90 писал(а):можно, но это не правильно, а не правильно потому что архитектурно вы не правильно проектируете приложение. Язык так построен что есть активити и вокруг неё всё крутится, не может так что бы какой то класс крутил активностю. Но мне больше интересно какие методы вы собрались вызывать, если эти методы используют компоненты экрана то это сразу креш приложения, если же обычные переменные то в любом случае придётся их делать статическими, и опять таки зачем если эти все данные можно передать в ваш класс Б и там уже их юзать.А вот можно ли мне из класса Б вызывать методы класса A?
Re: Вызов элементов activity в подключаемом классе
Ну с ООП полюбому нужно подружиться, если работаешь с JAVA без этого никуда.tolik777 писал(а):Я в принципе тоже так думал сделать, но в связи с тем, что плохо понимаю принципы ООП (прграммирую микроконтроллеры и PHP без ООП), то не могу понять как тогда реализовать вызов функций в подключаемом классе, из основного класса.
Т.е. можно ли так сделать: класс А - основной с активити, а класс Б - вспомогательный без активити с Bluetooth функциями. Из класса А я вызываю методы и функции класса Б. А вот можно ли мне из класса Б вызывать методы класса A? И как тогда import тоже прописывать в начале файла?
Еще раз сорри за мою тупизну, книгу Java раздел про ООП прочитал, половину не понял, видимо выросшим на бейсике и паскале в начале 90-х не суждено уже допетрить в полной мере принципы ООП мне условные и безусловные переходы как-то ближе
Тут не нужно, что-то выдумывать, все уже придумано до нас.
Если мы хотим в объекте класса Б созданном объектом класса A вызывать методы своего родителя (класса А), то здесь обычно поступают следующим образом.
1. Передают ссылку объекта класса A в класс Б и вызывают методы класса A через эту ссылку. Чаще всего это делают при создании класса Б т.е. передают ссылку прямо в конструктор класса Б. В объекте Б сохраняют ссылку на объект A во внутреннем поле и используют его по мере необходимости.
2. Делают класс Б встроенным в класс A тогда класс Б будет иметь доступ ко всем методам класса A, а также ко всем его полям. Но это не ваш случай т.к. класс Б у вас должен быть отдельным и использоваться для разных Activity.
Так что первый вариант вам больше всего подходит.
Добавьте в конструктор класса дополнительный параметр класса Activity и сохраняйте ссылку во внутреннем поле класса.
class MyBluetooth {
private Activity mActivity; //Поле в котором храним ссылку на родительское Activity
MyBluetooth (Activity activity){ //В конструкторе класса принимаем ссылку на объект родительского класса
mActivity = activity; //Сохраняем ссылку
}
}
В классе ваших Activity вы должны создавать объекты класса MyBluetooth следующим образом:
MyBluetooth myBluetooth = new MyBluetooth (this);
Теперь в классе MyBluetooth вы можете вызывать любые методы класса Activity
mActivity.methodActivity();
Но таким способом можно вызвать методы только определенные в классе Activity , а ваши Activity могут иметь еще собственные методы, которые не определены в классе Activity. В этом случае вам нужно будет приводить ссылку mActivity к типу вашей Activity
((MyActivity)mActivity).methodMyActivity();
Но здесь нужно быть осторожным т.к., если вы объект класса MyBluetooth создаете в разных Activity , то вызываемый метод должен быть определен во всех этих Activity иначе будет брошено исключение. Либо в коде MyBluetooth предусмотреть проверку к какому именно классу принадлежит ваша ссылка mActivity
if (mActivity instanceof MyActivity){
((MyActivity)mActivity).methodMyActivity();
}
тогда этот метод будет вызываться только, если класс объекта mActivity будет являться классом MyActivity
Еще что необходимо помнить, что если вы в разных Activity создаете объекты класса MyBluetooth то это будут разные объекты, у них будут свои поля со своими значениями. Если необходимо иметь что-то общее между этими объектами, то используются статические поля (помеченные ключевым словом static) эти поля будут общими для всех объектов MyBluetooth, еще говорят что они принадлежат не объектам класса, а самому классу. Они создаются один раз при первом вызове класса и гарантированно не уничтожаются, пока будет жив хотябы один объект этого класса.
Re: Вызов элементов activity в подключаемом классе
Начал делать так, чтобы с класса bluetooth все методы возвращали в основной активити переменные, и уже в активити их обрабатывать. С каждого метода мне нужно возвратить минимум 2 переменные: одну boolean и одну String. Погуглив нашел что можно определить класс и возвращать обьекты.
Набросал такой код. Часть кода активити:
Вот код файла Bluetooth.java:
Хочу сделать, чтобы мне в переменной err возвращалась ошибка и текст ошибки, но приложение крашится. Не пойму отчего.
Набросал такой код. Часть кода активити:
Код: Выделить всё
package com.example.bl_4wd;
import com.example.bl_4wd.Bluetooth;
import com.example.bl_4wd.R;
import android.os.Bundle;
....
....
class Error_Text {
public boolean eError;
public String eText_Error;
}
public class ActivityAccelerometer extends Activity implements SensorEventListener {
...
...
private Bluetooth bl;
....
....
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_accelerometer);
......
......
bl = new Bluetooth();
if(!bl.checkBTState().eError){
BluetoothAdapter.getDefaultAdapter();
//final int REQUEST_ENABLE_BT = 1;
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
else Toast.makeText(getBaseContext(), bl.checkBTState().eText_Error, Toast.LENGTH_SHORT).show();
}
Код: Выделить всё
package com.example.bl_4wd;
...
...
public class Bluetooth{
...
public Error_Text err = null;
...
Bluetooth(){
btAdapter = BluetoothAdapter.getDefaultAdapter();
Error_Text err = new Error_Text();
}
public Error_Text checkBTState() {
if(btAdapter==null) {
//errorExit("Fatal Error", "Bluetooth not support");
} else {
if (btAdapter.isEnabled()) {
Log.d(TAG, "...Bluetooth ON...");
//return true;
} else {
err.eError = false;
err.eText_Error = "Bluetooth не найден";
return err;
//return false;
}
}
return err;
}
}
Re: Вызов элементов activity в подключаемом классе
Судя по всему вы пытаетесь получить значение поля eText_Error которое не определено.
Дело в том, что по умолчанию (если явно не определить значение) полю примитивных типов (int, long, boolean и т.п.) присваиваются значения 0 или для boolean - false. Для всех других объектов присваивается значение null , а String не является примитивным типом в JAVA поэтому, если явно не присвоить ему значение, то его значение по умолчанию будет null.
Теперь смотрим в ваш код, там идет проверка btAdapter.isEnabled(), если проверка дает ошибку, то полю eText_Error присваивается значение "Bluetooth не найден", а если проверка прошла удачно, то какое значение получит eText_Error? Правильно, null. И при последующей попытке считать данные из этого поля будет брошено исключение.
Поэтому либо присвойте какой-нибудь значение этому полю в ветви
if (btAdapter.isEnabled()) {
Log.d(TAG, "...Bluetooth ON...");
//return true;
err.eText_Error = "Bluetooth найден";
либо в его определении присвойте ему значение с пустой строкой
class Error_Text {
public boolean eError;
public String eText_Error="";
}
Дело в том, что по умолчанию (если явно не определить значение) полю примитивных типов (int, long, boolean и т.п.) присваиваются значения 0 или для boolean - false. Для всех других объектов присваивается значение null , а String не является примитивным типом в JAVA поэтому, если явно не присвоить ему значение, то его значение по умолчанию будет null.
Теперь смотрим в ваш код, там идет проверка btAdapter.isEnabled(), если проверка дает ошибку, то полю eText_Error присваивается значение "Bluetooth не найден", а если проверка прошла удачно, то какое значение получит eText_Error? Правильно, null. И при последующей попытке считать данные из этого поля будет брошено исключение.
Поэтому либо присвойте какой-нибудь значение этому полю в ветви
if (btAdapter.isEnabled()) {
Log.d(TAG, "...Bluetooth ON...");
//return true;
err.eText_Error = "Bluetooth найден";
либо в его определении присвойте ему значение с пустой строкой
class Error_Text {
public boolean eError;
public String eText_Error="";
}
Re: Вызов элементов activity в подключаемом классе
Попробовал оба варианта, все равно крашится.
И еще настораживает вот что: Eclipse на строку Error_Text err = new Error_Text(); пишет варнинг, что переменная не используется нигде: The value of the local variable err is not used
Попробовал ее закомментировать, ничего не поменялось, все равно краш
И еще настораживает вот что: Eclipse на строку Error_Text err = new Error_Text(); пишет варнинг, что переменная не используется нигде: The value of the local variable err is not used
Попробовал ее закомментировать, ничего не поменялось, все равно краш
Re: Вызов элементов activity в подключаемом классе
Странно что так пишет, ведь вы возвращаете объект err (return err;) поэтому, вроде как, используете, может вы не во всех ветвях его возвращаете, то тогда бы выдало ошибку при компиляции.
Это может означать, только что объект err по какой-то причине оказался невидим внутри метода checkBTState()
Это может означать, только что объект err по какой-то причине оказался невидим внутри метода checkBTState()
Последний раз редактировалось AndreyI 13 ноя 2012, 12:14, всего редактировалось 2 раза.
Re: Вызов элементов activity в подключаемом классе
Попробуйте перенести Error_Text err = new Error_Text(); внутрь метода
public Error_Text checkBTState() {
...
}
public Error_Text checkBTState() {
...
}
Re: Вызов элементов activity в подключаемом классе
Вроде заработало! Спасибо! Буду разбираться дальше
Re: Вызов элементов activity в подключаемом классе
Понял в чем изначально была ваша ошибка, вы в конструкторе написали
Bluetooth(){
Error_Text err = new Error_Text();
}
Эта запись означает, что вы создаете новый объект err внутри конструктора, который умрет сразу же после выхода из конструктора, поэтому Eclipse и показывает что объект не используется, то что имена их совпадают это не означает, что вы хотите инициализировать поле класса с таким же именем.
вам нужно было записать так
Bluetooth(){
err = new Error_Text();
}
Тогда все было бы нормально.
ЗЫ Не зря хорошим тоном является явное (с помощью this) указание на поле объекта класса, тогда точно путаницы не возникнет.
this.err = new Error_Text();
Bluetooth(){
Error_Text err = new Error_Text();
}
Эта запись означает, что вы создаете новый объект err внутри конструктора, который умрет сразу же после выхода из конструктора, поэтому Eclipse и показывает что объект не используется, то что имена их совпадают это не означает, что вы хотите инициализировать поле класса с таким же именем.
вам нужно было записать так
Bluetooth(){
err = new Error_Text();
}
Тогда все было бы нормально.
ЗЫ Не зря хорошим тоном является явное (с помощью this) указание на поле объекта класса, тогда точно путаницы не возникнет.
this.err = new Error_Text();
Re: Вызов элементов activity в подключаемом классе
В общем решил делать через Handle. И напоролся на одну проблемку.
Итак кусок кода активити:
Во втором файле:
2 раза одно и тоже прописывать в двух файлах не хочется. А CASE почему то ругается когда хочу использовать константы из второго класса bluetooth, т.е. когда пишу bl.BL_INCORRECT_ADDRESS
Пока что заюзал if else, но по switch интересно все же почему...
Итак кусок кода активити:
Код: Выделить всё
@Override
public void onCreate(Bundle savedInstanceState) {
.....
bl = new Bluetooth(this, mHandler);
....
....
}
private final Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case BL_NOT_AVAILABLE:
Log.d(TAG, "Bluetooth is not available. Exit");
Toast.makeText(getBaseContext(), "Bluetooth is not available", Toast.LENGTH_SHORT).show();
finish();
int t1 = bl.BL_INCORRECT_ADDRESS; // Так все нормально
break;
case bl.BL_INCORRECT_ADDRESS: // А так ругается "case expressions must be constant expressions"
Log.d(TAG, "Incorrect Bluetooth address");
Toast.makeText(getBaseContext(), "Incorrect Bluetooth address", Toast.LENGTH_SHORT).show();
break;
}
};
};
Код: Выделить всё
public class Bluetooth{
public static final int BL_NOT_AVAILABLE = 1; // Статус для Handler
public static final int BL_INCORRECT_ADDRESS = 2;
.....
.....
Пока что заюзал if else, но по switch интересно все же почему...
Re: Вызов элементов activity в подключаемом классе
Используйте класс, а не экземпляр:tolik777 писал(а):А CASE почему то ругается когда хочу использовать константы из второго класса bluetooth, т.е. когда пишу bl.BL_INCORRECT_ADDRESS
Bluetooth.BL_INCORRECT_ADDRESS
Re: Вызов элементов activity в подключаемом классе
Спасибо! Понял!