Форум программистов, компьютерный форум, киберфорум
Программирование Android
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 31

Написать программу, в которой основную работу производит сервис

07.01.2014, 00:29. Показов 2759. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.
Возникла задача написать программу в которой основную работу производит сервис. Также требуется Activity для настройки параметров сервиса.
Создал проект с Activity, тут же создал сервис (во всех методах заглушки). Работает.

Собственно не понятно куда писать код самого сервиса. Функция onStartCommand() сказано должна возвращать тип инт (для меня это START_STICKY, что бы ОС запускало сервис в случае сбоев или нехватки памяти). Код START_STICKY будет возвращен системе после отработки функции onStartCommand().
(1) То есть в этой функции нельзя писать длительно исполняющийся код?

(2) Тогда как поступить? У меня только одна идея, в onStartCommand() запустить второй поток и уже писать всё в нем (назовём его исполняющим). Правильно? Тогда как не создавать другие потоки (мне нужен один) при повторных запусках onStartCommand()?

(3) Если в исполняющем потоке надо работать с интернет, все вызовы опять надо заворачивать в AsyncTask?

(4) как тогда из Activity передать данные (настройки работы) в исполняющий поток? В сервис через Bind, а из сервиса в исполняющий поток через handle?

Мои размышления верные? Так и делают или есть более правильные подходы?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.01.2014, 00:29
Ответы с готовыми решениями:

Написать программу которая производит сортировку алгоритма
Написать программу которая производит сортировку алгоритма:сортировка пузырьком, сортировка перемешиванием, быстрая сортировка.

Написать основную программу main, которая
Написать основную программу main, которая а) в режиме диалога вводит исходные данные Х,  и N - номер функции, по которой следует...

Написать перегруженные функции и основную программу, которая их вызывает
Написать перегруженные функции и основную программу, которая их вызывает. а) для массива целых чисел находит количество нечетных...

13
194 / 154 / 23
Регистрация: 16.08.2013
Сообщений: 738
07.01.2014, 00:47
http://startandroid.ru/ru/urok... rimer.html
С этого урока и дальше.
0
Командир зеленых роботов
 Аватар для angryrobot
349 / 286 / 54
Регистрация: 08.10.2013
Сообщений: 576
07.01.2014, 10:43
Цитата Сообщение от bt1024 Посмотреть сообщение
(1) То есть в этой функции нельзя писать длительно исполняющийся код?
Нельзя, но если очень хочется писать именно там, то можно быстренько стартовать новый поток который сделает всю работу.
Цитата Сообщение от bt1024 Посмотреть сообщение
Тогда как поступить?
Можно сделать так как написали вы, или использовать класс IntentService:

Java
1
2
3
4
5
6
7
8
9
10
11
12
public class MySrv extends IntentService {
 
  public MySrv() {
      super("MyThreadName");
      setIntentRedelivery(true);
  }
 
  @Override
  protected void onHandleIntent(Intent intent) {
      System.out.println("Hello from " + Thread.currentThread());
  }
}
Теперь когда вы стартуете сервис при помощи startService, каждый раз вызывается метод onHandleIntent в который передается ваш интент. И при это код выполняется в одном и том же отдельном потоке (см лог):

01-07 10:35:07.615: I/System.out(17408): Hello from Thread[IntentService[MyThreadName],5,main]
01-07 10:35:07.735: I/System.out(17408): Hello from Thread[IntentService[MyThreadName],5,main]
01-07 10:35:07.845: I/System.out(17408): Hello from Thread[IntentService[MyThreadName],5,main]
01-07 10:35:07.975: I/System.out(17408): Hello from Thread[IntentService[MyThreadName],5,main]


(3) Если в исполняющем потоке надо работать с интернет, все вызовы опять надо заворачивать в AsyncTask?
Работать с интернетом можно в любом потоке кроме главного.

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

В сервис через Bind, а из сервиса в исполняющий поток через handle?
Если нужно передать данные из сервиса в активити я обычно использую Handler, но есть и другие варианты, например через вызов метода sendBroadcast() в сервисе. А в активити настроен бродкаст ресивер который ловит интенты отсылаемые сервисом.
0
0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 31
07.01.2014, 16:50  [ТС]
Спасибо, перевариваю инфу..

Добавлено через 15 минут
Цитата Сообщение от angryrobot Посмотреть сообщение
Нельзя, но если очень хочется писать именно там, то можно быстренько стартовать новый поток который сделает всю работу.
Стоп, а где ещё можно писать? Мне не важно где писать код сервиса, лишь бы он работал так как надо мне, а не так как задумали разрабы андроида (капец, сервис есть, а исполняющего потока нет).
Или то и был намек на IntentService?
0
194 / 154 / 23
Регистрация: 16.08.2013
Сообщений: 738
07.01.2014, 17:48
Прочтите внимательно уроки что я вам предложил, в них все расписано.
0
0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 31
08.01.2014, 02:00  [ТС]
Цитата Сообщение от korsaj Посмотреть сообщение
Прочтите внимательно уроки что я вам предложил, в них все расписано.
прочитаны они, всё равно остались вопросы, потому и создал тему. Примеры безусловно хороши, но они не ложатся на мою программу, а переложить на мою ситуацию сходу не вышло.

Мне надо создать приложение в меню которого можно настраивать параметры. Здесь же есть сервис, который эти параметры читает, а приложение сообщает сервису о изменении настроек. Сервис перечитывает параметры и работает дальше. Всё это пишется как одна программа, Active и отдельно сервис в котором есть BroadcastReceiver. Вся программа будет в классе сервиса в том числе переменные. BroadcastReceiver устанавливает переменную статуса соединения (wifi, mobile, none, etc) далее уже в другом потоке который будет создан скорее всего в OnCreate() надо работать со всем этим. Работа будет в виде, если есть связь, что-то делаем, юзайем инет. Когда всё сделали, надо как то этот поток остановить или приостановить. Из спячки этот поток надо выводить или если пришло нужное сообщение от BroadcastReceiver или пришло сообщение с сети (тут пока не ясно, от сервера, в общем случае от другого компа).
0
Командир зеленых роботов
 Аватар для angryrobot
349 / 286 / 54
Регистрация: 08.10.2013
Сообщений: 576
08.01.2014, 10:55
Цитата Сообщение от bt1024 Посмотреть сообщение
Стоп, а где ещё можно писать?
Если ваш сервис это часть вашего приложения (выполняется в том же процессе) то где угодно :-)
Вы можете создать внутри сервиса любой public метод и вызывать его откуда угодно. Нужно только получить ссылку на ваш сервис.
Цитата Сообщение от bt1024 Посмотреть сообщение
капец, сервис есть, а исполняющего потока нет
Когда я начинал изучать андроид мне тоже показалось это дикостью, но об этом нюансе несколько раз упоминается в гугловской документации.
0
0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 31
08.01.2014, 13:22  [ТС]
Написал BroadcastReceiver что бы получать сообщения о подключениях. Было куча ошибок пока не вывел класс в отдельный файл. Если встраиваю этот класс в класс сервиса, андроид не может найти класс ресивера, он почему то ищет именно файл. Пытался подставить в манифесте путь
XML
1
2
3
4
5
6
<receiver android:name=".FService.ConnectivityReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
            </intent-filter>
        </receiver>
где FService это класс сервиса, ConnectivityReceiver - внутрений класс реализующий приемник.
Андроид ругается, всё равно ищет файл ConnectivityReceiver.java. Как эту проблему преодолеть? Мне желательно сделать его внутренним.

Добавлено через 7 минут
Цитата Сообщение от angryrobot Посмотреть сообщение
Если ваш сервис это часть вашего приложения (выполняется в том же процессе) то где угодно :-)
Вы можете создать внутри сервиса любой public метод и вызывать его откуда угодно. Нужно только получить ссылку на ваш сервис.
А как ссылку получить? Через package и имя класса?

Когда я начинал изучать андроид мне тоже показалось это дикостью, но об этом нюансе несколько раз упоминается в гугловской документации.
Тут можно много ругать их за это, типа видели кривость но всё равно сделали. Почему мне пока не ясно, но истинные причины их философии пока не важны, ибо работать надо
0
Командир зеленых роботов
 Аватар для angryrobot
349 / 286 / 54
Регистрация: 08.10.2013
Сообщений: 576
08.01.2014, 13:41
Цитата Сообщение от bt1024 Посмотреть сообщение
Как эту проблему преодолеть? Мне желательно сделать его внутренним.
Как-то вот так примерно:
Java
1
2
3
4
5
6
7
8
9
10
      BroadcastReceiver br = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //Ваш код здесь
        }
      };
      IntentFilter intFilter = new IntentFilter();
      intFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
      intFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
      registerReceiver(br, intFilter);
Цитата Сообщение от bt1024 Посмотреть сообщение
А как ссылку получить?
Есть несколько способов, гугловская документация рекомендует делать это так (первые два куска кода в статье). Или можно сделать по-деревенски: в сервисе объявить статическое поле и в момент создания сервиса писать туда this. А потом откуда угодно обращаться к нему.
0
0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 31
08.01.2014, 14:38  [ТС]
Цитата Сообщение от angryrobot Посмотреть сообщение
Как-то вот так примерно:
Да пробовал так вчера,

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
NetStateReceiver = new BroadcastReceiver(){
    @Override
    public void onReceive(Context context, Intent intent )
    {
        NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
        if(null != info){
        String stateString = info.toString().replace(',', '\n');
        Toast toast = Toast.makeText(context, stateString, Toast.LENGTH_LONG);
        toast.setGravity(Gravity.CENTER, 0, 0); 
        toast.show();
    }
    }
};
IntentFilter intFilter = new IntentFilter();
intFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
intFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
registerReceiver(NetStateReceiver, intFilter);
Не пойму имя чего регистрировать в манифесте в этом случае? Ругается на всё.
Added: Оказывается ничего не надо . Заработало!
0
194 / 154 / 23
Регистрация: 16.08.2013
Сообщений: 738
08.01.2014, 17:30
Ничего вы не читали! Все в указанных мною уроках подробно описано.
0
0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 31
09.01.2014, 21:12  [ТС]
Есть метод onReceive BroadcastReceiver-а, в нем я хочу запустить поток.
Написал отдельный Runnable класс.., вообщем для примера:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public WorkTask task; // Runnable class
public Thread r;
 
В 
onCreate(..){
    task = new WorkTask();
    r = new Thread(task);
}
 
@Override
public void onReceive(Context context, Intent intent ){
...
    r.start();
...
}
Получаю ошибку java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.wifi.WIFI_STATE_CHANGED flg=0x10000010 (has extras) } in com.site.app.FService$1@415dd540
Почему я получаю такую ошибку? Специально сделал отдельный поток, с onReceive() это ни как не связано. Переделал с Handle, тоже самое.
0
67 / 43 / 5
Регистрация: 24.08.2013
Сообщений: 678
09.01.2014, 23:12
Цитата Сообщение от bt1024 Посмотреть сообщение
Получаю ошибку java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.wifi.WIFI_STATE_CHANGED flg=0x10000010 (has extras) } in com.site.app.FService$1@415dd540
Почему я получаю такую ошибку? Специально сделал отдельный поток, с onReceive() это ни как не связано. Переделал с Handle, тоже самое.
Может потому, что должно быть не "android.net.wifi.STATE_CHANGED", а "android.net.wifi.STATE_CHANGE"?
0
0 / 0 / 0
Регистрация: 22.10.2012
Сообщений: 31
10.01.2014, 14:26  [ТС]
Цитата Сообщение от Slon747 Посмотреть сообщение
Может потому, что должно быть не "android.net.wifi.STATE_CHANGED", а "android.net.wifi.STATE_CHANGE"?
Андроид ругается на эту константу.
Если убрать запуск потока то всё работает как задумано. Но вот с запуском проблемы.

Ошибка исчезает если запуск задачи выполняется в отдельном потоке (не так как я в начале это делал)
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
public void StartWorkThread()
{
    if(ThreadWorking == false){
        ThreadWorking = true;
        new Thread(new Runnable(){
        public void run(){
            task = new WorkTask();
            task.run();
            }
        }).start();
    }else{
        counter++;
        ShowToast(Integer.toString(counter));
    }
}
 
public void run(){
    ShowToast("А я работаю! :)");
    while(isConnected != NET_NONE){
        GetSettings();
        try {
        TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e){
            e.printStackTrace();
        }
    }
    ThreadWorking = false;
    ShowToast("Поток завершен :(");
}
ShowToast() метод который вызывает метод из главного приложения проверяя Bind между сервисом и приложением.
Всё равно получаю ошибку, но другую..
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

Добавлено через 14 минут
вроде разобрался

Добавлено через 12 часов 31 минуту
Долго ли коротко..)) в общем "скелет" написан, заработал как я и хотел и всё написанное "мяско" к нему тоже, всем спасибо за помощь!!! Рутина закончилась (наивный да?), самое интересное и сладкое впереди, писать саму функциональность
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.01.2014, 14:26
Помогаю со студенческими работами здесь

Написать перегруженные функции и основную программу, которая их вызывает.В С++
Задание: а) для вычитания десятичных дробей; б) для вычитания обыкновенных дробей.

Написать перегруженные функции и основную программу, которая их вызывает
Написать перегруженные функции и основную программу, которая их вызывает. а)для сложения вещественных чисел; б) для сложения...

Написать перегруженные функции и основную программу, которая их вызывает
Написать перегруженные функции и основную программу, которая их вызывает. а) для сложения вещественных чисел; б) для сложения...

Написать программу, которые производит подсчет суммы элементов вектора, больших числа 7
с помощью средств программирования в mathcad написать программу, которые производит подсчет суммы элементов вектора, больших числа 7

написать основную программу int main , для проверки методов класса
Напишите основную программу типо строчка и там метод какой нить поиск например из класса #include &lt;iostream&gt; #include...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru