Страницы

Поиск по вопросам

Показаны сообщения с ярлыком service. Показать все сообщения
Показаны сообщения с ярлыком service. Показать все сообщения

суббота, 11 апреля 2020 г.

Сервис не стартует, выдавая ошибку 1053

#cpp #visual_studio #service #visual_studio_2013 #windows_service

                    
Собираю сервис с использованием с++. За основу брал условно-рабочий example, попытки
запустить сервис проводил на нем.
Запускаю код на своей машинее в дебаге/релизе/как обычное приложение/как сервис -
все работает. При попытке запустить данное творение на другой машине как обычное приложение
комп просто не выдает никакого окна. 

В принципе, как понимаю, сервисы и не обязаны отрабатывать как обычные приложения,
поэтому пытаюсь его установить как сервис.(в ком строке от имени админа sc create SERVICENAME
binpath= C:/[---].exe) Устанавливается. Новый процесс появляется в списке сервисов,
при попытке его стартануть (sc start SERVICENAME) комп вежливо отвечает, что 


  the service did not respond to the start or control request in a timely fashion


т е запуск сервиса не модет быть произведен т к сервис не отвечает. 
Как можно с этим справиться?

P.S. вот здесь сырцы полностью.
далее - исходный код самого сервиса

// SimpleService.cpp : Implementation of WinMain

#include "stdafx.h"
#include "resource.h"
#include "SimpleService.h"

class CSimpleServiceModule : public CAtlServiceModuleT< CSimpleServiceModule, IDS_SERVICENAME >
{
public :
    DECLARE_REGISTRY_APPID_RESOURCEID(IDR_SIMPLESERVICE, "{01D73C58-D8F4-4A85-B27D-424443739977}")
    HRESULT InitializeSecurity() throw()
    {
        return S_OK;
    }

    HRESULT PreMessageLoop (int nShowCmd);
    void RunMessageLoop (void) throw();
    void OnContinue (void) throw();
    void OnPause (void) throw();
    void OnShutdown (void) throw();
    void OnStop (void) throw();
};

HRESULT CSimpleServiceModule::PreMessageLoop (int nShowCmd) throw()
{
    return CAtlServiceModuleT< CSimpleServiceModule, IDS_SERVICENAME >::PreMessageLoop
(nShowCmd);
}

void CSimpleServiceModule::RunMessageLoop () throw()
{
    CAtlServiceModuleT< CSimpleServiceModule, IDS_SERVICENAME >::RunMessageLoop ();
}

void CSimpleServiceModule::OnContinue () throw()
{
    CAtlServiceModuleT< CSimpleServiceModule, IDS_SERVICENAME >::OnContinue ();
}

void CSimpleServiceModule::OnPause () throw()
{
    CAtlServiceModuleT< CSimpleServiceModule, IDS_SERVICENAME >::OnPause ();
}

void CSimpleServiceModule::OnShutdown () throw()
{
    OnStop ();
}

void CSimpleServiceModule::OnStop () throw()
{
    CAtlServiceModuleT< CSimpleServiceModule, IDS_SERVICENAME >::OnStop ();
}

CSimpleServiceModule _AtlModule;


//
extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, 
                                LPTSTR /*lpCmdLine*/, int nShowCmd)
{
    return _AtlModule.WinMain(nShowCmd);
}

    


Ответы

Ответ 1



Скорее всего у вас на второй машине не установлены рантаймы для C++. Если регистрировать сервис, как сказано в той статье через: SimpleService.exe -service То вы увидите соответствующую ошибку о том, что нет необходимых библиотек.

четверг, 9 апреля 2020 г.

Как добавить сервисы Google в Android Studio, чтобы уменшить размер

#android #service

                    
Ребята хочу добавить AdMob, но не используя

compile 'com.google.android.gms:play-services:7.0.0'
Так  как из за этой команды вес приложение возрастает в 5 раз.
До этого весил 700кб, сейчас 5 мегабайт, Это слишком! Есть ли выход? Читал что какой
то можно ProGuard задействовать или в Gradle указать чисто для AdMob

Gradle

apply plugin: 'com.android.application'


    android {
    compileSdkVersion 23
    buildToolsVersion '23.0.1'
    defaultConfig {
        applicationId "com.eranewgames.animevideo"
        minSdkVersion 10
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    productFlavors {
    }
}

repositories{
    flatDir{
        dirs 'libs'
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.mcxiaoke.volley:library:1.0.+'
    compile 'cz.msebera.android:httpclient:4.4.1.1'
    compile 'com.android.support:appcompat-v7:23.0.1'
}

    


Ответы

Ответ 1



Можно подключить отдельно только необходимую часть, полный список тут: https://developers.google.com/android/guides/setup Для AdMob достаточно com.google.android.gms:play-services-ads:8.1.0

Ответ 2



Обычно, перед созданием проекта в Android Studio, Вам должны предложить компоненты которые Вы хотите использовать в проекте. Начиная Play Games API, заканчивая Google Cast API. Попробуйте создать новый проект и вставить туда тот же код, но уже с выбранными компонентами.

Как и где в Android Studio посмотреть количество запущенных services у приложения?

#android #android_studio #service

                    
Раньше эклипс я помню показывал какие и сколько сервисов у приложения запущено, а
в AndroidStudio как посмотреть?
    


Ответы

Ответ 1



Tools -> Android -> Monitor Там отображаются процессы. Там же отображаются и сервисы.

Как обновить service не перезапуская его?

#java #android #service #android_service

                    
Возможно ли такое, чтобы запускать сервис при запуске приложения, а затем после каких-либо
операций на UI обновлять сервис без его перезапуска (т.е. сервис работает с начальными
данными, затем пользователь что-то делает, данные передаются в сервис и он начинает
работать уже с новыми данными, не делая при этом stopService(), startService) ?
    


Ответы

Ответ 1



Да, можно. При первом запуске сервиса вызывается его метод onCreate. При каждом последующем вызове Context#startServise(Context ctx, Intent intent), при условии, что сервис уже запущен, вызовется его метод onStartCommand. Таким образом по умолчанию вы получаете нужное вам поведение и не сервис не перезапускается каждый раз при вызове startServise, а вызываете метод ранее созданного экземпляра класса. При этом вы можете через содержимое интента передавать к-л данные, обновляя содержимое полей класса сервиса. Также есть ещё механизм биндинга сервиса к активити, позволяющего в активити получить ссылку на экземпляр запущенного сервиса и напрямую вызывать методы его экземпляра примерно так: instanceOfServiceClass.someMethodInServiceClass(someArgument);. Загуглить можно по Android service Binder. Вот статья на русском: Service. Биндинг. ServiceConnection

вторник, 31 марта 2020 г.

Как убить IntentService

#java #android #service #android_service


Для примера я создал сервис с таймером. Туда передаю какие-то параметры для сверки.
Через какое-то время я опять запускаю startService, но с новыми параметрами. В таком
случае старый сервис нужно убить. stopService как я понял не поможет, onHandleIntent
так и останется работать. Может быть можно как-то обновить параметры в старом сервисе?
    


Ответы

Ответ 1



IntentService получаемые параметры обрабатывает по очереди, то есть если вы сначала запустили startService() с одними параметрами, потом еще раз, но с другими параметрами, то будет 1 сервис, который будет обрабатывать запросы по очереди и они (разные запросы) не будут "мешать" друг другу. Так что "убивать" нет необходимости.

вторник, 17 марта 2020 г.

Остановить сервис через некоторое время после его старта

#java #android #service #сервисы


Как остановить сервис через некоторое время после его старта. Допустим, служба проработала
минуту, теперь надо её убить.    


Ответы

Ответ 1



Попробуйте так: то, что вы напишите в "run" исполнится через количество миллисекунд, заданных числом в конце метода. final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { // Сделать что-то чрез 60с = 60 000мс //Тут останавливать сервис context.stopService(new Intent(context, Service.class)); } }, 60000); Соответственно поместите этот кусок кода в метод, коий запускается при старте сервиса.

пятница, 13 марта 2020 г.

Запуск и остановка служб в Linux Mint

#linux #service


Какими командами останавливаются/запускаются службы в Linux Mint?

P.S. Разобрался:

sudo /etc/init.d/name_service stop/start

    


Ответы

Ответ 1



Бо́льшую часть служб можно запустить/перезапустить/остановить командой service SERVICE_NAME start/restart/stop Но некоторые такому управлению не поддаются и нужно использовать другие команды: /etc/init.d/SERVICE_NAME start/restart/stop Естественно, что это придётся выполнять с правами root.

понедельник, 24 февраля 2020 г.

Как обработать критическую ошибку при старте службы Windows?

#c_sharp #service


При старте службы windows возникает критическая ошибка требующая останова еще не
стартовавшей службы. Ошибку логирую. Но что делать с ней дальше? Как сообщить windows,
чтобы она не считала службу запущенной? Можно ли как то информировать пользователя
о том что служба не запущена?

Спасибо.
    


Ответы

Ответ 1



Если сервис не смог корректно запуститься - то достаточно просто остановить его из кода, вызовом Stop(): protected override void OnStart(string[] args) { // случилась ошибка? this.Stop(); } Он перейдет обратно в Stopped. Если при этом попытка запуска была инициирована пользователем - тому покажется стандартное сообщение вида The Service12 service on Local Computer started and then stopped. Some services stop automatically if they are not in use by other services or programs.

Ответ 2



Насколько я понял: У вас при инициализации службы происходит критическая ошибка. Вы с помощью try/catch её перехватываете, пишете сообщение в лог. В этот момент остановить службу вы не можете, так как она еще не запустилась. Возможные решения: Заведите переменную типа bool, и при вызове метода OnStart проверяйте её значение. В OnStart вы можете остановить службу. Я бы посоветовал вам не использовать код, который может привести к ошибке, в конструкторе. По возможности, постарайтесь перенести его в метод OnStart.

четверг, 13 февраля 2020 г.

Как закрыть другое Activity из класса, наследующего Service?

#java #android #многопоточность #service


Мой класс MyService:  

public class MyService extends Service
{
    IBinder mBinder;
    public static boolean status = true;

    @Override
    public void onCreate()
    {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        someTask();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy()
    {
        Log.e("MY_SERVICE", "onDestroy()");
        new CheckThread().stop();
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent)
    {
        return mBinder;
    }

    public void someTask()
    {
        new CheckThread().start();
    }

    public class CheckThread implements Runnable
    {
        Thread th;

        @Override
        public void run()
        {
            main();
        }

        public void start()
        {
            th = new Thread(this);
            th.setPriority(Thread.NORM_PRIORITY);
            Log.e("CheckThread", "start()");
            th.start();
        }

        public synchronized void stop()
        {
            th = null;
            status = false;
            Log.e("CheckThread", "stop()");
            notify();
        }

        public void main()
        {
            while (status)
            {
                if ( ! status)
                    stop();
                boolean connect = Vars.connect;
                if ( ! connect)
                {
                    Intent intent = new Intent("android.intent.action.MAIN");
                    intent.setClass(MyService.this, Disconnect.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                    status = false;
                    stop();
                }
                try
                {
                    Thread.sleep(3000);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}


Класс Disconnect запускается, когда закрывается Socket-соединение (класс не наследует
Activity, функции с UI недоступны).

    new Thread(new Runnable()
    {
        public void run()
        {
            String str = "";
            try
            {
                while ((str = in.readLine()) != null)
                {

                }
            }
            catch (IOException e)
            {
            }
            Vars.connect = false;
        }
    }).start();


Возможно ли как-то сделать так, чтобы при открытии класса Disconnect в MyService
закрывалось другое активное Activity, чтобы был активен только Disconnect? 

Ответов, как закрыть другое Activity из класса, наследующего Service, я не нашёл.
    


Ответы

Ответ 1



Только сама Activity может завершить себя (также она может быть завершена ОС). Из Service надо послать сигнал Activity на завершение, по получении которого она сама вызовет finish(). Сделать это можно одним из способов, описанных в этом ответе. Лично я рекомендую LocalBroadcastManager.

воскресенье, 26 января 2020 г.

Использование OpenCV в Service на ОС Android

#android #service #opencv


Добрый день.

При разработки службы (Service) в ОС Android с использованием библиотеки OpenCV4Android,
требуется обработать с использованием методов кадры (Frame) с камеры в background-режиме. 
Из всех советов, находил и про SurfaceView, и про создании отдельных служб, но так
и не понял, как адаптировать это дело - не черта не понял.

И собственно вопросы:


Как обработать фреймы камеры в созданном Service?
Как адаптировать это всё под использование OpenCV4Android.


P.S. ответы находил на эти вопросы здесь https://stackoverflow.com/questions/18811303/android-opencv-process-camera-frames-in-a-service

Но не понял, как этим можно воспользоваться, если кто сможет объяснить - буду благодарен.

UPDATE
Разобрался в итоге, если у кого-то есть вопросы - пишите.
Достаточно интегрировать класс HardwareCamera из ссылки в вашу службу. При удалении
некоторых неиспользуемых методов и редактировании кода вполне работает в службе и позволяет
обрабатывать фреймы камеры, используя OpenCV.

P.S. Таким образом, мне удалось заставить обнаруживать лица на камере, используя
несколько примеров из интернета.
    


Ответы

Ответ 1



вынесено из обновления вопроса: Разобрался в итоге, если у кого-то есть вопросы - пишите. Достаточно интегрировать класс HardwareCamera из ссылки в вашу службу. При удалении некоторых неиспользуемых методов и редактировании кода вполне работает в службе и позволяет обрабатывать фреймы камеры, используя OpenCV. P.S. Таким образом, мне удалось заставить обнаруживать лица на камере, используя несколько примеров из интернета.

воскресенье, 12 января 2020 г.

Android. immortal Thread

#java #android #многопоточность #service


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

В своем приложении, к сожалению, я НЕ могу использовать сервис. Я использую обычный
поток.

@Override
public void run() {       
    Looper.prepare();
    // code
    Looper.loop();
}


Он так же как сервис работает в фоновом режиме и выполняет соответствующие команды,
но так же и падает при нехватке памяти.

Ну так вот, знает кто, есть ли возможность этого избежать? Или каким-нибудь образом
реализовывать логику немедленного восстановления убитого потока?
Пробовал повышать приоритет у потока, так же прописывал в манифесте

android:largeHeap="true"


Не помогает. 

Другой сервис использовать для поддержания потока так же нельзя =)
Все что приходит на ум - использовать какой-нибудь системный receiver, который можно
прописать в манифесте. При этом он должен принимать команды постоянно, хотя бы раз
в минуту.
    


Ответы

Ответ 1



Скорее всего вам может помочь только рассылка собственных Intent через AlarmManager. Эти интенты принимайте в собственном ресивере и запускайте сервис. Вариант с системным интентом, рассылаемым каждую минуту, не подойдёт, т.к. его нельзя ловить в ресивере, определённом в манифесте. Только через Context.registerReceiver(). А, значит, нужен кто-то работающий, чтоб среагировать на интент.

пятница, 10 января 2020 г.

Определить из Сервиса запущено ли Активити

#android #activity #service


Из Активити запущен сервис, в котором запускается таймер.
Когда таймер закончит отсчет, нужно проверить, запущено ли Активити (за это время
пользователь может его закрыть, может не закрыть, может закрыть и снова открыть). В
зависимости от этого, либо сервис сам останавливается, либо в Активити передается сообщение
о том, что нужно нажать кнопку остановки. 
У меня для того ,что бы сервис знал о состоянии Активити, оно отправляет ему сообщения
startService(new Intent(this, MyService.class).putExtra("Mode", 0[1]));
каждый раз при запуске и при закрытии. 
Вопрос: Есть ли более эффективный метод проверки из сервиса, запущено ли породившее
его Активити? Если нет, откуда лучше отправлять сообщение startService ( OnCreate/OnDestroy,
OnResume/OnPause)? 
    


Ответы

Ответ 1



При завершении работы отправьте уведомление в активити (бродкастом или через EventBus) и создайте задачу через 2 секунды остановить сервис. Из активити при получении уведомления отправляйте подтверждение. Сервис, при получении подтверждения может отменить задачу остановки самого себя. Отсутствие подтверждения считайте отсутствием активити.

Ответ 2



Как вариант запустить Bound Service и при вызове Activity.onDestroy() известить Service о своей гибели. Так что к моменту завершения сервиса у него всегда будет информация о том жив ли Activity, который его запустил.

понедельник, 6 января 2020 г.

Как отправить данные в уже запущенный Service?

#android #service #android_intent


Как отправить данные в уже работающий сервис?

activity_main.xml




    

    

    



MainActivity.java

package com.example.my.myapplication;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;

import android.view.View;
import android.widget.EditText;


public class MainActivity extends Activity {

    public final static String BROADCAST_ACTION = "com.example.my.myapplication";

    BroadcastReceiver br;
    EditText EditText1;
    EditText EditText2;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EditText1 = (EditText) findViewById(R.id.editText1);
        EditText2 = (EditText) findViewById(R.id.editText2);

        // создаем BroadcastReceiver
        br = new BroadcastReceiver() {
            // действия при получении сообщений
            public void onReceive(Context context, Intent intent) {
                int result = intent.getIntExtra("result", 0);
                String re = Integer.toString(result);
                EditText2.setText(re);
            }
        };
        // создаем фильтр для BroadcastReceiver
        IntentFilter intFilt = new IntentFilter(BROADCAST_ACTION);
        // регистрируем (включаем) BroadcastReceiver
        registerReceiver(br, intFilt);


        Intent intent;

        // Создаем Intent для вызова сервиса,
        // кладем туда параметр времени и код задачи
        int s = Integer.parseInt(EditText1.getText().toString());
        intent = new Intent(this, MyService.class).putExtra("time", s);
        intent.putExtra("time", s);
        // стартуем сервис
        startService(intent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // дерегистрируем (выключаем) BroadcastReceiver
        unregisterReceiver(br);
    }

    public void onClickStart(View v) {
        Intent intent;
        int s = Integer.parseInt(EditText1.getText().toString());
        intent = new Intent(this, MyService.class).putExtra("time", s);
        intent.putExtra("time", s);
    }

}


MyService.java

package com.example.my.myapplication;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyService extends Service {

    ExecutorService es;

    public void onCreate() {
        super.onCreate();
        es = Executors.newFixedThreadPool(1);
    }

    public void onDestroy() {
        super.onDestroy();
    }

    public int onStartCommand(Intent intent, int flags, int startId) {

        int time = intent.getIntExtra("time", 1);
        MyRun mr = new MyRun(startId, time);
        es.execute(mr);

        return super.onStartCommand(intent, flags, startId);
    }

    public IBinder onBind(Intent arg0) {
        return null;
    }

    class MyRun implements Runnable {

        int time;
        int startId;

        public MyRun(int startId, int time) {
            this.time = time;
            this.startId = startId;
        }

        public void run() {
            Intent intent = new Intent(MainActivity.BROADCAST_ACTION);
            while (true) {
                try {
                    // начинаем выполнение задачи
                    TimeUnit.SECONDS.sleep(time);
                    // сообщаем об окончании задачи
                    intent.putExtra("result", time * 100);
                    sendBroadcast(intent);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
           // stop();
        }

        void stop() {
            stopSelfResult(startId);
        }
    }
}


Что я хочу от приложения: при запуске стартует сервис, ему отправляется число. Он
это число умножает на 100 и отправляет результат в активити во второе текстовое поле
(причём продолжает работать дальше). Далее я хочу отправить сервису новое число, не
останавливая его работу, ввожу новое число в первое тестовое поле, и при нажатии на
кнопку надо отправить сервису это число. А он должен его также умножить на 100 и отправить
обратно в активити в первое текстовое поле. Не могу разобраться, как передавать данные
уже запущенному сервису. Подскажите.
    


Ответы

Ответ 1



Запущенный сервис будет работать пока у него не вызван stopSelf(). Передавать данные в сервис можно так же с помощью startService(intent), новый сервис запускаться при этом не будет, а у запущенного сервиса будет вызван onStartCommand. Таким образом, вам надо убрать бесконечный цикл из MyRun.run(), реализовать логику ваших умножений, убрать stopSelfResult из MyRun.stop() и добавить startService(intent); в onClickStart вашей активити. Чтобы таки потом остановить сервис, запустите его с другим intent'ом, в onStartCommand обработайте его: остановите ваш пул или подождите пока он не отработает (см. тут). Затем вызовите stopSelf.

В чем отличие service locator от ioc-container?

#java #service #inversion_of_control


Хотелось бы примеры реализации на java,  примеров реализации service locators полно,
а вот ioc-containers не нашёл. Все ведет на готове реализации ioc, как правило Spring.
    


Ответы

Ответ 1



ServiceLocator и Dependency Injection можно рассматривать как две формы паттерна IoC. Только в первом случае зависимости запрашиваются у локатора(получается некоторый global state, что не очень хорошо), а во втором контейнер сам устанавливает зависимости классу. Есть старенькая, но очень хорошая статья от Фаулера - см. тут (ее вольный перевод есть тут и тут). Еще советую почитать статью от skipy Кроме Spring-а есть и другие реализации IoC - контейнеров: guice, weld-cdi,dagger, pico container, silkdi

воскресенье, 29 декабря 2019 г.

В чем смысл OnStart, когда все можно запихать в конструктор службы?

#c_sharp #net #service


На мой взгляд, OnStart нужен для какой-то инициализации.

Зачем нужен метод OnStart, когда все можно добавить в конструктор службы?
    


Ответы

Ответ 1



Запуск службы в отдельном процессе происходит так: Сначала запускается процесс. Процесс считается запущенным, когда вызван метод ServiceBase.Run Если процесс долго не запускается (тайм-аут там стоит 3 или 5 секунд) - винда прекращает запуск службы и переводит службу в режим останова. При этом не отрабатывает автоматический перезапуск, а в системных логах - невнятная ошибка. Также, пока процесс не запущен, диспетчер служб не имеет возможности выдавать службе никаких команд - что с точки зрения администратора может выглядеть как крайняя степень глючности. Потом запускается служба. Служба считается запущенной когда отработал метод OnStart. Этого события система ждет дольше - тайм-аут по умолчанию там 30 секунд. Кроме того, всегда можно запросить дополнительное время с помощью метода RequestAdditionalTime Пока служба запускается - она находится в состоянии, которое так и называется - "Запускается". Если служба не успела или не смогла запуститься - это событие отрабатывается системой куда адекватнее. Поэтому, в конструкторе службы, также как и в методе Main, следует делать только те действия, которые могут быть сделаны быстро. Для долгих действий надо использовать OnStart. А очень долгие - надо выносить в отдельный поток и предусматривать прерывание их на середине. Также следует помнить, что внезапно долгим может оказаться любой сетевой запрос, обращение к СУБД или к файлу по сетевому пути - причем их тайм-ауты по умолчанию превышают тайм-аут ожидания запуска процесса. Ни одно из этих действий нельзя делать в конструкторе.

Ответ 2



Ох, давно дело было. Если мне память не изменяет, то с OnStart начинается непосредственное выполнение службой действий, какие тебе нужны. А конструктор он для инициализации именно. Так же OnStart способен принять аргументы, которые могут сконфигурировать выполнение службы. Прошу прощения за неточность, но так же OnStart является методом жизненного цикла, и по логике должен вызываться в самый подходящий момент для запуска службы. Есть ли в этом разница с конструктором или нет - не могу с уверенностью сказать, но жизненный цикл вообще для таких вещей и служит. UPD: Конструктор службы вызывается единожды при иницализации, в дальнейшем служба может быть запущена с вызовом OnStart, остановлена с помощью OnStop и еще пара методов для рабы с приостановкой OnPause и OnContinue. Разница между конструктором и OnStart проявляется так же в том, что конструктор не вызывается после повторного запуска, сразу же вызывается метод OnStart, который должен инициализировать необходимые для работы ресурсы и запустить производимые службой действия. Вот тут https://msdn.microsoft.com/ru-ru/library/system.serviceprocess.servicebase(v=vs.110).aspx все очень хорошо описано.

C# service не могу понять, где здесь утечка памяти

#c_sharp #net #windows #service #wmi


Создал сервис с помощью шаблона, сократил код до минимума, и всё равно за несколько
минут сервис уже не 4, а 8 мб занимает и продолжает расти. Вот сам код:

protected override void OnStart(string[] args)
{
    bool close = false;
    bool alreadySend = false;
    bool firstExecute = true;
    int open_counter = 1;
    while (true)
    {
        if (open_counter >= 2147483643)
            open_counter = 1;

        ManagementObjectCollection sList = null;
        ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select
* From Win32_USBHub");
        sList = searcher.Get();
        sList.Dispose();
        searcher.Dispose();
        open_counter++;
        System.Threading.Thread.Sleep(10);
    }
}


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


Ответы

Ответ 1



Вот тут ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_USBHub"); Вы создаете обьект. А вот тут: searcher.Dispose(); Вы говорите GC, что его можно удалить, а не удаляете его. И делаете это в цикле. Это же C#, а не С++. Тут за Вас удаляет все сборщик мусора, он сам решит когда пора чистить и, приостановив программу, почистит. Попробуйте подождать и понаблюдать. Особенно в Visual Studio это хорошо видно. Там прям график есть. С MSDN: Этот метод используется для закрытия или освобождения неуправляемых ресурсов, таких как файлы, потоки и дескрипторы, хранящиеся экземпляром класса, реализующего этот интерфейс. Согласно Конвенции этот метод используется для всех задач, связанных с освобождением ресурсов, находящихся в объекте, или подготовкой объекта к повторному использованию.

Ответ 2



Об утечке памяти можно говорить только после продолжительного наблюдения и сравнения снэпшотов состояния памяти. Сборщик мусора в CLR достаточно ленив (говоря строгим языком, его поведение недетерменировано), и если у вас на машине достаточно памяти, то собирать мусор он будет редко. Так что запускайте сервис, берите профайлер и делайте снэпшоты каждый час. А потом смотрите, остались ли в живых какие-то объекты, которые по идее должны были уже удалиться, а так же на их количество (наличие некоторого количества таких объектов нормально). P.S. Ну и да, используйте лучше using: using (var searcher = new ManagementObjectSearcher("Select * From Win32_USBHub")) using (var sList = searcher.Get()) { ... }

четверг, 26 декабря 2019 г.

Принудительный выход устройства Android из режима блокировки

#android #java #service


Написал службу (Service) для устройств с ОС Android. Работает прекрасно, но только
в режиме, когда с телефоном работают (т.е. разблокирован и не в режиме сна). По блокировке
телефона, служба перестает исполнять свои функции.

Вопрос следующий.


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

    


Ответы

Ответ 1



В общем для того, чтобы устройство не засыпало надо контролировать т.н. WakeLock - то есть если вы будете держать WakeLock, то Service не остановится, иначе он заснет вместе с устройством. Паттерн использования может выглядеть так: Спим Некое событие (например AlarmManager) Захват (acquire) WakeLock Выполнение некой функции - например получени GPS координат, проверка Email да мало ли что еще! Отпускаем WakeLock Засыпаем В общем как-то так Не забудьте, что для использования WakeLock нужен специальный пермишен в манифесте: android.permission.WAKE_LOCK

вторник, 24 декабря 2019 г.

Сервис отключается при засыпании телефона

#java #android #service


Код сервиса, который каждую минуту запускает вибрацию на телефоне.
Как только экран гаснет, сервис прекращает работу. Как запретить остановку? И как
в нужный момент по кнопке остановить этот сервис?

    public class TimeService extends Service {
Vibrator vib;
public static final long NOTIFY_INTERVAL = 60 * 1000; // 60 seconds
private Handler mHandler = new Handler();
private Timer mTimer = null;

@Override
public IBinder onBind(Intent intent) { return null; }

@Override
public void onCreate() {
    vib = (Vibrator) this.getSystemService(Context.VIBRATOR_SERVICE);

    // cancel if already existed
    if (mTimer != null) { mTimer.cancel();}
else { mTimer = new Timer(); }
    // schedule task
    mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0,
            NOTIFY_INTERVAL);
}

class TimeDisplayTimerTask extends TimerTask {

    @Override
    public void run() {
        // run on another thread
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                vib.vibrate(500);
            }
        });
    }


Запускаю сервис так:

public void onClick_btTask(View v) {
    startService(new Intent(this, TimeService.class));

}

    


Ответы

Ответ 1



Service по умолчанию работает в том же потоке, что и запускающая его activity. Чтобы вибрировать каждую минуту, можете попробовать использовать связку с IntentService и AlarmManager-а с ключом RTC_WAKEUP, который будет этот IntentService каждую минуту вызывать. Примерно так: public class VibrateService extends IntentService { public static final String TAG = "VibrateService"; public VibrateService() { super(TAG); } @Override protected void onHandleIntent(Intent intent) { Vibrator vibrator = (Vibrator) this.getSystemService(Context.VIBRATOR_SERVICE); vibrator.vibrate(500); } } ... Intent intent = new Intent(this, VibrateService.class); // Запуск повторения вызова сервиса AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 60 * 1000, PendingIntent.getService(this, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT)); Конечно же, VibrateService должен быть объявлен в манифесте, как и разрешение вибрировать:

Как реализуются службы, которые срабатывают по расписанию?

#c_sharp #net #service


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

Как это правильно делается?

Правильно ли создавать список таймеров, на каждый таймер привязывать обработчик события(В
зависимости от типа задачи), затем высчитывать время срабатывания в мс относительно
текущего времени, а потом запускать отсчет?

Нашел еще какой-то Quartz.NET... На сколько он хорош?
    


Ответы

Ответ 1



Quartz.NET не пробовал, попробуйте, вдруг понравится =) Обычно "Правильно" у каждого свое, мои соображения следующие: 1. Короткие интервалы (секунды, минуты) Набор задач для коротких интервалов времени обычно фиксирован и задачи тесно связаны между собой. Поэтому предложенный вами вариант будет вполне уместным, но есть и недостатки: При перезапуске службы все задачи будут прерваны в произвольном месте, если не предусмотрен особый код завершения работы службы, таймеры будут перезапущены. Для изменения интервалов необходимо перезапускать службу, если не предусмотрена специальная команда для этого. К достоинствам можно отнести возможность прямой передачи данных между задачами с использованием привычных типов данных, достаточно высокую точность срабатывани по времени, для ультра коротких интервалов можно использовать таймер на основе StopWatch, имеющий максимальную точность измерения времени. Альтернативой может служить набор консольных программ (одна задача - одна программа) запускаемых с помощью системного планировщика. Для коротких интервалов преимущества данного метода весьма сомнительны если вообще есть. 2. Средние интервалы (часы, дни) Набор задач для таких интервалов иногда требует изменений набора выполняемых действий, а также принудительного выполнения задач мне расписания, что также накладывает ряд требований на применяемое решение. В службе с внутренними таймерами, придется предусмотреть специальные методы для управления списком выполняемых задач, принудительного запуска отдельных задач, сохранения расписания не смотря на внеплановый запуск. Также стоит отметь что служба будет висеть в памяти постоянно и расходовать ресурсы, особенно печально если где-то есть незначительная утечка, которую сразу не выявили. Для набора программ работающих по системному планировщику, ничего дополнительного делать не придется, этот функционал уже заложен в системном планировщике. Системный планировщик задач в любом случае запущен всегда, а вот ваши задачи будут потреблять ресурсы только во время выполнения, проблема постоянной утечки памяти при длительной работе отсутствует. Добавление и удаление задач не составляет особого труда. Возможно обновление программ выполняющих задачи независимо друг от друга. Возможно увеличение производительности за счет запуска особо тяжелых задач на отдельных компьютерах. К недостаткам - необходимость обмена данными между связанными задачами посредством файлов. Учитывая длину интервалов файловый обмен не очень страшен, но время на разработку протокола и формата файлов потратить придется. 3. Длинные интервалы (недели, месяцы, годы) Набор задач почти гарантированно будет меняться в процессе работы, и задачи редко бывают связаны между собой, либо объединяются в одну большую задачу. Со мной могут не согласиться другие участники, но лично мне, на таких интервалах использовать монолитную службу просто неудобно. К тому же в службе придется предусмотреть еще и синхронизацию времени, хотя бы с системными часами, и календарем, если нужно запускать задание, например раз в неделю, или по первым числам месяцев. Системный планировщик в данном случае освобождает разработчика от необходимости писать что либо кроме кода выполняемых задач. 4. Неопределенные интервалы или работа по событию Этот вариант конечно имеет малое отношение к таймерам, однако в рамках сравнения двух подходов его стоит рассмотреть. В службе необходимо предусмотреть код слушающий необходимые события. Обрабатываемые события могут быть вынесены в конфигурацию, а вот добавление или удаление действий без пересборки и переустановки службы уже не сделать. Системный планировщик также умеет срабатывать по событиям, но ограничен событиями, которые отслеживает операционная система. Чтобы добавить что-то свое, придется определить и зарегистрировать в системном логе источник событий, коды событий, возможно даже отдельный журнал событий и т.д. В отдельных сложных случаях результат стоит потраченного времени. Также для сложных случаев обработки событий можно написать свой планировщик, который будет реагировать на все что вам нужно и запускать программы для обработки задач вместо системного планировщика. В целом, для работы по событиям, можно считать оба способа равнозначными. Собственный планировщик задач. В некоторых случаях использовать системный планировщик не очень удобно. Тогда можно реализовать свой. Идея довольно простая: один таймер с фиксированным минимальным шагом, например раз в секунду. по событию таймера сравниваем текущее время с расписанием запланированных заданий. запускаем в отдельном потоке или процессе выполнение заданий, время которых меньше либо равно текущему.

Ответ 2



Для простых случаев -- запускать задачу раз в N секунд/минут/часов, один инстанс сервиса, нет критичных требований к запускам -- таймеров будет достаточно. Если же вам нужны гибкие расписания (читай, cron expressions), фейловер, возможность ребалансировки, персистентность, тогда лучше использовать Quartz.NET.

среда, 18 декабря 2019 г.

Web Service для Linux-сервера на C#

#c_sharp #mono #wcf #service #linux


Я занимаюсь изучением возможности написания Web Service'a для Linux-сервера при использовании
C#. Для этого необходимо использовать Mono-Framework. Как я понял, WCF в Mono имплементирован
лишь относительно и у меня появилось чувство, что лучше не трогать его. Вроде бы и
все основные вещи должны работать, но что-то не то...

И я вот подумал, что может лучше стоило бы воспользоваться другими фрэймворками,
которые адаптированны под Mono. Я нашел несколько, но наиболее интересными мне показались
лишь 3: 


Nancy
ServiceStack
NServiceBus (не понятно, работает вообще под моно или нет, но вроде как должен.


Есть ли у кого нибудь опыт подобной разработки и что можно было бы для этого посоветовать?
Поделитесь опытом. 

Или лучше вообще отказаться от такого проекта? Клиент хочет, чтобы сервер работал
на Linux и на Windows без установки Tomcat (поэтому ява исключается).
    


Ответы

Ответ 1



попробуй ASP .NET, там есть asmx-файлы http://www.mono-project.com/archived/writing_a_webservice/ <%@ WebService Language="C#" Class="MathService.MathService" %> using System; using System.Web.Services; namespace MathService { [WebService (Namespace = "http://tempuri.org/NumberService")] public class MathService : WebService { [WebMethod] public int AddNumbers (int number1, int number2) { return number1 + number2; } [WebMethod] public int SubtractNumbers (int number1, int number2) { return number1 - number2; } } }