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 @Nullable 25 @Override 26 public IBinder onBind(Intent intent) { 27 Log.i(TAG, "============onBind=================="); 28 return mMBinder; 29 } 30 @Override 31 public void onCreate() { 32 super.onCreate(); 33 Log.i(TAG, "============onCreate=================="); 34 mMBinder = new MBinder(); 35 } 36 37 @Override 38 public int onStartCommand(Intent intent, int flags, int startId) { 39 Log.i(TAG, "============onStartCommand=================="); 40 return super.onStartCommand(intent, flags, startId); 41 } 42 43 @Override 44 public void onDestroy() { 45 unBindTarget = true; 46 super.onDestroy(); 47 Log.i(TAG, "============onDestroy=================="); 48 } 49 50 @Override 51 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 @Override 62 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 @Nullable 17 @Override 18 public IBinder onBind(Intent intent) { 19 Log.i(TAG, "============onBind=================="); 20 return null; 21 } 22 23 @Override 24 public void onCreate() { 25 super.onCreate(); 26 Log.i(TAG, "============onCreate=================="); 27 } 28 29 @Override 30 public int onStartCommand(Intent intent, int flags, int startId) { 31 Log.i(TAG, "============onStartCommand=================="); 32 return super.onStartCommand(intent, flags, startId); 33 } 34 35 @Override 36 public void onDestroy() { 37 super.onDestroy(); 38 Log.i(TAG, "============onDestroy=================="); 39 } 40 41 @Override 42 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 @Override 35 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 @Override 53 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 @Override 61 public void onServiceDisconnected(ComponentName componentName) { 62 Log.i(TAG, "=============onServiceDisconnected=================="); 63 IsBinder = false; 64 } 65 }; 66 67 ICallbackResult mICallbackResult = new ICallbackResult(){ 68 @Override 69 public void OnBackResult(Object result) { 70 Log.i(TAG, "=============result=================="); 71 } 72 }; 73 74 @Override 75 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 }
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <service android:name="com.homily.training.service.StartService" /> <service android:name="com.homily.training.service.BindService" /> <activity android:name=".test.service.ServiceMainAct"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 > 7 8 <Button 9 android:id="@+id/startService" 10 android:layout_width="match_parent" 11 android:layout_height="wrap_content" 12 android:text="startService" 13 /> 14 <Button 15 android:id="@+id/closeService" 16 android:layout_width="match_parent" 17 android:layout_height="wrap_content" 18 android:text="closeService" 19 /> 20 21 <Button 22 android:id="@+id/binService" 23 android:layout_width="match_parent" 24 android:layout_height="wrap_content" 25 android:text="binService" 26 /> 27 <Button 28 android:id="@+id/unbinService" 29 android:layout_width="match_parent" 30 android:layout_height="wrap_content" 31 android:text="unbinService" 32 /> 33 34 </LinearLayout>
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后一定能重启。