1 package com.homily.training.service; 2 3 import android.app.Service; 4 import android.content.Intent; 5 import android.os.Binder; 6 import android.os.IBinder; 7 import android.support.annotation.Nullable; 8 import android.util.Log; 9 10 import com.homily.training.test.service.ICallbackResult;11 12 /**13 * Created by Rubert on 2016/7/6.14 */15 public class BindService extends Service{16 17 private final static String TAG = BindService.class.getSimpleName();18 19 private MBinder mMBinder;20 private ICallbackResult mICallbackResult;21 private boolean unBindTarget = false;22 23 24 @Nullable25 @Override26 public IBinder onBind(Intent intent) {27 Log.i(TAG, "============onBind==================");28 return mMBinder;29 }30 @Override31 public void onCreate() {32 super.onCreate();33 Log.i(TAG, "============onCreate==================");34 mMBinder = new MBinder();35 }36 37 @Override38 public int onStartCommand(Intent intent, int flags, int startId) {39 Log.i(TAG, "============onStartCommand==================");40 return super.onStartCommand(intent, flags, startId);41 }42 43 @Override44 public void onDestroy() {45 unBindTarget = true;46 super.onDestroy();47 Log.i(TAG, "============onDestroy==================");48 }49 50 @Override51 public boolean onUnbind(Intent intent) {52 Log.i(TAG, "============onUnbind==================");53 unBindTarget = true;//该处代码需要这么写是因为,Service中开启了线程。如果该Service直接onUnbind了,但是线程没有停止,并且如果再次bind该Service时,程序会再次重新实例化一个线程,并之前的线程也会一直运行下去,除非该app销毁。54 return super.onUnbind(intent);55 }56 57 public class MBinder extends Binder {58 public void start(){59 Log.i(TAG, "============MBinder-start==================");60 new Thread(new Runnable() {61 @Override62 public void run() {63 64 while (true) {65 if(unBindTarget) {66 break;67 }68 Log.i(TAG, Thread.currentThread().getName() + "============MBinder-start-run==================");69 mICallbackResult.OnBackResult(null);70 try {71 Thread.currentThread().sleep(5000);72 } catch (InterruptedException e) {73 e.printStackTrace();74 }75 }76 }77 }).start();78 }79 80 public void bind(ICallbackResult result) {81 mICallbackResult = result;82 }83 84 }85 86 87 }
1 package com.homily.training.service; 2 3 import android.app.Service; 4 import android.content.Intent; 5 import android.os.IBinder; 6 import android.support.annotation.Nullable; 7 import android.util.Log; 8 9 /**10 * Created by Rubert on 2016/7/6.11 */12 public class StartService extends Service{13 14 private final static String TAG = StartService.class.getSimpleName();15 16 @Nullable17 @Override18 public IBinder onBind(Intent intent) {19 Log.i(TAG, "============onBind==================");20 return null;21 }22 23 @Override24 public void onCreate() {25 super.onCreate();26 Log.i(TAG, "============onCreate==================");27 }28 29 @Override30 public int onStartCommand(Intent intent, int flags, int startId) {31 Log.i(TAG, "============onStartCommand==================");32 return super.onStartCommand(intent, flags, startId);33 }34 35 @Override36 public void onDestroy() {37 super.onDestroy();38 Log.i(TAG, "============onDestroy==================");39 }40 41 @Override42 public boolean onUnbind(Intent intent) {43 Log.i(TAG, "============onUnbind==================");44 return super.onUnbind(intent);45 }46 }
1 package com.homily.training.test.service; 2 3 import android.app.Activity; 4 import android.content.ComponentName; 5 import android.content.Context; 6 import android.content.Intent; 7 import android.content.ServiceConnection; 8 import android.os.Binder; 9 import android.os.Bundle;10 import android.os.IBinder;11 import android.util.Log;12 import android.view.View;13 import android.widget.Button;14 15 import com.homily.training.R;16 import com.homily.training.service.BindService;17 import com.homily.training.service.StartService;18 19 /**20 * Created by Rubert on 2016/7/6.21 * 主要验证startService 启动后再次启动;以及bindService绑定后,解绑再次绑定的情况。22 */23 public class ServiceMainAct extends Activity implements View.OnClickListener{24 25 private final static String TAG = ServiceMainAct.class.getSimpleName();26 27 Button startServiceBtn;28 Button closeServiceBtn;29 Button bindServiceBtn;30 Button unbindServiceBtn;31 BindService.MBinder mMBinder;32 boolean IsBinder = false;33 34 @Override35 protected void onCreate(Bundle savedInstanceState) {36 super.onCreate(savedInstanceState);37 setContentView(R.layout.service_layout);38 startServiceBtn = (Button)findViewById(R.id.startService);39 closeServiceBtn = (Button)findViewById(R.id.closeService);40 bindServiceBtn = (Button)findViewById(R.id.binService);41 unbindServiceBtn = (Button)findViewById(R.id.unbinService);42 43 startServiceBtn.setOnClickListener(this);44 closeServiceBtn.setOnClickListener(this);45 bindServiceBtn.setOnClickListener(this);46 unbindServiceBtn.setOnClickListener(this);47 }48 49 50 51 ServiceConnection mConnection = new ServiceConnection(){52 @Override53 public void onServiceConnected(ComponentName componentName, IBinder iBinder) {54 Log.i(TAG, "=============onServiceConnected==================");55 mMBinder = (BindService.MBinder)iBinder;56 mMBinder.bind(mICallbackResult);57 mMBinder.start();58 IsBinder = true;59 }60 @Override61 public void onServiceDisconnected(ComponentName componentName) {62 Log.i(TAG, "=============onServiceDisconnected==================");63 IsBinder = false;64 }65 };66 67 ICallbackResult mICallbackResult = new ICallbackResult(){68 @Override69 public void OnBackResult(Object result) {70 Log.i(TAG, "=============result==================");71 }72 };73 74 @Override75 public void onClick(View view) {76 switch (view.getId()) {77 case R.id.startService:78 Intent sintent = new Intent(ServiceMainAct.this, StartService.class);79 startService(sintent);80 break;81 case R.id.closeService:82 Intent cintent = new Intent(ServiceMainAct.this, StartService.class);83 stopService(cintent);84 break;85 case R.id.binService:86 Intent service = new Intent(ServiceMainAct.this, BindService.class);87 bindService(service, mConnection, Context.BIND_AUTO_CREATE);88 break;89 case R.id.unbinService:90 if(mConnection != null && IsBinder)91 unbindService(mConnection);92 break;93 }94 95 }96 97 98 99 }
1 package com.homily.training.test.service;2 3 /**4 * Created by Rubert on 2016/7/6.5 */6 public interface ICallbackResult {7 void OnBackResult(Object result);8 }
1 27 8 14 20 21 27 33 34
Android开发的过程中,每次调用startService(Intent)的时候,都会调用该Service对象的onStartCommand(Intent,int,int)方法,然后在onStartCommand方法中做一些处理。然后我们注意到这个函数有一个int的返回值,这篇文章就是简单地讲讲int返回值的作用。
从Android官方文档中,我们知道onStartCommand有4种返回值:
START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY: START_STICKY的兼容版本,但不保证服务被kill后一定能重启。