Service的使用一

来源:互联网 发布:编程入门书籍推荐 编辑:程序博客网 时间:2024/04/29 16:58

Service的基本知识点:

一、 Service简介

Service是android 系统中的四大组件之一(Activity、Service、BroadcastReceiver、ContentProvider),它跟Activity的级别差不多,但不能自己运行只能后台运行,并且可以和其他组件进行交互。service可以在很多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务总是藏在后台的。

Service的启动有两种方式:context.startService() context.bindService()


二、 Service启动流程

context.startService() 启动流程:

context.startService()  -> onCreate()  -> onStart()  -> Service running  -> context.stopService()  -> onDestroy()  -> Service stop 


如果Service还没有运行,则android先调用onCreate(),然后调用onStart();

如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。 

如果stopService的时候会直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行,该Service的调用者再启动起来后可以通过stopService关闭Service。

所以调用startService的生命周期为:onCreate --> onStart (可多次调用) --> onDestroy


context.bindService()启动流程:

context.bindService()  -> onCreate()  -> onBind()  -> Service running  -> onUnbind()  -> onDestroy()  -> Service stop
 

onBind()将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service的实例、运行状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。 

所以调用bindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。

在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。

 


三、 Service生命周期 

Service的生命周期并不像Activity那么复杂,它只继承了onCreate()、onStart()、onDestroy()三个方法

当我们第一次启动Service时,先后调用了onCreate()、onStart()这两个方法;当停止Service时,则执行onDestroy()方法。

这里需要注意的是,如果Service已经启动了,当我们再次启动Service时,不会在执行onCreate()方法,而是直接执行onStart()方法。

它可以通过Service.stopSelf()方法或者Service.stopSelfResult()方法来停止自己,只要调用一次stopService()方法便可以停止服务,无论调用了多少次的启动服务方法。

使用过程

1。分析客户端需要的功能。将功能抽象成接口。
2。按照AIDL文件编写规则(SDK的AIDL专题)编写AIDL文件。假设命名为IA.aidl。
3。在GEN中自动生成对应的JAVA文件。
4。使用公共类或者在service中的内部类来实现IA.Stub接口的抽象方法。实现AIDL的服务端功能。
    假设你写的实现类的名称是IAimpl
5。在service的onbind中以IA.Stub的类型,返回IAimpl的一个实例。
6。在客户端的conn接口实现中的onServiceConnected方法中,
    使用IA.Stub.asInterface(service)的方式返回一个IA实现类。
    通过这个实现类我们就可以使用AIDL远程调用的方法了。
    
注意:
1.AIDL的编写规则。具体在SDK的“docs\guide\developing\tools\aidl.html”目录下。
2.注意IA接口功能的实现是在IA.Stub实现类中实现的。
3.可以不去了解自动生成的那个JAVA文件的工作细节。个

定义一个简单的个人信息接口,有三个属性,姓名、年龄、显示姓名和年龄,注意后缀名为.aidl,后缀名写错了就不灵了。

package com.demo.www;

interface IPerson{
    void setAge(int age);
    void setName(String name);
    String display();
}

写一个类继承自Service,包什么的就不导入了,这个可以自动导

public class MyService extends Service {
//    申明我们代理类的实例。
//    声明IPerson.Stub类型。这是一种方法,下一节介绍另一种方法
    IPerson.Stub person = new Newperson();
    @Override
    public IBinder onBind(Intent intent) {
        return person;
    }

}
//下面这个就是我们IPerson.aidl的实现类。
//功能要在这个类中实现。
//实现后要在service中返回这个类的实例。
class Newperson extends IPerson.Stub
{
    private int age = 27;
    private String name = "lala";
    public void setAge(int age) throws RemoteException {
        // TODO Auto-generated method stub
        this.age = age;
    }

    public void setName(String name) throws RemoteException {
        // TODO Auto-generated method stub
        this.name = name;
    }

    public String display() throws RemoteException {
        // TODO Auto-generated method stub
        return new StringBuffer().append("名字:").append(name).append(" 年龄:").append(age).toString();
    }
    
}

下面这个是Activity调用Service的那个主界面,包名自己导入,

public class Service5Activity extends Activity implements OnClickListener {
    /** Called when the activity is first created. */
    LinearLayout lv;
    EditText et1,et2;
    TextView tv;
    Button bt;
    ServiceConnection conn;
    IPerson p;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.main);
        lv = new LinearLayout(this);//动态new 一个布局文件
        et1 = new EditText(this);
        et2 = new EditText(this);
        tv = new TextView(this);
        bt = new Button(this);
        bt.setText("display");
        bt.setOnClickListener(this);
        lv.setOrientation(LinearLayout.VERTICAL);
        lv.addView(et1);
        lv.addView(et2);
        lv.addView(bt);
        lv.addView(tv);
        setContentView(lv);
        //用AIDL的好处,1隐藏Serivice,2让其它程序调用实现特定功能
        conn = new ServiceConnection() {
            
            public void onServiceDisconnected(ComponentName name) {
                // TODO Auto-generated method stub
                
            }
            
            public void onServiceConnected(ComponentName name, IBinder service) {
                // TODO Auto-generated method stub
//                使用这句话获取IPerson的实现类句柄,通过这个句柄实现功能。这是方法其一,下节是另外一种方法
                p = IPerson.Stub.asInterface(service);
            }
        };
        bindService(new Intent(this,MyService.class), conn, Service.BIND_AUTO_CREATE);
    }
    public void onClick(View v) {
        // TODO Auto-generated method stub
        try {
//            setAge,setName,setDisplay都在Newperson中实现的。
//            我们客户端可以不用考虑细节,直接使用即可。
            p.setAge(Integer.parseInt(et2.getText().toString()));
            p.setName(et1.getText().toString());
            tv.setText(p.display());
        } catch (NumberFormatException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

例子很简单,不多说了,说多了污染大家的智商,如果各位大虾们觉得太简单了,希望不要拍砖过来,哥身材瘦小,经不起拍。这主要是给哥我温习用的

原创粉丝点击