android学习笔记(6)

来源:互联网 发布:judy兔子 知乎 编辑:程序博客网 时间:2024/05/17 16:12

service相关知识

使用和绑定service

首先得知道service是什么

http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html

这上面讲的比较清楚

首先我们创建一个service 


然后回到main,创建四个button分别代表,开始,结束,绑定,接触绑定


然后设定监听器,关于监听器,可以使用批量定义的方法



findViewById(R.id.button1).setOnClickListener(this);findViewById(R.id.button2).setOnClickListener(this);findViewById(R.id.button3).setOnClickListener(this);findViewById(R.id.button4).setOnClickListener(this);

 public void onClick(View v) {        switch (v.getId()){            case R.id.button1:                startService(intent);                break;            case R.id.button2:                stopService(intent);                break;            case R.id.button3:                bindService(intent,this,Context.BIND_AUTO_CREATE);                break;            case R.id.button4:                unbindService(this);                break;        }    }    @Override    public void onServiceConnected(ComponentName name, IBinder service) {    }    @Override    public void onServiceDisconnected(ComponentName name) {    }}



startService(intent);
public int onStartCommand(Intent intent, int flags, int startId) {    new Thread(){        @Override        public void run() {            super.run();            while (true) {                System.out.println("service..."+a++);                try {                    sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }.start();    return super.onStartCommand(intent, flags, startId);}
在service中写这个,
  1. 启动service的时候,onCreate方法只有第一次会调用,onStartCommand和onStart每次都被调用。onStartCommand会告诉系统如何重启服务,
  2. 如判断是否异常终止后重新启动,在何种情况下异常终止 

然后点击start,会自动运行,如果退出app,还是会继续运行


但是你会发现,如果写在onStartCommand中,当你点击多次开始服务的时候,他是会启动不同的线程来完成

所以将其写在public voidonCreate() 中,onCreat只在开始时运行一次,所以当你多次点击开始他也只会运行一次



说明service会在后台运行,所以很多需要在后台写的代码都可以在service中

我们可以改写代码

public void onCreate() {    super.onCreate();    running=true;    new Thread(){        @Override        public void run() {            super.run();            while (running) {                System.out.println("service..."+a);                try {                    sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }.start();}
@Overridepublic void onDestroy() { running=false; super.onDestroy();}
用来看他什么时候停止

当停止时,会终止运行。


还是用我们的老朋友Intent

在button的响应代码中加入

intent.putExtra("data",editText.getText().toString());
用以实现数据共享
我们可以在MyService,中找到
public int onStartCommand(Intent intent, int flags, int startId) {
可以用它接收Intent
public int onStartCommand(Intent intent, int flags, int startId) {    a=intent.getStringExtra("data");    return super.onStartCommand(intent, flags, startId);}
在MyServies中接受



case R.id.button3:    bindService(intent,this,Context.BIND_AUTO_CREATE);    break;

onServiceConnected会在绑定时运行
onServiceDisconnected会在程序崩溃时运行
我们可以看到
IBinder service
链接service时,会自动启动onServiceConnected,IBinder在MyService中
public IBinder onBind(Intent intent) {    return new Binder();}
为了方便,我们可以重写类
public class Binder extends android.os.Binder{    public void setData(String data){        MyService.this.a=data;    }}
然后回到MainActivity,private MyService.Binder binder;定义好一个Binder,
private MyService.Binder binder;
当绑定时,将两个binder绑定
@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {    binder= (MyService.Binder) service;}

新添加一个按钮,用来同步数据
case R.id.button5:    binder.setData(editText.getText().toString());    break;
可以完成数据的同步

startService()和bindService()两种模式是完全独立的,如果service还没启动,bindService会启动服务。


点击bind时,系统也会调用Myservice中的onCreat,


使用destroy并不能关掉


如果共享数据


那么后台的传输解决 解决了,又有一个 新的问题,如何将后台数据显示在activity中,这里就要用到android的回调机制

private CallBack callBack;public void setCallBack(CallBack callBack) {    this.callBack = callBack;}public CallBack getCallBack() {    return callBack;}public interface CallBack{    void onDataChange(String args);}

然后再Binder中添加getService方法,使得外界可以获得MyService

public class Binder extends android.os.Binder{    public void setData(String data){        MyService.this.a=data;    }    public MyService getService(){        return MyService.this;    }}
在activity中
@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {    binder= (MyService.Binder) service;   binder.getService().setCallBack(new MyService.CallBack() {       @Override       public void onDataChange(String args) {           tv.setText(args);       }   });
我本来想直接
 tv.setText(args);
结果发现不行,程序是由线程调用的,线程直接调用UI资源是会报错的。
在Android的UI开发中,我们经常会使用Handler来控制主UI程序的界面变化。有关Handler的作用,我们总结为:与其他线程协同工作,接收其他线程的消息并通过接收到的消息更新主UI线程的内容。
Handler handler=new Handler(){    @Override    public void handleMessage(Message msg) {        super.handleMessage(msg);    }};
Message是线程之间传递信息的载体,包含了对消息的描述和任意的数据对象。
public void onDataChange(String args) {    Message message=new Message();    Bundle bundle=new Bundle();    bundle.putString("data",args);    message.setData(bundle);    handler.sendMessage(message);}
这样可以UI线程的通信













1 0
原创粉丝点击