【问题标题】:Android - Periodic Background Service - AdviceAndroid - 定期后台服务 - 建议
【发布时间】:2012-05-02 19:28:03
【问题描述】:

我正在开发一个应用程序,它将有关其位置的信息中继到远程服务器。我打算通过向网络服务器发送一个简单的 HTTP 帖子来做到这一点,一切都很简单。

但根据规范,应用程序需要不时执行自身,假设每 30 分钟执行一次。独立于界面,这意味着即使应用程序关闭,它也需要运行。

我环顾四周,发现需要使用 Android Services。我可以用什么来实现这样的系统。手机重启时服务(或其他机制)会重启吗?

提前致谢。

【问题讨论】:

    标签: android service


    【解决方案1】:

    创建Service 将您的信息发送到您的服务器。大概,你已经控制住了。

    您的Service 应该由AlarmManager 触发的警报启动,您可以在其中指定时间间隔。除非您必须每 30 分钟准确报告一次数据,否则您可能需要不准确的警报,以便节省一些电池寿命。

    最后,您可以通过设置BroadcastReceiver 来注册您的应用以获取启动广播,如下所示:

    public class BootReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {  
            if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
                // Register your reporting alarms here.            
            }
        }
    }
    

    您需要将以下权限添加到您的 AndroidManifest.xml 才能使其正常工作。正常运行应用时不要忘记注册闹钟,否则只有在设备启动时才会注册。

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    

    【讨论】:

      【解决方案2】:

      这是一种使服务永久运行的半不同方式。如果你愿意,有办法在代码中杀死它

      后台服务:

      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() 将在应用程序关闭或终止时被调用,但可运行对象只是重新启动它。

      我希望这对某人有所帮助。

      有些人这样做的原因是因为企业应用程序在某些情况下用户/员工不能停止某些事情:)

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


      编辑

      从 Android O (8.0) 开始,您必须使用 JobManager 来执行计划任务。有一个名为 Android-Job by Evernote 的库,它可以让所有 Android 版本的定期后台工作变得轻而易举。我还为这个库做了一个Xamarin Binding

      那么你需要做的就是:

      在您的应用程序类中:

      public class MyApp extends Application {
      
          @Override
          public void onCreate() {
              super.onCreate();
              JobManager.create(this).addJobCreator(new MyJobCreator());
          }
      }
      

      创建以下两个类YourJobCreatorYourSyncJob(所有工作都将在其中完成。Android 为要运行的所有后台作业分配时间。对于

      public class MyJobCreator implements JobCreator {
      
          @Override
          @Nullable
          public Job create(@NonNull String tag) {
              switch (tag) {
                  case MySyncJob.TAG:
                      return new MySyncJob();
                  default:
                      return null;
              }
          }
      }
      
      public class MySyncJob extends Job {
      
          public static final String TAG = "my_job_tag";
      
          @Override
          @NonNull
          protected Result onRunJob(Params params) {
              //
              // run your job here
              //
              //
              return Result.SUCCESS;
          }
      
          public static void scheduleJob() {
              new JobRequest.Builder(MySyncJob.TAG)
                      .setExecutionWindow(30_000L, 40_000L) //Every 30 seconds for 40 seconds
                      .build()
                      .schedule();
          }
      }
      

      【讨论】:

      • 不错的解决方法,但这会在一段时间后继续启动处理程序,因为服务会在一段时间后再次启动。
      • 为了防止重启,将代码从 onCreate() 移动到 @Override public int onStartCommand(Intent intent, int flags, int startId) { //可运行代码 return START_NOT_STICKY; } return START_NOT_STICKY 将确保服务不会重新启动,并且您的处理程序将在 onDestroyed() 之后保持停止。
      • 不要忘记将服务添加到您的AndroidManifest.xml:&lt;service android:name=".services.MyService" android:label="MyService" &gt;&lt;/service&gt;
      • @KTWorks 这曾经适用于较旧的 Android 版本。您需要使用 github.com/evernote/android-job 之类的东西 - 使用正确的设置,您可以让作业无限期地运行而不会耗尽用户的电池。对于 Android O 及更高版本,您不能再在后台使用 StartService。所有处理程序都在打盹模式下暂停。
      【解决方案3】:

      您应该使用警报管理器安排您的服务,首先创建待处理的服务意图:

      Intent ii = new Intent(getApplicationContext(), MyService.class);
      PendingIntent pii = PendingIntent.getService(getApplicationContext(), 2222, ii,
      PendingIntent.FLAG_CANCEL_CURRENT);
      

      然后使用警报管理器安排它:

      //getting current time and add 5 seconds to it
      Calendar cal = Calendar.getInstance();
      cal.add(Calendar.SECOND, 5);
      //registering our pending intent with alarmmanager
      AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
      am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), pi);
      

      这将在当前时间 5 秒后启动您的服务。你可以让你的闹钟重复。

      【讨论】:

      • System.currentTimeMillis() + TIMEOUT_MS 之类的事情可能比处理Calendar 更容易,以获得您的初始延迟。
      • 你们知道在 AlarmManager 中有 1 天、12 小时、1 小时、半小时和 15 分钟的静态值吗? public static final long INTERVAL_DAYpublic static final long INTERVAL_FIFTEEN_MINUTESpublic static final long INTERVAL_HALF_DAYpublic static final long INTERVAL_HALF_HOURpublic static final long INTERVAL_HOUR
      【解决方案4】:

      您可以使用Alarm Manager在指定时间启动服务,然后在指定时间间隔重复报警。当警报响起时,您可以启动服务并连接到服务器并制作您想要的东西

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多