Service基础篇

Service(服务)是一个没有用户界面的在后台运行执行耗时操作的应用组件。其他应用组件能够启动Service,并且当用户切换到另外的应用场景,Service将持续在后台运行。另外,一个组件能够绑定到一个service与之交互(IPC机制)。首先明确一点,尽管Service是进行后台计算的,但它仍然是运行在主线程中,处理耗时造作仍然需要在子线程处理。

Service的分类,根据调用者和service在不在同一个进程里,Service可以分为:本地服务(LocalService)、远程服务(RemoteService)。

它的作用:1.耗时操作的执行:ANR对Activity和BroadcastReceiver响应时间的限制(Activity对事件响应不超过5秒,BroadcastReceiver执行不超过10秒),使得在其中都不适合执行较耗时操作,这样像网络、数据库、复杂计算这类耗时操作的执行就需要一个组件来承担。Service作为Android四大组件之一,其功能之一就是耗时操作的执行另外相对于Thread的耗时操作。

2.Service的可控性。任何 Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例。Service可以在任何有 Context 的地方调用 Context.startService、Context.stopService、Context.bindService,Context.unbindService,来控制它,你也可以在 Service 里注册 BroadcastReceiver,在其他地方通过发送 broadcast 来控制它,而新产生的Thread在销毁了它的Activity仍然可以运行,但已经没有办法对这可Thread操控。。

3.应用内或应用间数据通信(IPC通信):Android每个应用程序都在自己的dalvik虚拟机中运行,一个应用是不允许访问其他应用的内存信息的,为此Android引入了Content Provider在不同应用间共享数据,BroadcastReceiver广播信息给不同应用程序,但Content Provider更多用于数据的共享,BroadcastReceiver广播的信息会被所有应用接收较耗费系统资源,对于两个应用间动态的进行交互还需要通过Service来完成。

本地服务(LocalService)

调用者和service在同一个进程里,所以运行在主进程的main线程中。所以不能进行耗时操作,可以采用在service里面创建一个Thread来执行任务,service影响的是进程的生命周期。Service有两种启动状态,Service这两种状态可以共存。

第一种是直接start方式开启service,主要用于执行后台的计算。

使用service的步骤:

1,定义一个类继承service

2,manifest.xml文件中配置service

3,使用context的startService(Intent)方法启动service

4,不在使用时,调用stopService(Intent)方法停止服务

使用start方式启动的生命周期:onCreate() -- > onStartCommand() -- > onDestory()

注意:如果服务已经开启,不会重复回调onCreate()方法,如果再次调用context.startService()方法,service而是会调用onStart()或者onStartCommand()方法。停止服务需要调用context.stopService()方法,服务停止的时候回调onDestory被销毁。

特点:一旦服务开启就跟调用者(开启者)没有任何关系了。开启者退出了,开启者挂了,服务还在后台长期的运行,开启者不能调用服务里面的方法。

第二种是绑定状态bind的方式启动,主要用于和其他组件交互。

使用service的步骤:

1,定义一个类继承Service

2,在manifest.xml文件中注册service

3,使用context的bindService(Intent,ServiceConnection,int)方法启动service

4,不再使用时,调用unbindService(ServiceConnection)方法停止该服务

使用这种start方式启动的service的生命周期如下:onCreate() -- > onBind() --> onUnbind() -- > onDestory()  (注意:绑定服务不会调用onStart()或者onStartCommand()方法)

特点:bind的方式开启服务,绑定服务,调用者挂了,服务也会跟着挂掉。绑定者可以调用服务里面的方法。

DEMO:ServiceLifeCycle类中的两个静态方法是为了在验证启动模式的,主动关闭当前服务的效果,也可以通过广播的形式来关闭开启的服务。

public class ServiceLifeCycle extends Service {

    private static ApkActivity m;
    private String TAG = "ServiceLifeCycle";

    public static void startService(Context context) {
        if (null != context) {
            m = (ApkActivity) context;
            Intent intent = new Intent(context, ServiceLifeCycle.class);
            // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startService(intent);
        }
    }

    public static void stopService(Context context) {
        if (null != context) {
            Intent intent = new Intent(context, ServiceLifeCycle.class);
            // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.stopService(intent);
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand()");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "onCreate()");
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Log.e(TAG, "onStart(...)");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "onDestroy()");
        if (m != null) {
            m.finish();
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG, "onBind(...)");
        return new MyBinder();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e(TAG, "onUnbind(...)");
        return super.onUnbind(intent);
    }


    public class MyBinder implements IBinder {

        @Override
        public String getInterfaceDescriptor() throws RemoteException {
            return null;
        }

        @Override
        public boolean pingBinder() {
            return false;
        }

        @Override
        public boolean isBinderAlive() {
            return false;
        }

        @Override
        public IInterface queryLocalInterface(String descriptor) {
            return null;
        }

        @Override
        public void dump(FileDescriptor fd, String[] args) throws RemoteException {

        }

        @Override
        public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {

        }

        @Override
        public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
            return false;
        }

        @Override
        public void linkToDeath(DeathRecipient recipient, int flags) throws RemoteException {

        }

        @Override
        public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
            return false;
        }
    }


}
public class TestActivity extends Activity {

 
    MyServiceConnection myServiceConnection;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_apk);
        initView();
   }

    private void initView() {
        myServiceConnection = new MyServiceConnection();
        TextView mStart = (TextView) findViewById(R.id.start_service);
        TextView mStop = (TextView) findViewById(R.id.stop_service);
        mStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // ServiceLifeCycle.startService(ApkActivity.this);
                bindService(new Intent(TestActivity.this, ServiceLifeCycle.class), myServiceConnection, BIND_AUTO_CREATE);
            }
        });
        mStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //静态方法关闭
                // ServiceLifeCycle.stopService(ApkActivity.this);
                unbindService(myServiceConnection);
            }
        });
    }

    private void testStartService() {
        Intent mService = new Intent(this, ServiceLifeCycle.class);
        startService(mService);
    }


    private class MyServiceConnection implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            ServiceLifeCycle.MyBinder myBinder = (ServiceLifeCycle.MyBinder) service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }
}

xml布局简单就不在提供了。

注册列表:

<service android:name=“.downloadApk.ServiceLifeCycle"/>

startService启动打印结果:

 05-17 04:03:17.216 19745-19745/com.algorithm.algorithm E/ServiceLifeCycle: onCreate()

05-17 04:03:17.216 19745-19745/com.algorithm.algorithm E/ServiceLifeCycle: onStartCommand()

05-17 04:03:17.216 19745-19745/com.algorithm.algorithm E/ServiceLifeCycle: onStart(...)

bindService打印:

05-17 08:25:02.112 1348-1348/com.algorithm.algorithm E/ServiceLifeCycle: onCreate()

05-17 08:25:02.112 1348-1348/com.algorithm.algorithm E/ServiceLifeCycle: onBind(…)

点击unbindService,打印:

05-17 08:26:15.408 1348-1348/com.algorithm.algorithm E/ServiceLifeCycle: onUnbind(...)

05-17 08:26:15.408 1348-1348/com.algorithm.algorithm E/ServiceLifeCycle: onDestroy()

2.远程服务

调用者和service不在同一个进程中,service在单独的进程中的main线程,是一种垮进程通信方式.

绑定远程服务的步骤:

a.在服务的内部创建一个内部类,提供一个方法,可以间接调用服务的方法

b.把暴露的接口文件的扩展名改为.aidl文件 去掉访问修饰符

c.实现服务的onbind方法,继承Bander和实现aidl定义的接口,提供给外界可调用的方法

d.在activity 中绑定服务。bindService()

e.在服务成功绑定的时候会回调 onServiceConnected方法 传递一个 IBinder对象

f. AIDL定义的接口.Stub.asInterface(binder) 调用接口里面的方法

具体的内容可以参照我之后的文章:android AIDL

========================================

文章借鉴了:http://www.jianshu.com/p/51aaa65d5d25

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值