在Android中创建后台服务

Sat*_*ish 13 service 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>
Run Code Online (Sandbox Code Playgroud)

我在以下活动中调用此服务: -

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Intent service = new Intent(getApplicationContext(), ServiceTemplate.class);
    this.startService(service);
}
Run Code Online (Sandbox Code Playgroud)

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

Pie*_*rre 12

这是一种半不同的方式来保持服务永远.如果你愿意,有办法在代码中杀死它

后台服务:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是您从主要活动或您希望的任何地方开始的方式:

startService(new Intent(this, BackgroundService.class));
Run Code Online (Sandbox Code Playgroud)

onDestroy()当应用程序关闭或被杀死时会被调用,但是runnable会立即启动它.您还需要删除处理程序回调.

我希望这可以帮助别人.

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

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

  • 是的,`&lt;service android:name =“ com.ex.ample.BackgroundService” android:exported =“ false” /&gt;`,但是这个答案很旧。对于较新的解决方案,请查看https://github.com/evernote/android-job (2认同)
  • 谢谢,在清单中声明服务后,此答案对我来说已经足够了!并停止服务,我使用onDestroy(){super.onDestroy(); stopService(new Intent(BackgroundService.class)); }上的活动,当应用程序关闭时,它将停止任何后台服务 (2认同)

Com*_*are 5

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

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

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

服务只有在积极地为用户提供价值时才应该"正在运行" .这通常意味着服务不应该"始终在后台运行".相反,使用AlarmManagerIntentService定期工作.


Mil*_*adi 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);

    }

}
Run Code Online (Sandbox Code Playgroud)

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);

    }

}
Run Code Online (Sandbox Code Playgroud)

3-您必须将AlarmReceiver添加为接收器,将AlmasService添加为清单上的服务

    <service
        android:name=".ServicesManagers.AlmasService"
        android:exported="false"/>

    <receiver
        android:name=".ServicesManagers.AlmasAlarmReceiver"
        android:process=":remote" >
    </receiver>
Run Code Online (Sandbox Code Playgroud)

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);



    }
}
Run Code Online (Sandbox Code Playgroud)