Android四大组件之服务-Service 原理和应用开发详解
一、Android 服务简介
Service是android 系统中的四大组件之一(Activity、Service、BroadcastReceiver、ContentProvider),它跟Activity的级别差不多,但不能自己运行只能后台运行,并且可以和其他组件进行交互。service可以在很多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务总是藏在后台的。
Service的启动有两种方式:context.startService() 和 context.bindService()
二、原理和流程
1.创建前台服务,只需要提供一个通知栏图标并且调用startForeground即可。
2.想让服务做自己的想做的事情,也比较简单,只需要在onCreate或者onStartConmand的时候new一个Thread即可
3.如果Activity等UI想要和服务通信、调用服务提供的方法,怎么办呢?这时候就需要用到Binder了:只需要在onBind的时候返回一个IBinder对象,通过该对象可以获取当前Service的对象引用,这样就可以操作服务所提供的方法了,那如何在Service操作Acitivty呢?
有了Service引用,这个时候只需要在Service中给Activity开放设置回调接口即可。
4.当然了,服务需要在Manifest.xml中进行配置声明:
<service android:name="com.czm.servicetest.MyService" > </service>
三、实例:MyService.java
package com.czm.servicetest; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; /** * The Service Example * @author caizhiming * */ public class MyService extends Service{ IBinder mBinder = new MyBinder(); private int mCount = 0; public boolean mIsStop = false; // get the instance of MyService public class MyBinder extends Binder{ MyService getService(){ return MyService.this; } } public void setData(int data){ mCount = data; } public int getData(){ return mCount; } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); Thread thread = new Thread(null, new ServiceWorker(), "ServiceWorker"); thread.start(); } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub Log.v("czm","onBind()-service is started"); return mBinder; } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub Log.v("czm","onStartCommand()-service is started"); return super.onStartCommand(intent, flags, startId); } //The Service work's thread class ServiceWorker implements Runnable{ @Override public void run() { // TODO Auto-generated method stub while(!mIsStop){ Log.v("czm","ServiceWorker: mCount="+mCount); mCount ++; if(mCount >= 10000){ mCount = 0; } if(mCount %5 == 0){ mListener.onCallback(); } try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } //The callback listener to operate UI such as Activity private OnUICallbackListener mListener; public void setListener(OnUICallbackListener listener){ mListener = listener; } public interface OnUICallbackListener{ void onCallback(); } }
四、如何使用服务-MyService?
package com.czm.servicetest; import com.czm.servicetest.MyService.MyBinder; import com.czm.servicetest.MyService.OnUICallbackListener; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity implements OnUICallbackListener{ private Button mBtnStart; private Button mBtnChange; private Button mBtnStop; private TextView mTvResult; private MyService mMyService; Intent serviceIntent; private Handler mHandler = new Handler(){ public void handleMessage(Message msg) { mTvResult.setText(String.valueOf(mMyService.getData())); mHandler.sendEmptyMessageDelayed(0, 1000); }; }; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub Log.v("czm","onServiceDisconnected()"); } @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub Log.v("czm","onServiceConnected()"); MyBinder binder = (MyBinder) service; mMyService = binder.getService(); mMyService.setListener(MainActivity.this); mHandler.sendEmptyMessageDelayed(0, 0); } }; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtnStart = (Button)findViewById(R.id.btn_start); mBtnChange = (Button)findViewById(R.id.btn_change); mBtnStop = (Button)findViewById(R.id.btn_stop); mTvResult = (TextView)findViewById(R.id.tv_result); mBtnStart.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub //start service serviceIntent = new Intent(MainActivity.this,MyService.class); serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //bind service in order to communicate with service MainActivity.this.bindService(serviceIntent, mServiceConnection, BIND_AUTO_CREATE); // startService(serviceIntent); } }); mBtnChange.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub mMyService.setData(1000); } }); mBtnStop.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub mMyService.mIsStop = true; MainActivity.this.unbindService(mServiceConnection); stopService(serviceIntent); } }); } /** * service callback * @param serviceConnection */ @Override public void onCallback() { // TODO Auto-generated method stub runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub Toast.makeText(MainActivity.this, "service callback", Toast.LENGTH_SHORT).show(); } }); } }