1 Service了解
主要作用处理一些好事的逻辑,或者执行某些需要长期运行的任务,必要的时候程序退出则Service可以在后台继续保持运行状态
2 Service生命周期 onCreate ,onStartCommand ,onStart , onDestroy
Service开启的时候依次执行 onCreate ,onStartCommand ,onStart
Service 调用stopService 时候执行 onDestroy
bindService方法执行Service中的onBind 方法
unbindService 方法执行Service中的onUnbind 方法
3 Service与线程使用与区别
1 )Service可以脱离Activity独立运行,2)可以运行在后台 3)与主线程是一个线程
有一些东西执行比较耗时,比如下载,但是我下载同时还要做其他事情,这时候使用Service虽然Activity退出了,但是程序依然运行,因为主线程与Service在
一个线程中,会阻碍主线程,这时候可以在Service中启动一个单独的子线程即可
总结:当一个任务需要独立Activity运行,这时候用Service ,Service比较耗时就可以单独启动Thread来使用
4 Service可以是前台Service,也可以做成后台不可见的Service
5 使用
1)类继承Service 2)在主的xml中进行注册 3)Activity开启与使用
代码:
1 Activity
public class ServiceMainActivity extends Activity { //为日志工具设置标签 private static String TAG = "MusicService"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_service_main); Log.d("ServiceMainActivity", "ServiceMainActivity thread id is " + Thread.currentThread().getId()); //输出Toast消息和日志记录 Toast.makeText(this, "ServiceMainActivity", Toast.LENGTH_SHORT).show(); Log.e(TAG, "ServiceMainActivity"); initlizeViews(); } private void initlizeViews(){ Button btnStart = (Button)findViewById(R.id.startMusic); Button btnStop = (Button)findViewById(R.id.stopMusic); Button btnBind = (Button)findViewById(R.id.bindMusic); Button btnUnbind = (Button)findViewById(R.id.unbindMusic); //定义点击监听器 OnClickListener ocl = new OnClickListener() { @Override public void onClick(View v) { //显示指定 intent所指的对象是个 service Intent intent = new Intent( ServiceMainActivity.this ,MusicService.class); switch(v.getId()){ case R.id.startMusic: //开始服务 startService(intent); break; case R.id.stopMusic: //停止服务 stopService(intent); break; case R.id.bindMusic: //绑定服务 bindService(intent, conn, Context.BIND_AUTO_CREATE); break; case R.id.unbindMusic: //解绑服务 unbindService(conn); break; } } }; //绑定点击监听 btnStart.setOnClickListener(ocl); btnStop.setOnClickListener(ocl); btnBind.setOnClickListener(ocl); btnUnbind.setOnClickListener(ocl); } //定义服务链接对象 final ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { Toast.makeText(ServiceMainActivity.this, "ServiceMainActivity onSeviceDisconnected" , Toast.LENGTH_SHORT).show(); Log.e(TAG, "ServiceMainActivity onSeviceDisconnected"); } @Override public void onServiceConnected(ComponentName name, IBinder service) { Toast.makeText(ServiceMainActivity.this, "ServiceMainActivity onServiceConnected" ,Toast.LENGTH_SHORT).show(); Log.e(TAG, "ServiceMainActivity onServiceConnected"); MusicService.MyBinder bind = (MusicService.MyBinder)service; bind.startDownload(); Log.e(TAG, "bind====" +bind); } }; }
2 SERvice
public class MusicService extends Service { //为日志工具设置标签 private static String TAG = "MusicService"; //定义音乐播放器变量 private MediaPlayer mPlayer; public MyBinder myBinder = new MyBinder(); //该服务不存在需要被创建时被调用,不管startService()还是bindService()都会启动时调用该方法 @Override public void onCreate() { Toast.makeText(this, "MusicSevice onCreate()" , Toast.LENGTH_SHORT).show(); Log.e(TAG, "MusicSerice onCreate()"); Log.d("MusicService", "MusicService thread id is " + Thread.currentThread().getId()); //后台的Service使用 mPlayer = MediaPlayer.create(getApplicationContext(),R.raw.ring); // 设置可以重复播放 mPlayer.setLooping(true); //前台的Service使用 Notification notification = new Notification(R.drawable.ic_launcher, "有通知到来", System.currentTimeMillis()); Intent notificationIntent = new Intent(this, ServiceMainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.setLatestEventInfo(this, "这是通知的标题", "这是通知的内容", pendingIntent); startForeground(1, notification); super.onCreate(); } @Override public void onStart(Intent intent, int startId) { Toast.makeText(this, "MusicSevice onStart()" , Toast.LENGTH_SHORT).show(); Log.e(TAG, "MusicSerice onStart()"); mPlayer.start(); super.onStart(intent, startId); } public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "MusicSerice onStartCommand()"); new Thread(new Runnable() { @Override public void run() { // 开始执行后台任务 } }).start(); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { Toast.makeText(this, "MusicSevice onDestroy()" , Toast.LENGTH_SHORT).show(); Log.e(TAG, "MusicSerice onDestroy()"); mPlayer.stop(); super.onDestroy(); } //其他对象通过bindService 方法通知该Service时该方法被调用 @Override public IBinder onBind(Intent intent) { Toast.makeText(this, "MusicSevice onBind()" , Toast.LENGTH_SHORT).show(); Log.e(TAG, "MusicSerice onBind()"); mPlayer.start(); return null; } //其它对象通过unbindService方法通知该Service时该方法被调用 @Override public boolean onUnbind(Intent intent) { Toast.makeText(this, "MusicSevice onUnbind()" , Toast.LENGTH_SHORT).show(); Log.e(TAG, "MusicSerice onUnbind()"); mPlayer.stop(); return super.onUnbind(intent); } //简历与activity的联系类 class MyBinder extends Binder { public void startDownload() { new Thread(new Runnable() { @Override public void run() { // 执行具体的下载任务 } }).start(); Log.d("TAG", "startDownload() executed"); // 执行具体的下载任务 } } }
3 xml布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Welcome to Andy's blog!" android:textSize="16sp"/> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="音乐播放服务"/> <Button android:id="@+id/startMusic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开启音乐播放服务"/> <Button android:id="@+id/stopMusic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="停止音乐播放服务"/> <Button android:id="@+id/bindMusic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="绑定音乐播放服务"/> <Button android:id="@+id/unbindMusic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="解除 ——绑定音乐播放服务"/> </LinearLayout>