在我的项目中,我需要在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);
}
但如果我杀死当前活动,该服务也会被破坏。我需要这项服务始终在后台运行。 我需要做什么? 我该如何注册服务? 我该如何开始服务?
答案 0 :(得分:10)
这是一种保持服务永远不变的半不同方式。如果你愿意的话,有办法在代码中杀死它
后台服务:
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()
会被调用,但是runnable会立即启动它。您还需要删除处理程序回调。
我希望这可以帮助别人。
有些人这样做的原因是企业应用程序,在某些情况下,用户/员工必须无法阻止某些事情:)
答案 1 :(得分:5)
但如果杀死当前的活动,该服务也会被杀死。我需要这项服务始终在后台运行。我需要做什么?
如果通过“杀死当前活动”表示您正在使用任务杀手,或者在“设置”应用中强制停止,则您的服务将被停止。你无能为力。用户表示他们不希望您的应用再次运行;请尊重用户的意愿。
如果通过“杀死当前活动”你的意思是你按下BACK或HOME或其他东西,那么服务应该继续运行,至少会持续一段时间,除非你打电话给stopService()
。它不会永远运行 - Android最终将摆脱服务,因为太多开发人员编写的服务试图“始终在后台运行”。和。当然,用户可以在用户想要的时候终止服务。
当服务主动向用户提供价值时,服务应该只是“正在运行”。这通常意味着服务不应该“始终在后台运行”。相反,请使用AlarmManager
和IntentService
定期开展工作。
答案 2 :(得分:5)
您可以创建后台服务并通过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 - 现在您可以启动服务并在MainActivity上调用AlarmManager
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);
}
}
答案 3 :(得分:3)
尝试在单独的线程中启动服务,这样当您销毁活动时,服务不会受到影响。它会在没有任何中断的情况下运行。此外,在Service.START_STICKY
的服务返回onStartCommand(intent, flags, startId)
中,以确保在系统(Android OS)终止服务时重新创建该服务。
答案 4 :(得分:1)
覆盖此方法:
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_STICKY;
}
答案 5 :(得分:0)
完成@abhinav所说的:如果使用onBind(),则不需要使用onStartCommand(),反之亦然:
实际上,如果组件调用bindService()创建服务而未调用onStartCommand(),则仅在组件绑定到该组件时,该服务才会运行。服务从其所有客户端解除绑定后,系统将销毁它。为了显示: 当您的服务开始执行其工作时,将调用onStartCommand()方法。 onCreate()已完成,可以开始做需要做的事情。并且如果使用onBind()方法,则将Service与例如Activity的寿命相关联。如果活动完成,则该服务将被允许释放并且本身可以完成。该服务将持续存在,只要仍然有约束。