Service生命周期.png 第一种方式:通过StartService启动Service通过startService启动后,service会一直无限期运行下去,只有外部调用了stopService()或stopSelf()方法时,该Service才会停止运行并销毁。 要创建一个这样的Service,你需要让该类继承Service类,然后重写以下方法:
这几个方法都是回调方法,且在主线程中执行,由android操作系统在合适的时机调用。 startService代码实例创建TestOneService,并在manifest里注册。 /** * Created by Kathy on 17-2-6. */public class TestOneService extends Service{ @Override public void onCreate() { Log.i("Kathy","onCreate - Thread ID = " + Thread.currentThread().getId()); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("Kathy", "onStartCommand - startId = " + startId + ", Thread ID = " + Thread.currentThread().getId()); return super.onStartCommand(intent, flags, startId); } @Nullable @Override public IBinder onBind(Intent intent) { Log.i("Kathy", "onBind - Thread ID = " + Thread.currentThread().getId()); return null; } @Override public void onDestroy() { Log.i("Kathy", "onDestroy - Thread ID = " + Thread.currentThread().getId()); super.onDestroy(); } } 在MainActivity中三次startService,之后stopService。 /** * Created by Kathy on 17-2-6. */public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i("Kathy", "Thread ID = " + Thread.currentThread().getId()); Log.i("Kathy", "before StartService"); //连续启动Service Intent intentOne = new Intent(this, TestOneService.class); startService(intentOne); Intent intentTwo = new Intent(this, TestOneService.class); startService(intentTwo); Intent intentThree = new Intent(this, TestOneService.class); startService(intentThree); //停止Service Intent intentFour = new Intent(this, TestOneService.class); stopService(intentFour); //再次启动Service Intent intentFive = new Intent(this, TestOneService.class); startService(intentFive); Log.i("Kathy", "after StartService"); } } 打印出的Log如下: 02-06 15:19:45.090 8938-8938/? I/Kathy: Thread ID = 1 02-06 15:19:45.090 8938-8938/? I/Kathy: before StartService 02-06 15:19:45.233 8938-8938/? I/Kathy: onCreate - Thread ID = 1 02-06 15:19:45.234 8938-8938/? I/Kathy: onStartCommand - startId = 1, Thread ID = 1 02-06 15:19:45.234 8938-8938/? I/Kathy: onStartCommand - startId = 2, Thread ID = 1 02-06 15:19:45.235 8938-8938/? I/Kathy: onStartCommand - startId = 3, Thread ID = 1 02-06 15:19:45.236 8938-8938/? I/Kathy: onDestroy - Thread ID = 1 02-06 15:19:45.237 8938-8938/? I/Kathy: onCreate - Thread ID = 1 02-06 15:19:45.237 8938-8938/? I/Kathy: onStartCommand - startId = 1, Thread ID = 1 02-06 15:19:45.238 8938-8938/? I/Kathy: after StartService 分析: 第二种方式:通过bindService启动ServicebindService启动服务特点: bindService代码实例交互界面设计如下: ActivityA界面布局.png ActivityB界面布局.png 1.创建一个TestTwoService继承Service(Server) TestTwoService创建如下: /** * Created by Kathy on 17-2-6. */public class TestTwoService extends Service{ //client 可以通过Binder获取Service实例 public class MyBinder extends Binder { public TestTwoService getService() { return TestTwoService.this; } } //通过binder实现调用者client与Service之间的通信 private MyBinder binder = new MyBinder(); private final Random generator = new Random(); @Override public void onCreate() { Log.i("Kathy","TestTwoService - onCreate - Thread = " + Thread.currentThread().getName()); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("Kathy", "TestTwoService - onStartCommand - startId = " + startId + ", Thread = " + Thread.currentThread().getName()); return START_NOT_STICKY; } @Nullable @Override public IBinder onBind(Intent intent) { Log.i("Kathy", "TestTwoService - onBind - Thread = " + Thread.currentThread().getName()); return binder; } @Override public boolean onUnbind(Intent intent) { Log.i("Kathy", "TestTwoService - onUnbind - from = " + intent.getStringExtra("from")); return false; } @Override public void onDestroy() { Log.i("Kathy", "TestTwoService - onDestroy - Thread = " + Thread.currentThread().getName()); super.onDestroy(); } //getRandomNumber是Service暴露出去供client调用的公共方法 public int getRandomNumber() { return generator.nextInt(); } } client端要做的事情: 创建ActivityA,代码如下: /** * Created by Kathy on 17-2-6. */public class ActivityA extends Activity implements Button.OnClickListener { private TestTwoService service = null; private boolean isBind = false; private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder binder) { isBind = true; TestTwoService.MyBinder myBinder = (TestTwoService.MyBinder) binder; service = myBinder.getService(); Log.i("Kathy", "ActivityA - onServiceConnected"); int num = service.getRandomNumber(); Log.i("Kathy", "ActivityA - getRandomNumber = " + num); } @Override public void onServiceDisconnected(ComponentName name) { isBind = false; Log.i("Kathy", "ActivityA - onServiceDisconnected"); } }; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_a); Log.i("Kathy", "ActivityA - onCreate - Thread = " + Thread.currentThread().getName()); findViewById(R.id.btnBindService).setOnClickListener(this); findViewById(R.id.btnUnbindService).setOnClickListener(this); findViewById(R.id.btnStartActivityB).setOnClickListener(this); findViewById(R.id.btnFinish).setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.btnBindService) { //单击了“bindService”按钮 Intent intent = new Intent(this, TestTwoService.class); intent.putExtra("from", "ActivityA"); Log.i("Kathy", "----------------------------------------------------------------------"); Log.i("Kathy", "ActivityA 执行 bindService"); bindService(intent, conn, BIND_AUTO_CREATE); } else if (v.getId() == R.id.btnUnbindService) { //单击了“unbindService”按钮 if (isBind) { Log.i("Kathy", "----------------------------------------------------------------------"); Log.i("Kathy", "ActivityA 执行 unbindService"); unbindService(conn); } } else if (v.getId() == R.id.btnStartActivityB) { //单击了“start ActivityB”按钮 Intent intent = new Intent(this, ActivityB.class); Log.i("Kathy", "----------------------------------------------------------------------"); Log.i("Kathy", "ActivityA 启动 ActivityB"); startActivity(intent); } else if (v.getId() == R.id.btnFinish) { //单击了“Finish”按钮 Log.i("Kathy", "----------------------------------------------------------------------"); Log.i("Kathy", "ActivityA 执行 finish"); this.finish(); } } @Override protected void onDestroy() { super.onDestroy(); Log.i("Kathy", "ActivityA - onDestroy"); } } 创建ActivityB,代码如下: /** * Created by Kathy on 17-2-6. */public class ActivityB extends Activity implements Button.OnClickListener { private TestTwoService service = null; private boolean isBind = false; private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder binder) { isBind = true; TestTwoService.MyBinder myBinder = (TestTwoService.MyBinder)binder; service = myBinder.getService(); Log.i("Kathy", "ActivityB - onServiceConnected"); int num = service.getRandomNumber(); Log.i("Kathy", "ActivityB - getRandomNumber = " + num); } @Override public void onServiceDisconnected(ComponentName name) { isBind = false; Log.i("Kathy", "ActivityB - onServiceDisconnected"); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_b); findViewById(R.id.btnBindService).setOnClickListener(this); findViewById(R.id.btnUnbindService).setOnClickListener(this); findViewById(R.id.btnFinish).setOnClickListener(this); } @Override public void onClick(View v) { if(v.getId() == R.id.btnBindService){ //单击了“bindService”按钮 Intent intent = new Intent(this, TestTwoService.class); intent.putExtra("from", "ActivityB"); Log.i("Kathy", "----------------------------------------------------------------------"); Log.i("Kathy", "ActivityB 执行 bindService"); bindService(intent, conn, BIND_AUTO_CREATE); }else if(v.getId() == R.id.btnUnbindService){ //单击了“unbindService”按钮 if(isBind){ Log.i("Kathy", "----------------------------------------------------------------------"); Log.i("Kathy", "ActivityB 执行 unbindService"); unbindService(conn); } }else if(v.getId() == R.id.btnFinish){ //单击了“Finish”按钮 Log.i("Kathy", "----------------------------------------------------------------------"); Log.i("Kathy", "ActivityB 执行 finish"); this.finish(); } } @Override public void onDestroy(){ super.onDestroy(); Log.i("Kathy", "ActivityB - onDestroy"); } } 测试步骤1step1: 点击ActivityA的bindService按钮 02-07 14:09:38.031 1738-1738/com.demo.kathy.demo I/Kathy: ActivityA - onCreate - Thread = main02-07 14:09:39.488 1738-1738/com.demo.kathy.demo I/Kathy: ----------------------------------------------------------------------02-07 14:09:39.488 1738-1738/com.demo.kathy.demo I/Kathy: ActivityA 执行 bindService02-07 14:09:39.496 1738-1738/com.demo.kathy.demo I/Kathy: TestTwoService - onCreate - Thread = main02-07 14:09:39.497 1738-1738/com.demo.kathy.demo I/Kathy: TestTwoService - onBind - Thread = main02-07 14:09:39.500 1738-1738/com.demo.kathy.demo I/Kathy: ActivityA - onServiceConnected02-07 14:09:39.500 1738-1738/com.demo.kathy.demo I/Kathy: ActivityA - getRandomNumber = -104698737602-07 14:09:50.866 1738-1738/com.demo.kathy.demo I/Kathy: ----------------------------------------------------------------------02-07 14:09:50.866 1738-1738/com.demo.kathy.demo I/Kathy: ActivityA 执行 unbindService02-07 14:09:50.870 1738-1738/com.demo.kathy.demo I/Kathy: TestTwoService - onUnbind - from = ActivityA02-07 14:09:50.871 1738-1738/com.demo.kathy.demo I/Kathy: TestTwoService - onDestroy - Thread = main 总结调用bindService之后发生的事情: 总结调用unbindService之后发生的事情: 测试步骤2step1: 点击ActivityA的bindService按钮 02-07 14:49:16.626 12566-12566/com.demo.kathy.demo I/Kathy: ActivityA - onCreate - Thread = main02-07 14:49:18.102 12566-12566/com.demo.kathy.demo I/Kathy: ----------------------------------------------------------------------02-07 14:49:18.102 12566-12566/com.demo.kathy.demo I/Kathy: ActivityA 执行 bindService02-07 14:49:18.105 12566-12566/com.demo.kathy.demo I/Kathy: TestTwoService - onCreate - Thread = main02-07 14:49:18.110 12566-12566/com.demo.kathy.demo I/Kathy: TestTwoService - onBind - Thread = main02-07 14:49:18.112 12566-12566/com.demo.kathy.demo I/Kathy: ActivityA - onServiceConnected02-07 14:49:18.112 12566-12566/com.demo.kathy.demo I/Kathy: ActivityA - getRandomNumber = -31839988602-07 14:49:19.540 12566-12566/com.demo.kathy.demo I/Kathy: ----------------------------------------------------------------------02-07 14:49:19.540 12566-12566/com.demo.kathy.demo I/Kathy: ActivityA 执行 finish02-07 14:49:19.789 12566-12566/com.demo.kathy.demo I/Kathy: ActivityA - onDestroy02-07 14:49:19.798 12566-12566/com.demo.kathy.demo I/Kathy: TestTwoService - onUnbind - from = ActivityA02-07 14:49:19.798 12566-12566/com.demo.kathy.demo I/Kathy: TestTwoService - onDestroy - Thread = main 总结:如果client销毁,那么client会自动与Service解除绑定。 测试步骤3step1: 点击ActivityA的bindService按钮 02-07 14:55:04.390 12566-12566/com.demo.kathy.demo I/Kathy: ActivityA - onCreate - Thread = main02-07 14:55:08.191 12566-12566/com.demo.kathy.demo I/Kathy: ----------------------------------------------------------------------02-07 14:55:08.191 12566-12566/com.demo.kathy.demo I/Kathy: ActivityA 执行 bindService02-07 14:55:08.197 12566-12566/com.demo.kathy.demo I/Kathy: TestTwoService - onCreate - Thread = main02-07 14:55:08.198 12566-12566/com.demo.kathy.demo I/Kathy: TestTwoService - onBind - Thread = main02-07 14:55:08.205 12566-12566/com.demo.kathy.demo I/Kathy: ActivityA - onServiceConnected02-07 14:55:08.205 12566-12566/com.demo.kathy.demo I/Kathy: ActivityA - getRandomNumber = -70621554202-07 14:55:23.261 12566-12566/com.demo.kathy.demo I/Kathy: ----------------------------------------------------------------------02-07 14:55:23.261 12566-12566/com.demo.kathy.demo I/Kathy: ActivityA 启动 ActivityB02-07 14:55:29.239 12566-12566/com.demo.kathy.demo I/Kathy: ----------------------------------------------------------------------02-07 14:55:29.239 12566-12566/com.demo.kathy.demo I/Kathy: ActivityB 执行 bindService02-07 14:55:29.241 12566-12566/com.demo.kathy.demo I/Kathy: ActivityB - onServiceConnected02-07 14:55:29.241 12566-12566/com.demo.kathy.demo I/Kathy: ActivityB - getRandomNumber = 182757272602-07 14:55:33.951 12566-12566/com.demo.kathy.demo I/Kathy: ----------------------------------------------------------------------02-07 14:55:33.951 12566-12566/com.demo.kathy.demo I/Kathy: ActivityB 执行 unbindService02-07 14:55:36.645 12566-12566/com.demo.kathy.demo I/Kathy: ----------------------------------------------------------------------02-07 14:55:36.645 12566-12566/com.demo.kathy.demo I/Kathy: ActivityB 执行 finish02-07 14:55:36.852 12566-12566/com.demo.kathy.demo I/Kathy: ActivityB - onDestroy02-07 14:55:43.137 12566-12566/com.demo.kathy.demo I/Kathy: ----------------------------------------------------------------------02-07 14:55:43.137 12566-12566/com.demo.kathy.demo I/Kathy: ActivityA 执行 unbindService02-07 14:55:43.143 12566-12566/com.demo.kathy.demo I/Kathy: TestTwoService - onUnbind - from = ActivityA02-07 14:55:43.143 12566-12566/com.demo.kathy.demo I/Kathy: TestTwoService - onDestroy - Thread = main 总结bindService的生命周期: 2.点击ActivityB中的bindService按钮 3.点击ActivityB中的unbindService按钮 4.点击ActivityA中的unbindService按钮 如何保证Service不被杀死?1. onStartCommand方式中,返回START_STICKY 首先我们来看看onStartCommand都可以返回哪些值: 调用Context.startService方式启动Service时,如果Android面临内存匮乏,可能会销毁当前运行的Service,待内存充足时可以重建Service。而Service被Android系统强制销毁并再次重建的行为依赖于Service的onStartCommand()方法的返回值。
2.提高Service的优先级 3.提升Service进程的优先级 当系统进程空间紧张时,会依照优先级自动进行进程的回收。
4.在onDestroy方法里重启Service 5.系统广播监听Service状态 |
|