应用程序关闭后保持活动状态且不锁定UI的服务

时间:2015-11-24 13:53:36

标签: java android multithreading service intentservice

在我的Android项目中,我有必要开始Service

  1. 即使在申请结束后仍然活着
  2. 不阻止主线程
  3. 我为此问题分析了服务,IntentServices和线程:

    使用Service并覆盖

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // Some nasty code
        return START_STICKY;
    }
    

    我实现了第一个目标,但是当我启动服务时阻止主线程

    使用IntentService并覆盖

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        return START_STICKY;
    }
    
    @Override
    protected void onHandleIntent(Intent intent) {
        // Same nasty code as before
    }
    

    我实现了第二个目标,因为我没有阻止UI,但是当我杀死应用程序时服务就死了。

    然后我尝试使用Thread启动Service,如下所示:

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                //The usual nasty code
            }
        });
        thread.start();
        return START_STICKY;
    }
    

    我获得了与第一种情况相同的结果(我阻止了用户界面)。

    我使用myActivity.startService(myActivity, MyService.class)

    启动服务

    我错过了一些明显的东西吗?是否可以实现这两个目标?

4 个答案:

答案 0 :(得分:1)

对于这种情况:

  

即使在申请结束后仍然存活。

您需要使用Service而不是IntentService,因为在IntentService中的代码完全执行后onHandleIntent始终会自行终止。通过在startForeground(int notification_id, Notification notification)的{​​{1}}方法中调用onStartCommand,将使Service仍然活着,而不会阻止UI线程。但您需要创建Service方法的通知。在完成startForeground之后,请勿忘记stopForeground(true) onDestroy()方法中的Service。请记住,如果要执行的代码是异步的,请创建一个扩展Service的私有类ServiceHandler,并使用Handler方法运行代码。

实现此模式的应用程序是DU Battery Saver。

答案 1 :(得分:0)

如果您使用IntentServiceonHandleIntent方法中的所有内容都会自动显示在第二个工作人员Thread中。所以不需要自己创建Thread。还要确保您在onHandleIntent中完成了实际工作。这是您应该执行后台工作的地方。

另外you should not override onStartCommand

答案 2 :(得分:0)

这里是在关闭应用程序时,如果其进程被终止,则重新启动服务的代码。在您的服务中,添加以下代码。

@Override
public void onTaskRemoved(Intent rootIntent){
    Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
    restartServiceIntent.setPackage(getPackageName());

    PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
    AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    alarmService.set(
    AlarmManager.ELAPSED_REALTIME,
    SystemClock.elapsedRealtime() + 1000,
    restartServicePendingIntent);

    super.onTaskRemoved(rootIntent);
 }

答案 3 :(得分:0)

您可以按照以下步骤操作:

第1步:创建IntentService

public class DownloadService extends IntentService {
@Override
    protected void onHandleIntent(Intent intent) {
        // Gets data from incoming Intent
        String yourDataString = intent.getDataString();
        ...
        // manipulate intent
        ...
    }
}

Stpe 2:在清单中记录IntentService

<application
        android:icon="@drawable/icon"
        android:label="@string/app_name">
        ...

        <service
            android:name=".DownloadService"
            android:exported="false"/>
        ...
 <application/>

第3步:向IntentService发送请求

/* Starting Service */
Intent intent = new Intent(Intent.ACTION_SYNC, null, this, DownloadService.class);

/* You can send Extras to IntentService if needed */
intent.putExtra("url", url);
intent.putExtra("receiver", mReceiver);
intent.putExtra("requestId", 101);

startService(intent);
  

注意:需要android.permission.INTERNET权限。

您可以查看here表单