欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android Activity 与Service进行数据交互详解

程序员文章站 2024-03-05 11:14:30
①从设计的角度来讲: android的activity的设计与web页面非常类似,从页面的跳转通过连接,以及从页面的定位通过url,从每个页面的独立封装等方面都可以看...

①从设计的角度来讲:

android的activity的设计与web页面非常类似,从页面的跳转通过连接,以及从页面的定位通过url,从每个页面的独立封装等方面都可以看出来,它主要负责与用户进行交互。

service则是在后台运行,默默地为用户提供功能,进行调度和统筹。如果一棵树的地上部分是activity的话,它庞大的根须就是service。android的服务组件没有运行在独立的进程或线程中,它和其他的组件一样也在应用的主线程中运行,如果服务组件执行比较耗时的操作就会导致主线程阻塞或者假死,从而无法响应用户的操作。

因此,耗时的操作不要放在ui线程中,因为ui 5s,广播10s就阻塞了,会引发anr。

②从使用的角度来讲: 

service不仅可以给activity建立双向连接,为activity提供数据和功能支持,也可以单向接受intent的请求,进行数据的分析处理和功能调度。

③从扮演的角色来讲:

activity的功能比较单一,主要就是显示应用所具有的一些功能,帮助用户与应用进行交互,像一个人的脸。而service可能扮演功能调度者也能扮演功能提供者,从触发器收集信息进行分析和处理,然后更新界面,修改数据或进行其他操作时是一个功能调度者,从输入法的选择考虑service扮演的就是一个功能提供者。view组件是android中用户能够实实在在看到的部分,如按钮,输入框等就是继承自这个类,view只有装入activity这样的容器中才有意义,而反过来activity装入了这些view后才能够成功完成与用户交互的任务,但是service不需要这些花哨的东西,只需要默默地等待事件发生或者听候差遣。

android启动service有两种方法,一种是startservice,一种是bindservice。生命周期如下:

Android Activity 与Service进行数据交互详解

执行startservice时,调用者如果没有stopservice,service会一直在后台运行。多次调用startservice,该service只能被创建一次,即该service的oncreate方法只会被调用一次。但是每次调用startservice,onstartcommand方法都会被调用。

执行bindservice时,调用者调用unbindservice方法或者调用者context不存在了(如activity被finish了)。第一次执行bindservice时,oncreate和onbind方法会被调用,但是多次执行bindservice时,oncreate和onbind方法并不会被多次调用,即并不会多次创建服务和绑定服务。 多个组件可以同时绑定到该服务,但全部取消绑定后,该服务即会被销毁。

既使用startservice又使用bindservice的情况,需要unbindservice和stopservice同时调用才会终止service。

activity与service交互有两种方法:一种是使用broadcast,另一种是使用bindservice。本文只介绍bindservice方法。

public class msgservice extends service {
  public msgservice() {
  }

  /**
   * 进度条的最大值
   */
  public static final int max_progress = 100;
  /**
   * 进度条的进度值
   */
  private int progress = 0;

  /**
   * 增加get()方法,供activity调用
   *
   * @return 下载进度
   */
  public int getprogress() {
    return progress;
  }

  /**
   * 模拟下载任务,每秒钟更新一次
   */
  public void startdownload(){
    new thread(new runnable() {

      @override
      public void run() {
        while(progress < max_progress){
          progress += 5;

          //进度发生变化通知调用方
          if(onprogresslistener != null){
            onprogresslistener.onprogress(progress);
          }

          try {
            thread.sleep(1000);
          } catch (interruptedexception e) {
            e.printstacktrace();
          }

        }
      }
    }).start();
  }

  @override
  public ibinder onbind(intent intent) {
    return new mybinder();
  }

  public class mybinder extends binder {
    public msgservice getservice() {
      return msgservice.this;
    }
  }

  public interface onprogresslistener {
    void onprogress(int progress);
  }

  /**
   * 更新进度的回调接口
   */
  private onprogresslistener onprogresslistener;


  /**
   * 注册回调接口的方法,供外部调用
   *
   * @param onprogresslistener
   */
  public void setonprogresslistener(onprogresslistener onprogresslistener) {
    this.onprogresslistener = onprogresslistener;
  }

}
public class mainactivity extends activity {

  private button button19;

  private msgservice msgservice;
  private int progress = 0;
  private progressbar mprogressbar;


  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);

 


    btnexec = (button) findviewbyid(r.id.btnexec);
    button19 = (button) findviewbyid(r.id.button19);
    mprogressbar = (progressbar) findviewbyid(r.id.progressbar);


    button19.setonclicklistener(new view.onclicklistener() {
      @override
      public void onclick(view view) {
        msgservice.startdownload();
      }
    });

    intent intent = new intent(this, msgservice.class);
    bindservice(intent, mserviceconnection, context.bind_auto_create);

 

  }

 

 

  serviceconnection mserviceconnection = new serviceconnection() {
    @override
    public void onserviceconnected(componentname componentname, ibinder ibinder) {
      msgservice = ((msgservice.mybinder) ibinder).getservice();

      msgservice.setonprogresslistener(new msgservice.onprogresslistener() {
        @override
        public void onprogress(int progress) {
          mprogressbar.setprogress(progress);
        }
      });
    }

    @override
    public void onservicedisconnected(componentname componentname) {

    }
  };


  @override
  protected void ondestroy() {

    unbindservice(mserviceconnection);
    super.ondestroy();
  }
}

例子中,msgservice模拟耗时的下载任务,mainactivity 绑定服务,通过注册onprogresslistener回调获取下载进度,更新进度条。

本例子activity和service是在同一个进程中,对于跨进程调用service需要使用到aidl技术。

 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!