为什么 onStartCommand() 的主体只执行一次?

Why the body of onStartCommand() is getting executed only once?

为了了解 Android 中 IntentService 和 Service 之间的区别,我创建了下面发布的服务小测试 class。 MainActivity 有一个 Button,按下时, 服务将使用 startService() 启动,如下面的代码所示,这将调用 onStartCommand()。在 onStartCommand() 中,我 运行 循环 10 秒,然后我 预计该循环将阻塞 UI "the butoon"。实际上,当我第一次启动服务时发生了什么,但是当我在 10 秒后按下按钮时 经过,它将导致调用 onStartCommand() 但 onStartCommand() 中的日志消息永远不会显示,而且 UI 永远不会被阻止。

任何人都可以解释 onStartCommand() 的主体是什么被执行并仅在服务首次启动时阻塞 UI 并且此后不再启动?

MainActivity

public class MainActivity extends AppCompatActivity {

private Button mbtnSend = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    this.mbtnSend = (Button) findViewById(R.id.btn_send);
    this.mbtnSend.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(getApplicationContext(), MyService.class);
            startService(intent);
        }
    });
}
}


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    registerReceiver(this.mBCR_VALUE_SENT, new IntentFilter(MyIntentService.INTENT_ACTION));

    this.mbtnSend = (Button) findViewById(R.id.btn_send);
    this.mbtnSend.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(getApplicationContext(), MyIntentService.class);
            intent.putExtra("intent_key", ++i);
            startService(intent);
        }
    });
}

}

MyIntentService:

public class MyService extends Service{
private final String TAG = this.getClass().getSimpleName();
private long mStartTime;

@Override
public void onCreate() {
    super.onCreate();
    Log.w(TAG, SubTag.msg("onCreate"));

    this.mStartTime = TimeUtils.getTSSec();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.w(TAG, SubTag.msg("onStartCommand"));

    while ( (TimeUtils.getTSSec() - this.mStartTime) <=10) {
        Log.w(TAG, SubTag.msg("time: " + (TimeUtils.getTSSec() - this.mStartTime)));
        SystemClock.sleep(1000);
    }

    return Service.START_STICKY;
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    Log.w(TAG, SubTag.msg("onBind"));

    return null;
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.w(TAG, SubTag.msg("onDestroy"));
}

}

您在 onCreate() 中将 mStartTime 设置为 TimeUtils.getTSSec(),这意味着它只会被初始化一次。

之后,onStartCommand() 被调用,但是 mStartTime 时间戳没有被更新,所以 while 循环永远不会运行。

我相信在 while 循环之前将初始化 mStartTime 的行移动到 onStartCommand() 将使您的线程再次挂起。