学习笔记:四大组件之Service理解

来源:互联网 发布:linux创建属性目录命令 编辑:程序博客网 时间:2024/06/06 03:40

一、Service基本概念

1.定义:

  - 后台运行,不可见,无界面

  - 优先级高于Activity  

2.用途

  - 播放音乐、记录地理位置的改变、监听某种动作。。。

3.注意

  - 运行在主线程,不能用它来做耗时请求或动作,否则会出现ANR
  - 可以在Service中开启一个子线程,来做耗时操作


4.生命周期

  - startService
  - bindService








5. 两种Service类型:


Start方式

  - 服务跟启动源没有任何联系

  - 无法得到服务对象

Bind方式:
  - 通过IBinder接口实例的onBind()方法,返回一个Binder对象给启动源


  - 通过onServiceConnected() 方法得到Service对象,并且可以调用Service对象中发方法



二、Start启动方式


1. 定义Service

自定义一个MyStartService去继承Service类。复写其中的onCreate()、onStartCommand()、onDestroy()、onBind(),其中onBind()为抽象方法必须复写,但在Start启动方式中用不上。

第一次启动Service时会首先执行onCreate()方法创建一个Service实例,此方法中可以执行一些初始化操作,接着会执行onStartCommand()方法去执行具体的耗时逻辑,一般做法是开启子线程来处理,停止Service时会调用onDestroy(),回收资源。


2.启动和停止Service

和Activity一样,Service启动也需要Intent。首先需要new一个Intent对象,传入Activity实例和Service类两个参数,然后调用startService(intent)启动Service,此时Service将会执行onCreate()和onStartCommand。停止Service时,只需要调用stopService(intent),便会调用Service中的onDestroy()停止Service。或者也可以在MyStartService代码任意位置调用stopSelf()也会停止该Service


3.优点和缺点

优点:启动简单,可以一直保持后台运行,Activity退出时,不影响该Service运行,直到调用stopService

缺点:Activity与Service不能保持关联,Activity不能调用Service中的数据和方法,Activity启动Service之后,两者没有任何关系,各自执行各自的任务。



三、Bind启动方式


1.在Service中,定义一个DownloadBinder的内部类去继承Binder,定义一些public权限的方法,实现Service实例中的具体业务逻辑,然后复写onBind()方法将DownloadBinder对象返回给Activity使用;


2.在Activity中,创建一个ServiceConnection对象conn,复写onServiceConnected()和onServiceDisconnected()方法。前者在Activity与Service成功绑定时调用,后者在解除绑定时调用。通过onServiceConnected()方法获取Service传过来的DownloadBinder对象,然后执行该对象的逻辑业务。


3.在Activity中,同Start启动方式一样,也是需要先new一个Intent对象,然后调用bindService(intent, conn, BIND_AUTO_CREATE)去绑定Service。其中conn是ServiceConnection对象,BIND_AUTO_CREATE表示Activity和Service在绑定成功后自动调用onCreate()方法去创建Service实例,但不会执行onStartCommand。


4.在Activity中,调用unbindService(intent)解除绑定,将会调用Service中的onDestroy()方法


5.一个Service可以同时调用startService()和bindService(),那么停止时需要调用stopService()和unbindService(),才能停止该Service。



四、IntentService


1.集开启子线程和自动停止Service于一身


2.定义一个MyIntentService类去继承IntentService抽象类,复写onHandleIntent()抽象方法,只需要编写自己的逻辑业务,它会自动开启线程来执行,并且在执行完该方法后自动停止该Service。启动方式同Start方式一样,通过startService(intent)来开启Service,不需要手动停止,IntentService将自动完成。


五、理解误区:

Service是在后台运行,很容易让人联想到子线程,认为Service运行在后台子线程中。事实上,Service与子线程没有关系,和启动它的Activity一样,它也运行在主线程中,只不过,我们在Service中开启子线程来处理耗时业务,防止出现ANR。


六、参考代码


测试Start方式启动的MyStartService

package com.steven.myservicetest;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.support.annotation.Nullable;import android.util.Log;/** * Created by Steven on 2016/9/17. */public class MyBindService extends Service {    private static final String TAG = "Steven";    @Override    public void onCreate() {        super.onCreate();        Log.d(TAG, "onCreate");    }    @Override    public void onDestroy() {        super.onDestroy();        Log.d(TAG, "onDestroyed");    }    //创建一个DownloadBinder实例    private DownloadBinder mBinder = new DownloadBinder();    //定义DownloadBinder去继承Binder类,并实现下载和进度两个方法    class DownloadBinder extends Binder{        public void startDownload(){            Log.d(TAG, "开始下载");        }        public void getProgress(){            Log.d(TAG, "下载进度");        }    }    @Nullable    @Override    //在onBind()方法中将mBinder返回给绑定源使用    public IBinder onBind(Intent intent) {        Log.d(TAG, "onBind");        return mBinder;    }}



测试Bind方式启动的MyBindService
package com.steven.myservicetest;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.support.annotation.Nullable;import android.util.Log;/** * Created by Steven on 2016/9/17. */public class MyBindService extends Service {    private static final String TAG = "Steven";    @Override    public void onCreate() {        super.onCreate();        Log.d(TAG, "onCreate");    }    @Override    public void onDestroy() {        super.onDestroy();        Log.d(TAG, "onDestroyed");    }    //创建一个DownloadBinder实例    private DownloadBinder mBinder = new DownloadBinder();    //定义DownloadBinder去继承Binder类,并实现下载和进度两个方法    class DownloadBinder extends Binder{        public void startDownload(){            Log.d(TAG, "开始下载");        }        public void getProgress(){            Log.d(TAG, "下载进度");        }    }    @Nullable    @Override    //在onBind()方法中将mBinder返回给绑定源使用    public IBinder onBind(Intent intent) {        Log.d(TAG, "onBind");        return mBinder;    }}




测试IntentService类型的MyIntentService
package com.steven.myservicetest;import android.app.IntentService;import android.content.Intent;import android.util.Log;/** * Created by Steven on 2016/9/17. */public class MyIntentService extends IntentService {    private static final String TAG = "Steven";    public MyIntentService(){        super("My IntentService");    }    //系统开启线程处理耗时逻辑,处理完之后自动调用onDestroy()关闭Service    @Override    protected void onHandleIntent(Intent intent) {        Log.d(TAG, "Thread id is " + Thread.currentThread().getId());    }    @Override    public void onDestroy() {        super.onDestroy();        Log.d(TAG, "onDestroy");    }}




MainActivity去启动三种Service
package com.steven.myservicetest;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;public class MainActivity extends AppCompatActivity implements View.OnClickListener{    private Button startService;    private Button stopService;    private Button bindService;    private Button unbindService;    private Button startIntentService;    private MyBindService.DownloadBinder downloadBinder;    private static final String TAG = "Steven";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //start/stop Service        startService = (Button)findViewById(R.id.btn_start_service);        startService.setOnClickListener(this);        stopService = (Button)findViewById(R.id.btn_stop_service);        stopService.setOnClickListener(this);        //bind/unbind Service        bindService = (Button)findViewById(R.id.btn_bind_service);        bindService.setOnClickListener(this);        unbindService = (Button)findViewById(R.id.btn_unbind_service);        unbindService.setOnClickListener(this);        //intentService        startIntentService = (Button)findViewById(R.id.btn_start_intent_service);        startIntentService.setOnClickListener(this);    }    //创建ServiceConnection实例,实现两个方法    private ServiceConnection connection = new ServiceConnection() {        //绑定源与Service成功绑定时被调用        @Override        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {            downloadBinder = (MyBindService.DownloadBinder)iBinder; //获取从Service中onBind()方法中返回的IBinder实例            //调用Service中downloadBinder的两个方法            downloadBinder.startDownload();            downloadBinder.getProgress();        }        //绑定源与Service解除绑定时被回调        @Override        public void onServiceDisconnected(ComponentName componentName) {        }    };    @Override    public void onClick(View view) {        switch (view.getId()){            case R.id.btn_start_service:                Intent startIntent = new Intent(this, MyStartService.class);                startService(startIntent);      //启动Service                break;            case R.id.btn_stop_service:                Intent stopIntent = new Intent(this, MyStartService.class);                stopService(stopIntent);        //停止Service                break;            case R.id.btn_bind_service:                Intent bindIntent = new Intent(this, MyBindService.class);                bindService(bindIntent, connection, BIND_AUTO_CREATE);  //bind Service                break;            case R.id.btn_unbind_service:                unbindService(connection);      //unbind Service                break;            case R.id.btn_start_intent_service:                Log.d(TAG, "Thread id is " + Thread.currentThread().getId());                Intent intentService = new Intent(this, MyIntentService.class);                startService(intentService);            default:                break;        }    }}


Service同其他四大组件一样需要在AndroidManifest.xml文件中声明

<span style="font-size:18px;"><activity android:name=".MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <service            android:name=".MyStartService">        </service>        <service            android:name=".MyBindService">        </service>        <service            android:name=".MyIntentService">        </service></span>



界面如下:














0 0
原创粉丝点击