android学习笔记(6)

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 void onCreate() 中,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绑定
@Override
public 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中
@Override
public 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线程的通信















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值