参考:http://blog.csdn.net/pi9nc/article/details/18764415
Service要执行onCreate()、onStartCommand()和onDestroy()方法,Service是运行在主线程里。
构建Intent对象,调用startService()方法和stopService()方法来启动和停止Service
注意:项目中的每一个Service都必须在AndroidManifest.xml中注册才行,
<Service android:name-""> </Service>
当启动一个Service的时候,会调用该Service中的onCreate()和onStartCommand()方法。
onCreate()方法只会在Service第一次被创建的时候调用,如果当前Service已经被创建过了,不管怎样调用startService()方法,onCreate()方法都不会再执行,只会执行onStartCommand()方法
Service和Activity的通信:
1、Service 里有onBind()方法 ,这个方法是用于和Activity建立关联的
2、Activity里首先创建一个ServiceConnection的匿名类,里面重写了onServiceConnected()方法和onServiceDisconnected()方法,这两个方法分别会在Activity与Service建立关联和解除关联的时候调用。
3、在onServiceConnected()方法中,把service赋值为 MyBinder的实例对象
4、在点击事件中,构建出一个Intent对象,然后调用bindService()方法将Activity和Service进行绑定。
bindService()方法接收三个参数,第一个参数就是刚刚构建出的Intent对象,第二个参数是前面创建出的ServiceConnection的实例,第三个参数是一个标志位,这里传入BIND_AUTO_CREATE表示在Activity和Service建立关联后自动创建Service,这会使得MyService中的onCreate()方法得到执行,但onStartCommand()方法不会执行。
5、如果想解除ctivity和Service之间的关联,调用一下unbindService()方法就可以了。
注意:任何一个Service在整个应用程序范围内都是通用的,即MyService不仅可以和MainActivity建立关联,还可以和任何一个Activity建立关联,而且在建立关联时它们都可以获取到相同的MyBinder实例。
实例:
Service 文件:
public class MyService extends Service { public static final String TAG="MyService"; private MyBinder mBinder=new MyBinder(); @Override public void onCreate() { Log.e(TAG,"onCreate() executed"); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG,"onStartCommand() executed"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { Log.e(TAG,"onDestroy() executed"); super.onDestroy(); } @Override public IBinder onBind(Intent intent) { return mBinder; } class MyBinder extends Binder{ public void startDownload(){ Log.e(TAG,"开始下载....."); } } }
Activity 文件:
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private Button button; private MyService.MyBinder myBinder; private ServiceConnection connection=new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { myBinder= (MyService.MyBinder) service; myBinder.startDownload(); } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button= (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(MainActivity.this,MyService.class); bindService(intent,connection,BIND_AUTO_CREATE); } }); Log.e(TAG, "start onCreate~~~"); } }
Service的销毁:
1、先执行startService()方法,再执行stopService()方法,Service就销毁了
2、先执行bindService()方法,再执行unbindService()方法,Service就销毁了
3、执行了startService()方法,又执行了bindService()方法,stopService()和unbindService()两个方法必须都执行才能销毁Service,执行其中的一个都不能销毁Service。
注:我们要记得在Service的onDestroy()方法里去清理掉那些不再使用的资源,防止在Service被销毁后还会有一些不再使用的对象仍占用着内存。
Service与Thread的关系:
Service里要创建一个子线程,因为所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。
标准的Service:
@Override public int onStartCommand(Intent intent, int flags, int startId) { new Thread(new Runnable() { @Override public void run() { // 开始执行后台任务 } }).start(); return super.onStartCommand(intent, flags, startId); } class MyBinder extends Binder { public void startDownload() { new Thread(new Runnable() { @Override public void run() { // 执行具体的下载任务 } }).start(); } }创建前台Service: 在Service中onCreate()方法中创建一个Notification对象,然后调用setLatestEventInfo()方法来为通知初始化布局和数据,并在这里设置了点击通知后就打开MainActivity。然后调用startForeground()方法就可以让Service变成一个前台Service,并会将通知的图片显示出来。 例如:
@Override public void onCreate() { Log.e(TAG,"onCreate() executed"); Log.d("MyService", "MyService thread id is " + Thread.currentThread().getId()); super.onCreate(); Intent builderIntent=new Intent(this,MainActivity.class); PendingIntent pendingIntent=PendingIntent.getActivity(this,0,builderIntent,0); Notification.Builder builder=new Notification.Builder(this) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("这是通知的标题") .setContentText("这是通知的内容") .setWhen(System.currentTimeMillis()) .setContentIntent(pendingIntent); Notification notification=builder.getNotification(); startForeground(1,notification); }远程Service: