为什么 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()
将使您的线程再次挂起。
为了了解 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()
将使您的线程再次挂起。