Создание фонового сервиса в Android
В моем проекте мне нужно создать сервис в Android. Я могу зарегистрировать сервис следующим образом:
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<service android:enabled="true"
android:name=".ServiceTemplate"/>
<activity
android:name=".SampleServiceActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Я звоню на эту услугу внутри деятельности, как показано ниже:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent service = new Intent(getApplicationContext(), ServiceTemplate.class);
this.startService(service);
}
Но если я убью текущую активность, служба также будет уничтожена. Мне нужен этот сервис всегда работает в фоновом режиме. Что я должен сделать? Как мне зарегистрировать сервис? Как мне запустить сервис?
5 ответов
Вот полу-другой способ сохранить сервис навсегда. Есть способы убить его в коде, если вы хотите
Фоновая служба:
package com.ex.ample;
import android.app.Service;
import android.content.*;
import android.os.*;
import android.widget.Toast;
public class BackgroundService extends Service {
public Context context = this;
public Handler handler = null;
public static Runnable runnable = null;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
Toast.makeText(this, "Service created!", Toast.LENGTH_LONG).show();
handler = new Handler();
runnable = new Runnable() {
public void run() {
Toast.makeText(context, "Service is still running", Toast.LENGTH_LONG).show();
handler.postDelayed(runnable, 10000);
}
};
handler.postDelayed(runnable, 15000);
}
@Override
public void onDestroy() {
/* IF YOU WANT THIS SERVICE KILLED WITH THE APP THEN UNCOMMENT THE FOLLOWING LINE */
//handler.removeCallbacks(runnable);
Toast.makeText(this, "Service stopped", Toast.LENGTH_LONG).show();
}
@Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "Service started by user.", Toast.LENGTH_LONG).show();
}
}
Вот как вы начинаете это со своей основной деятельности или где хотите:
startService(new Intent(this, BackgroundService.class));
onDestroy()
будет вызван, когда приложение будет закрыто или уничтожено, но исполняемый файл просто запустит его обратно. Вам также необходимо удалить обратные вызовы обработчика.
Я надеюсь, что это поможет кому-то.
Причина, по которой некоторые люди делают это, связана с корпоративными приложениями, где в некоторых случаях пользователи / сотрудники не могут останавливать определенные вещи:)
Но если я убиваю текущую деятельность, служба также убивает. Мне нужен этот сервис всегда работает в фоновом режиме. Что я должен сделать?
Если под "убить текущую активность" вы подразумеваете, что используете убийцу задач или принудительную остановку в приложении "Настройки", ваша служба будет остановлена. С этим ничего не поделаешь. Пользователь указал, что не хочет, чтобы ваше приложение больше запускалось; Пожалуйста, уважайте пожелания пользователя.
Если под "убить текущую активность" вы имеете в виду, что вы нажали BACK или HOME или что-то еще, то служба должна продолжать работать, по крайней мере, некоторое время, пока вы не позвоните stopService()
, Он не будет работать вечно - Android в конечном итоге избавится от сервиса, потому что слишком много разработчиков пишут сервисы, которые пытаются "всегда работать в фоновом режиме". А также. Конечно, пользователь может убить службу, когда захочет.
Служба должна быть "запущена" только тогда, когда она активно доставляет ценность пользователю. Обычно это означает, что служба не должна быть "всегда запущена в фоновом режиме". Вместо этого используйте AlarmManager
и IntentService
делать работу на периодической основе.
Вы можете создать фоновый сервис и вызвать его с помощью AlarmManager
1 - вам нужно создать класс BroadcastReceiver для вызова с помощью AlarmManager
public class AlarmReceiver extends BroadcastReceiver
{
/**
* Triggered by the Alarm periodically (starts the service to run task)
* @param context
* @param intent
*/
@Override
public void onReceive(Context context, Intent intent)
{
Intent i = new Intent(context, AlmasService.class);
i.putExtra("foo", "AlarmReceiver");
context.startService(i);
}
}
2 - вам нужно создать класс IntentService для вызова с помощью AlarmReceiver
public class AlmasService extends IntentService
{
public Context context=null;
// Must create a default constructor
public AlmasService() {
// Used to name the worker thread, important only for debugging.
super("test-service");
}
@Override
public void onCreate() {
super.onCreate(); // if you override onCreate(), make sure to call super().
}
@Override
protected void onHandleIntent(Intent intent) {
context=this;
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
String val = intent.getStringExtra("foo");
// Do the task here
Log.i("MyTestService", val);
}
}
3 - вы должны добавить AlarmReceiver в качестве получателя и AlmasService в качестве службы в манифесте
<service
android:name=".ServicesManagers.AlmasService"
android:exported="false"/>
<receiver
android:name=".ServicesManagers.AlmasAlarmReceiver"
android:process=":remote" >
</receiver>
4-теперь вы можете запустить сервис и вызвать AlarmManager на MainActivity
public class MainActivity extends AppCompatActivity
{
public static final int REQUEST_CODE = (int) new Date().getTime();
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scheduleAlarm();
}
public void scheduleAlarm()
{
// Construct an intent that will execute the AlarmReceiver
Intent intent = new Intent(getApplicationContext(), AlmasAlarmReceiver.class);
// Create a PendingIntent to be triggered when the alarm goes off
final PendingIntent pIntent = PendingIntent.getBroadcast(
this, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Setup periodic alarm every every half hour from this point onwards
long firstMillis = System.currentTimeMillis(); // alarm is set right away
AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
// First parameter is the type: ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC_WAKEUP
// Interval can be INTERVAL_FIFTEEN_MINUTES, INTERVAL_HALF_HOUR, INTERVAL_HOUR, INTERVAL_DAY
alarm.setRepeating(AlarmManager.RTC_WAKEUP, firstMillis, (long) (1000 * 60), pIntent);
}
}
Попробуйте запустить службу в отдельном потоке, чтобы, когда вы уничтожите свою деятельность, служба не пострадала. Он будет работать без перерыва. Также в сервисе возврата Service.START_STICKY
от onStartCommand(intent, flags, startId)
чтобы убедиться, что сервис воссоздан, если он был убит системой (ОС Android).
Переопределить этот метод:
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
Чтобы завершить то, что сказал @abhinav: если вы используете onBind(), вам не нужно использовать onStartCommand() и наоборот:
Фактически, если компонент вызывает bindService() для создания службы, а onStartCommand() не вызывается, служба работает только до тех пор, пока к ней привязан компонент. После того, как служба отключена от всех своих клиентов, система уничтожает ее. Для иллюстрации: метод onStartCommand() вызывается, когда ваша служба начинает выполнять свою работу. onCreate() завершен, и он готов приступить к тому, что нужно сделать. и если вы используете метод onBind(), вы привязываете Сервис к продолжительности жизни, например, Activity. Если Действие завершено, Служба может быть выпущена и может завершиться сама. Услуга будет действовать до тех пор, пока к ней что-то привязано.