在Android中创建后台服务

时间:2012-02-07 13:36:41

标签: android service

在我的项目中,我需要在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);
}

但如果我杀死当前活动,该服务也会被破坏。我需要这项服务始终在后台运行。 我需要做什么? 我该如何注册服务? 我该如何开始服务?

6 个答案:

答案 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会立即启动它。您还需要删除处理程序回调。

我希望这可以帮助别人。

有些人这样做的原因是企业应用程序,在某些情况下,用户/员工必须无法阻止某些事情:)

http://i.imgur.com/1vCnYJW.png

答案 1 :(得分:5)

  

但如果杀死当前的活动,该服务也会被杀死。我需要这项服务始终在后台运行。我需要做什么?

如果通过“杀死当前活动”表示您正在使用任务杀手,或者在“设置”应用中强制停止,则您的服务将被停止。你无能为力。用户表示他们不希望您的应用再次运行;请尊重用户的意愿。

如果通过“杀死当前活动”你的意思是你按下BACK或HOME或其他东西,那么服务应该继续运行,至少会持续一段时间,除非你打电话给stopService()。它不会永远运行 - Android最终将摆脱服务,因为太多开发人员编写的服务试图“始终在后台运行”。和。当然,用户可以在用户想要的时候终止服务。

当服务主动向用户提供价值时,服务应该只是“正在运行”。这通常意味着服务不应该“始终在后台运行”。相反,请使用AlarmManagerIntentService定期开展工作。

答案 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的寿命相关联。如果活动完成,则该服务将被允许释放并且本身可以完成。该服务将持续存在,只要仍然有约束。