一.Activity 和 Service进行通信的基本概念

前面我们学习我生命周期里面包含了启动和停止服务的方法,虽然服务器在活动里启动,但在启动了服务之后,活动与服务基本就没有什么关系了。我们在活动里调用了startService()方法来启动Service这个服务,然后Service的onCreate()和onStartCommaned()方法就会得到执行.之后服务会一直运行状态,但具体运行的是什么逻辑,活动就控制不了咯,这就类似于活动通知了服务一下,“你可以启动了”,然后服务就去忙自己的事情了,但活动并不知道服务到底去做了什么事情,以及完成的如何......很多人就会问有没有什么办法能让活动和服务的关系更紧密一些呢? 比如在活动中指挥服务去干什么,服务就会去干什么。当然可以了,这时候就需要用到onBind()方法。

二.验证BindService启动Service的顺序:

在写代码前首先去了解一些东西先,Context的bindService方法如下:

ServiceConnection对象:监听访问者与Service间的连接情况,如果成功连接,回调 onServiceConnected(),如果异常终止或者其他原因终止导致Service与访问者断开 连接则回调onServiceDisconnected方法,调用unBindService()不会调用该方法!

onServiceConnected方法中有一个IBinder对象,该对象即可实现与被绑定Service 之间的通信!我们再开发Service类时,默认需要实现IBinder onBind()方法,该方法返回的 IBinder对象会传到ServiceConnection对象中的onServiceConnected的参数,我们就可以 在这里通过这个IBinder与Service进行通信!

总结:

  1. 在自定义的Service中继承Binder,实现自己的IBinder对象
  2. 通过onBind( )方法返回自己的IBinder对象
  3. 在绑定该Service的类中定义一个ServiceConnection对象,重写两个方法, onServiceConnected和onDisconnected!然后直接读取IBinder传递过来的参数即可!

三.代码之旅

  OK!接下来就是写代码验证了,这里的话我们定义一个用来计数的Service, 然后来演示BindService的用法以及方法调用流程!

package com.nyl.bindservice;  

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log; public class TestService extends Service{ private static String TAG = TestService.class.getSimpleName();
private int count;
private boolean quit; //定义onBinder方法所返回的对象
private MyBinder binder = new MyBinder(); public class MyBinder extends Binder{
public int getCount(){
return count;
}
} //必须实现的方法,绑定该Service是回调该方法
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG,"onBind方法被回调!");
return binder;
} //Service被创建时回调
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG,"onCreate被回调");
//创建一个线程动态的修改count的值
new Thread(new Runnable() {
@Override
public void run() {
while (!quit){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;
}
}
}).start();
} //Service断开连接时回调
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG,"onUnbind方法被调用");
return true;
} //service被关闭前回调
@Override
public void onDestroy() {
super.onDestroy();
this.quit = true;
Log.i(TAG,"onDestroy方法被调用");
} @Override
public void onRebind(Intent intent) {
Log.i(TAG,"onRebind方法被调用");
super.onRebind(intent);
}
}

  在AndroidManifest.xml中对Service组件进行注册:

  当一个活动和服务绑定之后,就可以调用该服务里的Binder提供的方法了,我们可以写一个MainActivity测试一下,代码如下:

package com.nyl.bindservice;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast; public class MainActivity extends Activity implements View.OnClickListener { private Button btnLockService;
private Button btnUnLockService;
private Button btnGetService; final Intent intent = new Intent(); //保持所启动的Service的IBinder对象,同时定义一个ServiceConnection对象
TestService.MyBinder binder; private ServiceConnection conn = new ServiceConnection() { //Activity与Service连接成功回调该方法
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
System.out.println("连接服务");
binder = (TestService.MyBinder) iBinder;
} //Activity与Service断开连接时回调该方法
@Override
public void onServiceDisconnected(ComponentName componentName) {
System.out.println("不连接服务");
}
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView(); //初始化控件
} private void initView() {
btnLockService = (Button) findViewById(R.id.btnLockService);
btnUnLockService = (Button) findViewById(R.id.btnUnLockService);
btnGetService = (Button) findViewById(R.id.btnGetService); intent.setAction("com.nyl.bindservice.TestService");
intent.setPackage(getPackageName()); btnLockService.setOnClickListener(this);
btnUnLockService.setOnClickListener(this);
btnGetService.setOnClickListener(this); } @Override
public void onClick(View view) {
if (view.getId() == R.id.btnLockService){
//绑定service
bindService(intent,conn, Service.BIND_AUTO_CREATE);
}
if (view.getId() == R.id.btnUnLockService){
if(conn!=null){
//解除service的绑定
unbindService(conn);
}
}
if (view.getId() == R.id.btnGetService){
Toast.makeText(getApplicationContext(),"Service的count的值为:" + binder.getCount(),Toast.LENGTH_SHORT).show();
}
}
}

  注:有些时候我们使用Service的时需要采用隐私启动的方式,但是Android 5.0一出来后,其中有个特性就是Service Intent must be explitict,也就是说从Lollipop开始,service服务必须采用显示方式启动。解决方法:设置Intent的Action和packageName(intent.setPackage(getPackageName());

  运行MainActivity,如下图所示:

  

  点击锁定Service和解除锁定,运行结果如下图:

  点击获取Service状态按钮,如下图:

  

  关于Activity和 Service进行通信的内容就介绍这么多,文章如果有写得不对的地方,欢迎广大园友指正!

Android学习总结(四)—— Activity和 Service进行通信的更多相关文章

  1. 五、Android学习第四天补充——Android的常用控件(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 五.Android学习第四天补充——Android的常用控件 熟悉常用的A ...

  2. 四、Android学习第四天——JAVA基础回顾(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 四.Android学习第四天——JAVA基础回顾 这才学习Android的 ...

  3. Android学习整理之Activity篇

    一.Activity概念介绍 activity属于android的四大组件之一(其他的三个: Content provider,Broadcast receiver,Service),它可以理解为一个 ...

  4. android学习十四(android的接收短信)

    收发短信是每一个手机主要的操作,android手机当然也能够接收短信了. android系统提供了一系列的API,使得我们能够在自己的应用程序里接收和发送短信. 事实上接收短信主要是利用我们前面学过的 ...

  5. android学习笔记27——Activity

    Activity配置==> android应用程序要求所有的应用程序组件都需要进行显示配置后,才可正常使用.包括:Activity.Service.BroadCastReceiver.Conte ...

  6. android学习笔记26——Activity

    Activity ==> android中四大组件:Activity.Service.BroadcastReceiver.ContentProvider Activity组件用于对用户呈现操作界 ...

  7. Android 跨应用调用Activity及Service

    如何调用另外一个app应用的activity或者service,本文提供一个验证可行的方法. 调用方法: Intent intent=new Intent("youActionName&qu ...

  8. Android学习笔记之Activity详解

    1 理解Activity Activity就是一个包含应用程序界面的窗口,是Android四大组件之一.一个应用程序可以包含零个或多个Activity.一个Activity的生命周期是指从屏幕上显示那 ...

  9. 【Android】完善Android学习(四:API 3.1)

    备注:之前Android入门学习的书籍使用的是杨丰盛的<Android应用开发揭秘>,这本书是基于Android 2.2API的,目前Android已经到4.4了,更新了很多的API,也增 ...

随机推荐

  1. 5.oracle中一个字段中存储'a','b'与'a'与a的写法,存储过程中与之对应

    select '''a'',''b''' from dual; --'a','b' select '''a''' from dual; --'a' select 'a' from dual; --a

  2. themeforest 免费模板

    http://www.im286.com/thread-9550365-1-1.html 官网:http://themeforest.net/item/elena-responsive-email-t ...

  3. c语言编译器内置宏

    注:转自http://www.cnblogs.com/lixiaohui-ambition/archive/2012/08/21/2649052.html  感谢分享 前言: 我们在写程序的时候,总是 ...

  4. Git 移除某些文件

    一.前言 在使用 Git 版本控制中,有些文件是不需要加入到版本控制中的.如 日志( log ).编译的文件.这些随时都在变的文件,使用用一个代码库的用户.只要稍稍修改一点,或者启动一下,就会变.容易 ...

  5. 让group tableview每个section拥有阴影和圆角

    #import <UIKit/UIKit.h> @class GroupShadowTableView; @protocol GroupShadowTableViewDelegate &l ...

  6. TyvjP1863 [Poetize I]黑魔法师之门(2014-8-27)

    P1863 [Poetize I]黑魔法师之门 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 经过了16个工作日的紧张忙碌,未来的人类终于收集到了足够的能源 ...

  7. Mol Cell Proteomics. |王欣然| 基于微粒的蛋白聚合物捕获技术让能满足多种不同需求的蛋白质组学样品制备方法成为可能

    大家好,本周分享的是发表在Molecular & Cellular Proteomics. 上的一篇关于蛋白质组学样本质谱分析前处理方法改进的文章,题目是Protein aggregation ...

  8. JAVA实训总结 :String

    String是特殊的类,与其他基本类型并不相同,是被java封装的类型 String底层组成对象为数组与字典(字符集编码表) String 类型的字符串是存储在JVM特别开辟的字符串常量池中   创建 ...

  9. bzoj4563 HAOI2016放旗子

    bzoj传送门 已知了"任意两个障碍不在同一行,任意两个障碍不在同一列",如果我们按每列只能放一个来考虑,那么这\(n\)个障碍一定是一个排列,那么也就是"每一列只能放一 ...

  10. PostgreSQL - 用psql 运行SQL文件

    对于预先写好的SQL文件,比如/home/user1/updateMyData.sql, 可以有两种方式来运行这个SQL文件. 方式一:连接db后执行SQL文件 首先通过psql连接到对应的db: p ...