1 需求
目的:
(1)看看是先执行activity的循环,还是service的循环?
(2)看看service是否会阻塞主线程?
(3)service创建子线程,可以解决阻塞问题
答案:
(1)activity任务优先级大于service,所以,先执行activity的循环,再执行service的循环;
(2)如果不创建子线程,如果service的任务执行时间超过5秒,会阻塞主线程,导致应用ANR,详见下面示例;
(3)service创建子线程,即使有sleep,也不会导致主线程阻塞;
2 接口
3.X 示例:activity 和 service的优先级
答案:先执行activity的循环,再执行service循环
MainActivity.java
package com.dsl.startservice;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnStartService = (Button) findViewById(R.id.btnStartService);
Button btnStopService = (Button) findViewById(R.id.btnStopService);
btnStartService.setOnClickListener(this);
btnStopService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStartService:
startService();
break;
case R.id.btnStopService:
stopService();
break;
default:
break;
}
}
/**
* 目的:
* (1)看看是先执行activity的循环,还是service的循环?
* (2)看看service是否会阻塞主线程?
* (3)service创建子线程,可以解决阻塞问题
* <p>
* 答案:
* (1)activity任务优先级大于service,所以,先执行activity的循环,再执行service的循环;
* (2)如果不创建子线程,如果service的任务执行时间超过5秒,会阻塞主线程,导致应用ANR,详见下面示例;
* (3)service创建子线程,即使有sleep,也不会导致主线程阻塞;
*/
void startService() {
Intent intent = new Intent(this, MyService.class);
startService(intent);
for (int i = 0; i < 10; i++) {
Log.i(TAG, "startService: " + Thread.currentThread().getName() + i);
}
}
void stopService() {
Intent intent = new Intent(this, MyService.class);
stopService(intent);
}
}
MyService.java
package com.dsl.startservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private static final String TAG = "MyService";
public MyService() {
}
@Override
public void onCreate() {
Log.i(TAG, "onCreate: ");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand: ");
for (int i = 0; i < 10; i++) {
Log.i(TAG, "onStartCommand: " + Thread.currentThread().getName() + ": " + i);
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i(TAG, "onDestroy: ");
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
3.2 示例:服务导致应用ANR
MainActivity.java
package com.dsl.startservice;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnStartService = (Button) findViewById(R.id.btnStartService);
Button btnStopService = (Button) findViewById(R.id.btnStopService);
btnStartService.setOnClickListener(this);
btnStopService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStartService:
startService();
break;
case R.id.btnStopService:
stopService();
break;
default:
break;
}
}
/**
* 目的:
* (1)看看是先执行activity的循环,还是service的循环?
* (2)看看service是否会阻塞主线程?
* (3)service创建子线程,可以解决阻塞问题
* <p>
* 答案:
* (1)activity任务优先级大于service,所以,先执行activity的循环,再执行service的循环;
* (2)如果不创建子线程,如果service的任务执行时间超过5秒,会阻塞主线程,导致应用ANR,详见下面示例;
* (3)service创建子线程,即使有sleep,也不会导致主线程阻塞;
*/
void startService() {
Intent intent = new Intent(this, MyService.class);
startService(intent);
for (int i = 0; i < 10; i++) {
Log.i(TAG, "startService: " + Thread.currentThread().getName() + ": " + i);
}
}
void stopService() {
Intent intent = new Intent(this, MyService.class);
stopService(intent);
}
}
MyService.java
package com.dsl.startservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private static final String TAG = "MyService";
public MyService() {
}
@Override
public void onCreate() {
Log.i(TAG, "onCreate: ");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand: ");
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
Log.i(TAG, "onStartCommand: " + Thread.currentThread().getName() + ": " + i);
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i(TAG, "onDestroy: ");
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
运行结果:
/data/anr/traces.txt
3.3 示例:service创建子线程,解决主线程阻塞
MainActivity.java
package com.dsl.startservice;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnStartService = (Button) findViewById(R.id.btnStartService);
Button btnStopService = (Button) findViewById(R.id.btnStopService);
btnStartService.setOnClickListener(this);
btnStopService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStartService:
startService();
break;
case R.id.btnStopService:
stopService();
break;
default:
break;
}
}
/**
* 目的:
* (1)看看是先执行activity的循环,还是service的循环?
* (2)看看service是否会阻塞主线程?
* (3)service创建子线程,可以解决阻塞问题
* <p>
* 答案:
* (1)activity任务优先级大于service,所以,先执行activity的循环,再执行service的循环;
* (2)如果不创建子线程,如果service的任务执行时间超过5秒,会阻塞主线程,导致应用ANR,详见下面示例;
* (3)service创建子线程,即使有sleep,也不会导致主线程阻塞;
*/
void startService() {
Intent intent = new Intent(this, MyService.class);
startService(intent);
for (int i = 0; i < 10; i++) {
Log.i(TAG, "startService: " + Thread.currentThread().getName() + ": " + i);
}
}
void stopService() {
Intent intent = new Intent(this, MyService.class);
stopService(intent);
}
}
MyService.java
package com.dsl.startservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private static final String TAG = "MyService";
public MyService() {
}
@Override
public void onCreate() {
Log.i(TAG, "onCreate: ");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand: ");
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
Log.i(TAG, "onStartCommand: " + Thread.currentThread().getName() + ": " + i);
}
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i(TAG, "onDestroy: ");
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
运行结果: