Android组件序列—-Android Service组件深刻剖析

“第四次过虫洞嘛,有含义。”

图片 1

他说,水母触须上面,不是装有共生的双鳍鲳吗。

1 package com.example.servicetest02;  
2 interface IPerson{  
3     void setName(String name); 
4     void setSex(String sex);
5     void setAge(int age);
6     String getPerson();
7 }

上一节目:《常回家看看》演唱:王元博

根据上边第一段的知识,大家介绍了销毁Service最简便的一种情景:现在卸载程序,重新运行程序,点击Start
Service按钮启动Service,再点击Stop
Service按钮甘休Service,那样MyService就被灭绝了:

高小山:天上飘过的发光体不自然是孔明灯,也说不定是无家可归的外星难民。在三回留白的人类打扰后,有超强生殖能力的水母状的外星人来到地球。这一个星际难民组成货真价实的“超生游击队”,为全人类的活着增加了一抹诡谲却又略有点儿小自己的魔幻现实色彩。

文件保留之后,ADT会在gen目录下自动生成一个遥相呼应的Java文件,如下图所示:

“只要大家尽力深远人类社会,将来肯定有那么一天,能向人类注解,大家不是水母,大家是真的的,能和她俩平起平坐的智慧体!”

上图中的Stub类可以比作存根。Stub类继承了Binder类,同时达成了IPerson接口(没有落到实处IPerson里的法门)。所以越发明白为:Stub既是IPerson里的中间类,也是一个IPerson。

▲ 丈母娘!孔明灯飞上天了!(图源:deviantart.com)

继承回想第(1)步中自动生成的IPerson.java文件,截取第22至32行,摘抄如下:

红灯笼情感缓和了些:“你说,自从跟你一起,离开母星,日子就没有一天平稳。”

(2)在清单文件中对劳动开展注册服务:

▲ 别藏了!超生罚款单贴你们家门口了!(图源:deviantart.com)

也就是说,要贯彻:让Activity与一个长途Service建立关系,这就要选取AIDL来展开跨进程通讯了(IPC)。那里把Bind
Service及任何的概念再重复一下:

——回不去了,回不去了。

  【声明】 

“被抓去连躲躲藏藏的生活都没了。”蓝灯笼忧郁地拱一拱红灯笼,“它们必然活着啊。我们的幼虫随彗星穿越银河,什么都能适应。”

可以看看,大家只是在onCreate()、onStartCommand()和onDestroy()方法中分别打印了一句话,并不曾举办其余任何的操作,注意代码注释中这七个方法的法力。

——我研商过人类对大家的商量。当大家赞叹,当我们多少变大,理论上,共振会尤其持久。要清楚,在母星上,大家多少很少。

(1)在外表使用stopService()

注:文中描绘的增殖格局参考了实际中的灯笼水母,但分化。

38至50行:新建一个MyBinder类,继承Binder:让其中的方法执行下载任务,并取得下载进程。当然,那里只是五个模拟方法,并从未落实真正的作用,我们由此打印日志的款型来显示。

晚年的灯笼水母已高速旋转,比它更快,并狠狠将自己甩到墙壁上。五彩斑斓的、半晶莹剔透的、伞状躯体立时碎成一团团的细胞组织。无用细胞立时脱落,其他细胞复原为干细胞,构成一团透明原生质,纷繁爬向管道口,接近管道时,原生质重新变成了形如水螅的杆状灯笼幼虫。

假设将那种艺术运用到地点的第四段中,意况是那样的:

蓝灯笼的响声很大,引起了全体共振。它的子女们随后有些颤动,如拾草芥,发出浑厚的低频重音。

什么样销毁Service:

紫幼虫尾随。

因而说,一个相比较正规的Service,就能够写用度段中第1节的典范。

“哇!”不知何时,街道口站了拿糖葫芦的人类小孩。

AIDL辅助的品种:八大骨干数据类型、String类型、CharSequence、List、Map、自定义。

宽恕游击队

运作程序,点击按钮button3_stop_intentservice,突显如下:

幼虫群落散开,纷纭攀上墙壁,初始崩溃。一时间,街道遍布小灯柱构成的写道。每个灯柱端口都发出十几个灯笼幼体。第四遍变成灯笼的小幼体直径到五分米便不再成长;另一对则基于自己的变态次数,成熟为体格不一的灯笼。

【正文】

▲ 它们有谈得来的家园,不应该到地球来(图源:qinni.deviantart.com)

应用程序组件(客户端)通过调用bind瑟维斯()方法能够绑定服务,然后Android系统会调用服务的onBind()回调方法,则个方法会重临一个跟服务器端交互的Binder对象。

紫灯笼突然反弹,高速游到街道口。

过程:在经过A中创立一个Message,将以此Message对象通过Messenger.send(message)方法传递到进程B的音信队列里,然后交给Handler去处理。

管道一阵波动,无数幼虫飘出,兴奋地上下游动。有的只一毫米长,触手没长全;有的接近十毫米,躯体分三节。幼虫集成分裂部落,形成五光十色圣诞树。

 1 package com.example.servicetest;
 2 
 3 import android.app.Service;
 4 import android.content.Intent;
 5 import android.os.IBinder;
 6 
 7 public class MyService extends Service {  
 8       
 9     public static final String TAG = "MyService";   
10   
11     //服务执行的操作
12     @Override  
13     public int onStartCommand(Intent intent, int flags, int startId) {  
14         new Thread(new Runnable() {
15             public void run() {
16                 //处理具体的逻辑
17                 stopSelf();  //服务执行完毕后自动停止
18             }
19         }).start();        
20         return super.onStartCommand(intent, flags, startId);  
21     }
22 
23     @Override
24     public IBinder onBind(Intent intent) {
25         // TODO Auto-generated method stub
26         return null;
27     }      
28  
29 }

(扫码关心“不存在早报”公众号)

只是,如若点击button3_bind_service按钮绑定服务,程序会崩溃的。这是因为,如今MyService已经是一个长距离Service了,Activity和瑟维斯运行在八个不等的进度当中,那时就不可以再选拔传统的创立关系的办法,程序也就完蛋了。

明日头条、十五言、和讯专栏、简书

可以看到,那里大家率先创立了一个ServiceConnection的匿名类(24行),在里边重写了onServiceConnected()方法和onServiceDisconnected()方法,固然当前Activity与服务连接成功后,服务会回调onServiceConnected()方法,

一老一少登上巡视车,声音劳燕分飞。

1、怎样定义(启动)一个Service:

“每变态五遍,数量就翻几番,再这么下来,杆状幼虫也藏不住——”

要旨代码是第44行。

“可人类——”

本段中(第五段)使用的是IPC跨进度通讯,MainActivity和MyService在差其余经过中,可以绑定远程服务。

人类大妈抱着不舍离开的男女走远。

【本文主要内容】

“可我们升高了。那对男女唯有裨益。”蓝灯笼欢快起来,“大家学会了种种语言,见识了人类文明,丰盛了国有意识。人类可是已知智慧生物中最早进入现代性的啊,他们自由、民主、包容。”

一、Service的基本概念(四大组件之一)

“别摸!”小孩儿的亲娘快步来到,把子女拉倒身前,才察觉马路里挤满了灯笼水母。

(1)新建一个My瑟维斯类,继承自Service,不分相互写父类的onCreate()、onStartCommand()和onDestroy()方法,代码如下:

狭小空间内高速飘满了五光十色的灯笼水母。它们撞来撞去,相互打闹。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button_bind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="bind Service" />

    <Button
        android:id="@+id/button_unbind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="unbind Service" />

</LinearLayout>

“它们有三种办法,一种和我们一样,一种嘛,就像你用一根软管,沾点肥皂水,吹出很多众多泡沫。那泡泡,就是灯笼水母,那软管,就是灯笼幼虫。一只灯笼幼虫可以变出很多灯笼水母,人类能接受的外星人又有数,它们就只能挤在街道里,变成外星难民了。它们有自己的家中,不应有到地球来……”

现行赶回本段内容。卸载程序,重新开端。那么只要大家只点击的Bind
Service按钮呢?由于在绑定Service的时候指定的声明位是BIND_AUTO_CREATE,表明点击Bind
Service按钮的时候Service也会被创制,那时应该怎么销毁Service呢?其实也很不难,点击一下Unbind
Service按钮,将Activity和Service的涉嫌解除就可以了:

“拉倒吧,我不爱好地球上生的小幼仔!照在此之前,我拉个爪,就能和它们沟通。现在,它们先叫您‘爸’,才叫自己‘妈’,集体意识都得爪把爪教。”

二、定义(启动)一个Service:

刚出生的小水母附在它的伞状体上,“吱、吱、吱”鸣叫。

运作程序,点击第三个按钮,然后点击首个按钮,效果如下:

蓝、绿色幼虫在管道口附近停住。因为老警察靴子“哒、哒、哒”磕着当地。

1       case R.id.button3_stop_intentservice:
2             Log.d("MainActivity","主线程的id是:"+Thread.currentThread().getId());
3             Intent intentService = new Intent(this,MyIntentService.class);
4             startService(intentService);
5         default:

蓝、紫幼虫本已接纳断后措施,听到那句,又忍不住轻手轻脚,爬向管道口。

 1 package com.example.servicetest03;
 2 
 3 import android.os.RemoteException;
 4 
 5 //业务对象的实现
 6 public class StudentImpl extends IStudent.Stub{
 7 
 8     private Student student;
 9     
10     public StudentImpl(){
11         student = new Student();
12     }
13     @Override
14     public void setStudent(String name, String sex) throws RemoteException {
15         // TODO Auto-generated method stub
16         student.setName(name);
17         student.setSex(sex);
18         
19     }
20 
21     @Override
22     public Student getStudent() throws RemoteException {
23         // TODO Auto-generated method stub
24         return student;
25     }
26 
27 }

蓝灯笼长舒一口气。刚落地的小灯笼不明就里。紫灯笼便用触手揽住它们,一起跻身公共意识的摇篮,分享部分弥足爱抚的明白。

图片 2

撞壁前一刻,紫灯笼愤愤说:“爸,你还向着人类,肯定是那对母女告了状。”

劳务不会自行开启线程,我们需要在劳动的中间手动成立子线程,并在此处举办实际的任务。关于多线程的学识:可以参见此外一篇小说:Android二十四线程—-异步信息处理体制之Handler详解

即日起,您可以在每一天的春晚节目推送中找到投票链接,选出自己最疼爱的撰稿人文章。

一、Service的基本概念(四大组件之一)
二、定义(启动)一个Service

蓝灯笼飘出街道口,飘到小孩儿面前。小孩儿被歌声与灯笼迷住。他请求想摸它,它退了回去。

大家在上一步的MessengerService类新建了一个Messenger,在那里又新建另一个Messenger(54行)。八个Messenger绑定了同一个劳动,Activity就可以和瑟维斯落成通信了。

▲ 将来有那么一天,要和人类平起平坐(图源:deviantart.com)

(3)当系统调用你的onServiceConnected()回调方法时,你就可以开端利用接口中定义的艺术来调用服务了

灯笼水母一须臾间都不动了。

(5)在activity_main.xml中添加多个按钮button_bind_service和button_unbind_service,用于绑定远程服务和撤回绑定。activity_main.xml的代码如下:

“我最钟爱的科幻春晚节目”评选

AIDL它可以用于让某个Service与多少个应用程序组件之间开展跨进度通讯,从而得以兑现八个应用程序共享同一个Service的成效。

——是呀,能让每一个灯笼都颤动,每一个个体都心灵交汇。

在平等进度中,各类零部件进行通讯是那一个有益于的,普通的函数调用就可以解决;可是对于分歧的长河中的组件来说,要拓展通讯,就必要采纳Android的IPC机制了。

红灯笼声音深深:“不能小心点!”

 1 package com.example.servicetest02;
 2 
 3 import android.app.Service;
 4 import android.content.Intent;
 5 import android.os.IBinder;
 6 import android.util.Log;
 7 
 8 public class MyService extends Service {  
 9       
10     public static final String TAG = "MyService";  
11   
12      PersonImpl mBinder = new PersonImpl();
13   
14     @Override  
15     public void onCreate() {  
16         super.onCreate();  
17         Log.d(TAG, "onCreate");  
18     }  
19   
20     @Override  
21     public int onStartCommand(Intent intent, int flags, int startId) {  
22         Log.d(TAG, "onStartCommand");  
23         return super.onStartCommand(intent, flags, startId);  
24     }  
25   
26     @Override  
27     public void onDestroy() {  
28         super.onDestroy();  
29         Log.d(TAG, "onDestroy");  
30     }  
31   
32     @Override  
33     public IBinder onBind(Intent intent) { 
34         Log.d("MyService", "onBind");
35         return mBinder;  //在这里返回新建的MyBinder类
36     }
37   
38 }  

——记得在母星上呢,那时,唯有大家俩。大家约好,只要三个孩子,红、绿、蓝。三种原初的色光。等它们长大,我们再次回到二人世界。

借使要落实进程间通讯,就亟须让MainActivity和瑟维斯相互独立。有四个格局:

五只巨大的灯笼水母飘到路边。

图片 3

科幻春晚分答分会场

图片 4

“外星难民越多,还可以如何做。”

应用程序组件(客户端)通过调用bindService()方法可以绑定服务,然后Android系统会调用服务的onBind()回调方法,则个方法会重返一个跟服务器端交互的Binder对象。

它提心吊胆飘上夜空,发出古老声响,寻找宇宙生物共有的节拍,转动通体透明的肉体,将一切灯笼,都映成了亮黄色。

(3)在activity_main.xml中添加一个按钮button3_stop_intentservice,用于启动MyIntentService服务,代码略。

灯笼水母的部落共振,比任何四遍都明确。

(2)在activity_main.xml中添加多少个按钮button_bind_service和button_unbind_service,用于绑定远程服务和收回绑定。activity_main.xml的代码如下:

蓝幼虫飘出管道,飘到灯火通明的康庄大道中间,一个人类都并未。

(3)新建类MyService,代码如下:

节目预先报告:《好运来》 演唱:凌晨

07行:若是iin不为空,并且iin为IPerson,那就将iin强制转换为IPerson(08行)。很明显,这里是经过内通讯(本地通讯)要用到的。也就是本段中的例子。

“我说过,照旧有灵性的好人类的。”

注:布局文件里不再添加绑定服务和废除绑定的按钮,大家稍后在Activity的生命周期里做到那件事。

“抓就抓,豁出去了。整天东躲江西,你看看大家的孩子,”红灯笼转动身体,晃动触手,“非常之一记得贝塔星,千分之一记得半人马座,新出生的只懂躲在管道里。一路上丢掉的孩子,千千万万,也不知它们是活着,依旧死了。”

4、Service和Thread的关系:

蓝灯笼凑近:“小点儿声。被抓去管控委,就完了。”

实在,后台和子线程是三个精光两样的概念:

——要不是刚刚,我差一些忘了大家本来的歌声。

现行,B应用的作业对象和劳务建立好了。B应用的事务对象通过与Service绑定,让Service把作业对象暴露给了A应用或者其余的行使。也就是说,Service最后并没有完毕业务职能。

熟稔的三连音。

 

“活着的孔明灯?”

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button_messenger"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="使用messenger" />
</LinearLayout>

“管控委!”它说。

那样的话,接二连三点击Unbind Service按钮,就不会使程序出现卓殊。

可是新兴,人类没能找到让灯笼水母甘休共振的主意。水母便永远地飘在了天上之中。

 1 package com.example.servicetest02;
 2 
 3 import android.os.RemoteException;
 4 
 5 public class PersonImpl extends IPerson.Stub{
 6     
 7     private String name;
 8     private String sex;
 9     private int age;
10 
11     @Override
12     public void setName(String name) throws RemoteException {
13         // TODO Auto-generated method stub
14         this.name = name;
15         
16     }
17 
18     @Override
19     public void setSex(String sex) throws RemoteException {
20         // TODO Auto-generated method stub
21         this.sex = sex;
22         
23     }
24     @Override
25     public void setAge(int age) throws RemoteException {
26         // TODO Auto-generated method stub
27         this.age = age;
28         
29     }
30 
31     @Override
32     public String getPerson() throws RemoteException {
33         // TODO Auto-generated method stub
34         return "name="+name+",sex="+sex+",age="+age;
35     }
36 }

——记得,那一个时候,你要么粉黑色的啊。

我们在上面的门类ServiceTest基础上展开修改,步骤如下:

“墙上沾着的,灯笼幼虫变态成灯笼水母时预留的杆状骨架,”老警察转到巷子深处,又重临管道附近,“其余团伙,成年水母退化成杆状幼虫放任的体细胞……”

1         <service android:name=".MyService" >
2             <intent-filter>
3                 <action android:name="com.example.servicetest02.MyService" />
4             </intent-filter>
5         </service> 

▲ 孩儿他爸,看好了,别让娃们乱跑(图源:turenoir.com)

  • 1、怎么着定义(启动)一个Service:
  • 2、为止一个started服务有三种格局
  • 3、onStartCommand方法的再次回到值

入夜时分,下曲江区街道角落,十分米长,形如水螅的八只灯笼幼虫,从管道飘出。它们通体透明,像细长竹杆,分为四节,关节处幽幽辉光。一只红,一只蓝。“竹杆”两端为口,一端有细小触手;另一端可以发声。

设若现在Service和Activity已经相关联了,点击Unbind
Service按钮可以清除绑定,假若继续点击Unbind
Service按钮,程序会丰富退出,那说东汉码不够健全,大家必要在代码中加一个判定是或不是绑定的记号mBound。在改MainActivity中扩张部分代码,最后改MainActivity的完整代码如下:(加粗字体是丰硕的情节)

红灯笼飘到它们中间:“管控委的老警察都知道母星好,就你嫌,还用人类语言给男女起名,连名字都起不佳。”

有鉴于此,启动一个IntentService和开行一个平日的Service,步骤是同样的。

“欧罗巴是女神,多美。”

(2)检查清单文件,是还是不是业已对Service举行注册:

华灯之下,晶莹剔透,也不知是全人类的霓虹,依然灯笼水母的赫赫。

(4)在MainActivity里面参加启动IntentService的逻辑,大旨代码如下:

群体共振又伊始了,并不可以,但温和且持久,一波波扩散。蓝灯笼与红灯笼随之颤动。街道上的、路面上的灯笼水母,也都早先震荡。

生命壹号:http://www.cnblogs.com/smyhvae/

它们身后,成百上千的幼虫爬出管道,变为多如牛毛灯笼水母,纷繁飘上街头。

 

▲ 母星都让地球人挖没了,怎么回去?(图源:deviantart.com)

接着,新建一个和类同名的aidl文件,即新建Student.aidl,代码如下:

今日是春龙节,人都回家过节了。

2、完结Service和Activity之间通信步骤:

蓝灯笼收起身体,一阵僻静。

3、onStartCommand方法的重返值:

蓝幼虫游到路口,伸出触手,感受春季冷飕飕的气氛,发出人耳难以辨其他低频音:“哒、哒、哒……”

图片 5

它们都感受到了它的振动。

着眼地方第二段中MyService中的代码,你会意识直接有一个onBind()方法大家都没有行使到,这一个艺术其实就是用来和Activity建立关系的,修改MyService中的代码,如下所示:

它全身透明,要旨好似点了一盏剔透的蓝灯,在空气中游动、呼吸,告诉人类,它不是真的的水母。

这就注解,MyService可以响应带有com.example.servicetest02.MyService这一个action的Intent

“他怎么了解大家的安全信号。”

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <Button
        android:id="@+id/button_bind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="bind Service" />

    <Button
        android:id="@+id/button_unbind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="unbind Service" />
</LinearLayout>

蓝灯笼用触手波动新宝宝:“十八月中圣诞,10月初端午节。我和你妈没什么礼物给您们,周游世界,多过人类节日,仍能的。”

1 package com.example.servicetest03;
2 
3 import com.example.servicetest03.Student;
4 interface IStudent{
5     void setStudent(String name,String sex);
6     Student getStudent();
7 }

“——不过,你通晓人家管大家叫什么吧?流动大军!为何星际鲸鱼是搬迁,大家就是流动呢!”

<service android:name=".MessengerService"> </service>

“那么些群落,曲率航行时横裂的啊,非叫什么虫洞,还虫洞一号,虫洞二号。”

若果在类型的其余地点调用了Context的startService()方法,相应的服务就会启动起来,并回调onstartCommand()方法。固然这么些服务以前还平素不开创过,onCreate()方法会先于onstartCommand()方法执行。服务启动过后,会一贯维系运行情形,直到stopService()或stopself()方法被调用。注意即便每一次调用四回startService()方法,onstartCommand()方法就会以履行一遍,但实质上每个服务都只会存在一个实例。所以随便你调用了不怎么次start瑟维斯()方法,只需调用三次stopService()或stopself()方法,服务就会终止。

小小的灯笼最胆怯,力气不够大,不足以将团结撞碎。蓝灯笼和紫灯笼便用触手裹住它们,将它们甩向墙壁,摔出单身的干细胞。

图片 6

科幻春晚主会场

 1 package com.example.servicetest;
 2 
 3 import android.os.Parcel;
 4 import android.os.Parcelable;
 5 
 6 public class Student implements Parcelable {
 7     private String name;
 8     private String sex;
 9 
10     public Student() {
11         super();
12     }
13 
14     public String getName() {
15         return name;
16     }
17 
18     public void setName(String name) {
19         this.name = name;
20     }
21 
22     public String getSex() {
23         return sex;
24     }
25 
26     public void setSex(String sex) {
27         this.sex = sex;
28     }
29 
30     @Override
31     public int describeContents() {
32         // TODO Auto-generated method stub
33         return 0;
34     }
35 
36     // 重写父类的方法:将需要传送的数据放进来
37     @Override
38     public void writeToParcel(Parcel dest, int flags) {
39         // TODO Auto-generated method stub
40         dest.writeString(name);
41         dest.writeString(name);
42     }
43 
44     public static final Parcelable.Creator<Student> CREATOR = new Parcelable.Creator<Student>() {
45         public Student createFromParcel(Parcel in) {
46             Student s = new Student();
47             s.setName(in.readString());
48             s.setSex(in.readString());
49             return s;
50         }
51 
52         public Student[] newArray(int size) {
53             return new Student[size];
54         }
55     };
56 
57 }

蓝幼虫便依附墙壁,触手向外,飞快不相同,暴发众多横沟,形成十多少个盘子似得蝶状幼体。其中最大的率先脱落,小幼体紧随其后。五分钟后,大幼体成熟为直径四十分米的灯笼水母。

1、Bind Service的介绍:

兰巴斯饼干,一咬满口脆。中土食品厂祝精灵的恋人们七夕喜悦!

然后在子类中落到实处onHandleIntent()这么些抽象方法,可以在那几个点子里去处理局地有血有肉的逻辑,我们就用四遍for循环,打印当前线程的id,每趟延时1秒。

“孔明灯!”小孩说。

当大家须要如此一次性完结的职分时,就足以应用IntentService来成功。

“繁衍?”

<service android:name=".MyService" android:process=":remote"> </service>

本届科幻春晚合营媒体

那里在营造Intent的时候是行使MyService.class来指定要绑定哪一个Service的,然则在另一个应用程序中去绑定Service的时候并从未MyService那个类,那时就不可能不运用到隐式Intent了。

红幼虫冲向蓝灯笼,狠狠地戳了戳蓝灯笼的透明伞,戳得三分之一伞面都成为乳白色。尔后,红幼虫吸附墙壁,横裂出五十多少个水母小幼体,其中一只成长为比蓝灯笼稍大的红灯笼水母。

分裂二:参数传递

人类妈妈没听过灯笼水母的歌声,大概也没见过挤满街道的灯笼水母,一脸愕然:“不、不是孔明灯,是灯笼水母。”

  • START_NOT_STICKY:“非粘性的”。使用这些重返值时,借使在执行完onStartCommand方法后,服务被那些kill掉,系统不会活动重启该服务。
  • START_STICKY:借使Service进度被kill掉,保留Service的情景为发端情状,但不保留递送的intent对象。随后系统会尝试再一次创制Service,由于劳动处境为始发景况,所以创设服务后肯定会调用onStartCommand(Intent,int,int)方法。假若在此时期没有其余启动命令被传送到瑟维斯,那么参数Intent将为null。
  • START_REDELIVER_INTENT:重传Intent。使用这么些再次回到值时,系统会自动重启该服务,并将Intent的值传入。

“不一样?”

介绍:Messenger落成了IPC通讯,底层也是行使了AIDL形式。和AIDL格局各异的是,Messenger格局是选用Handler方式处理,由此,它是线程安全的,那也表示它不协助并发处理;而AIDL情势是非线程安全的,支持并发处理,由此,大家选择AIDL格局时,须要确保代码的线程安全。超过半数情景下,应用中不必要出现处理,因而大家不足为奇只要求使用Messenger格局。

红灯笼听了一惊,身体疾速如陀螺般旋转。

 1 package com.example.messengertest;
 2 
 3 import android.app.Activity;
 4 import android.content.ComponentName;
 5 import android.content.Intent;
 6 import android.content.ServiceConnection;
 7 import android.os.Bundle;
 8 import android.os.IBinder;
 9 import android.os.Message;
10 import android.os.Messenger;
11 import android.os.RemoteException;
12 import android.util.Log;
13 import android.view.View;
14 import android.view.View.OnClickListener;
15 import android.widget.Button;
16 
17 public class MainActivity extends Activity implements OnClickListener {
18 
19     private Button button_messenger;
20 
21     private Messenger messenger;
22     boolean mBound = false;
23 
24     @Override
25     protected void onCreate(Bundle savedInstanceState) {
26         super.onCreate(savedInstanceState);
27         setContentView(R.layout.activity_main);
28         button_messenger = (Button) findViewById(R.id.button_messenger);
29         button_messenger.setOnClickListener(this);
30     }
31 
32     @Override
33     protected void onStart() {
34         // TODO Auto-generated method stub
35         super.onStart();
36         Intent bindIntent = new Intent(this, MessengerService.class);
37         bindService(bindIntent, connection, BIND_AUTO_CREATE);
38     }
39 
40     @Override
41     protected void onDestroy() {
42         // TODO Auto-generated method stub
43         super.onDestroy();
44         if (mBound) {
45             unbindService(connection);
46             mBound = false;
47         }
48     }
49 
50     private ServiceConnection connection = new ServiceConnection() {
51         @Override
52         public void onServiceConnected(ComponentName name, IBinder service) {
53             // TODO Auto-generated method stub
54             messenger = new Messenger(service);            
55             
56             mBound = true;
57         }
58 
59         @Override
60         public void onServiceDisconnected(ComponentName name) {
61             // TODO Auto-generated method stub
62             mBound = false;
63 
64         }
65 
66     };
67 
68     //点击按钮,发送Message消息,在MessengerService里接收,从而执行Service里面的方法
69     @Override
70     public void onClick(View v) {
71         switch (v.getId()) {
72         case R.id.button_messenger:
73             Message  msg  = Message.obtain();
74             msg.what = MessengerService.MSG_SAY_HELLO;
75             try {
76                 messenger.send(msg);
77                   Log.d("MainActivity", "MainActivity thread id is " + Thread.currentThread().getId()); //打印MainActivity的线程id
78             } catch (RemoteException e) {
79                 // TODO Auto-generated catch block
80                 e.printStackTrace();
81             }
82             break;
83 
84         default:
85             break;
86         }
87     }
88 
89 }

腾讯网、豆瓣、澎湃新闻、中国青年报、MONO

当然,Message对象自我是不可能被传送到进程B的,send(message)方法会利用一个Pacel对象对Message对象编集,再将Pacel对象传递到进程B中,然后解编集,得到一个和经过A中的Message对象内容相同的对象。

涟漪般扩散的低频重音作基底,清脆的调子,飘上夜空。

1、IntentService的引入:

“别瞎说。是自个儿刚才唱的歌。地球人发现大家时候我唱的歌。有记录。”蓝灯笼将团结撞成褐色碎片。

 1 package com.example.clienttest;
 2 
 3 import android.app.Activity;
 4 import android.content.ComponentName;
 5 import android.content.Intent;
 6 import android.content.ServiceConnection;
 7 import android.os.Bundle;
 8 import android.os.IBinder;
 9 import android.os.RemoteException;
10 import android.util.Log;
11 import android.view.View;
12 import android.view.View.OnClickListener;
13 import android.widget.Button;
14 
15 import com.example.servicetest02.IPerson;
16 
17 
18 public class MainActivity extends Activity implements OnClickListener {
19     public static final String TAG = "MainActivity";
20     private Button button_bind_service;
21     private Button button_unbind_service;
22     private IPerson person;
23     boolean mBound = false; // 一开始,并没有和Service绑定.这个参数是用来判断绑定状态
24     // 匿名内部类:服务连接对象
25     private ServiceConnection connection = new ServiceConnection() {
26         // 当服务异常终止时会调用。注意,解除绑定服务时不会调用
27         @Override
28         public void onServiceDisconnected(ComponentName name) {
29             mBound = false; // 服务异常终止时,状态为未绑定
30         }
31         // 和服务绑定成功后,服务会回调该方法。在这个方法里调用的业务对象中的内容
32         @Override
33         public void onServiceConnected(ComponentName name, IBinder service) {
34             Log.d(TAG, "onServiceConnected");
35             person = IPerson.Stub.asInterface(service); // 得到person对象
36             Log.d("person", "person对象的内存地址是" + person); // 打印出person对象的内存地址
37             try {
38                 person.setName("生命壹号");
39                 person.setAge(22);
40                 person.setSex("男");
41                 String p = person.getPerson();
42                 Log.d("person", "person的信息是" + p);
43             } catch (RemoteException e) {
44                 // TODO Auto-generated catch block
45                 e.printStackTrace();
46             }
47             mBound = true; //true说明是绑定状态
48         }
49     };
50     @Override
51     protected void onCreate(Bundle savedInstanceState) {
52         super.onCreate(savedInstanceState);
53         setContentView(R.layout.activity_main);
54         button_bind_service = (Button) findViewById(R.id.button_bind_service);
55         button_unbind_service = (Button) findViewById(R.id.button_unbind_service);
56         button_bind_service.setOnClickListener(this);
57         button_unbind_service.setOnClickListener(this);
58     }
59     @Override
60     public void onClick(View v) {
61         switch (v.getId()) {
62         case R.id.button_bind_service:
63             Intent bindIntent = new Intent("com.example.servicetest02.MyService");
64             bindService(bindIntent, connection, BIND_AUTO_CREATE);
65             break;
66         case R.id.button_unbind_service:
67             // 如果和Service是绑定的状态,就解除绑定。
68             if (mBound) {
69                 unbindService(connection);
70                 mBound = false;
71             }
72             break;
73         default:
74             break;
75         }
76     }
77 }

不无小幼虫安全退入管道,紫幼虫和蓝幼虫才联合“刺溜”一声,藏了起来。

第四段中行使的是价值观的法门和Service建立关联,默许MainActivity和MyService在同一个线程内,倘诺将Service的android:process属性指定成:remote,此时MainActivity和MyService将在分化的线程内,不过力不从心绑定服务。

“妈,你说对了。”紫水母膨胀成灯笼,“不管爸怎么崇拜人类,大家只是难民、是盲流、是人民、是群龙无首!”

小心:唯有Activity、Service、Content
Provider可以绑定服务;BroadcastReceiver广播接收器不可以绑定服务。

人类为那一天的美折服。

2、停止一个started服务有三种艺术:

紫灯笼泄气地缩成一根灯柱。

再一次建一个工程ServiceTest03。步骤如下:

“水母应该在水里。”

(4)在MainActivity作为程序的主Activity,在里面加入发送Message音讯和创建Service连接的逻辑,代码如下:

蓝灯笼底气不足了,歌声渐渐变小,往后退。

4、AIDL(Android Interface Definition
Language)Android接口定义语言:

它们同时吸附地面,横裂成为灯笼水母。

 1         public static com.example.servicetest02.IPerson asInterface(
 2                 android.os.IBinder obj) {
 3             if ((obj == null)) {
 4                 return null;
 5             }
 6             android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
 7             if (((iin != null) && (iin instanceof com.example.servicetest.IPerson))) {
 8                 return ((com.example.servicetest.IPerson) iin);
 9             }
10             return new com.example.servicetest.IPerson.Stub.Proxy(obj);
11         }

蓝灯笼有些当机不断。

因此一个比较标准的劳动可以这么写

蓝灯笼升到城市上方。它感受到了都会种种角落的气流。

可以看到,只点击了Bind
瑟维斯按钮,不过oncreate()方法得到了实践,而onStartCommand()方法不会执行。

但它长得太像人类熟谙的灯笼水母。事到近期,它也初阶称自己“灯笼水母”。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical" >  

    <Button  
        android:id="@+id/button1_start_service"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Start Service" />  

    <Button  
        android:id="@+id/button2_stop_service"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Stop Service" />  

</LinearLayout> 

红灯笼紧随蓝灯笼,然后是紫灯笼。大大小小的灯笼水母群落,一串一串,飞往夜空。

(2)新建PersonImpl类,继承IPerson.Stub类,重写父类里的章程。代码如下:(也就是说,按照地点的java类,生成业务对象,即原理图中B应用的作业对象)

前年新年,《不设有晚报》沿袭二零一八年观念,举行史上首届“科幻春晚”。国内超级科幻小说家受邀,在给定标题为历届重阳节晚会经典节目名的原则下,在限时48钟头内高速创作,为科幻迷呈现出二十余篇风格各异的科幻小说。另有中华科幻“四大天王”携手担任嘉宾主持。阴历十月二十六至十一月十七(12月24日至四月13日)每一天中午,为各位科幻迷奉上上巳节沐日的科幻盛筵。

主导代码是第03行,固然Student类文件和本文件是在同一个包下,然则照旧要导包,否则将不能辨认Student类。然后在第06行代码中,就足以把Student这些类传递出去了。注意了,第06行再次来到的是Student类型,那不就是ADIL所支撑的自定义类型嘛。

“这个是?”年轻人问。

急需注意的是,倘若没有第17行的stopSelf(),服务一旦启动后,就会直接处在运行状态,必须调用stopService()或者stopSelf()方法才能让服务截至下来;所以大家添加了17行的stopSelf(),服务实施完结后会自动终止

它们没再用人类语言,只各伸出一缕触手,轻轻碰触,互换存储于民用的,集体意识。

public final class Messenger extends Object implements Parcelable

所幸,它们也不再变回幼虫,无限繁衍。

五、使用Bind Service完毕IPC进程间通讯:(在同一个APP内模拟)

——我回忆,你要么浅黑色的时候,就会唱最久远的曲调。

瞩目红框部分,包名是不一致等的啊。简单的讲,大家真正已经打响促成跨进程通讯了,在一个主次中访问到了其余一个程序中的方法。

“女神?那到了木星,你不叫Venus了,非要以金星城邦命名,叫了‘Colin斯’。Colin斯是淫荡之都啊。要不是Colin斯四号告诉我,我都不驾驭。”

图片 7


前日,B应用的事情对象和劳动建立好了。B应用的事体对象通过与Service绑定,让Service把业务对象揭露给了A应用或者其它的选拔。也就是说,Service最后并没有兑现工作成效。

——大家就是灯笼水母身子下游弋的那种,小牧鱼。

 

红灯笼碰撞它。

四、使用Bind Service落成Service和Activity之间的通讯

“怎么可以如此说孩子!没有人类语言,我们平素不明了思考——”

上图中,固然A应用程序想访问B应用程序中的业务对象,可以先让A绑定B应用中的Service,然后经过Service去访问B中的业务对象。我们得以用AIDL来讲述须求被别人调用的接口(即B中的业务对象)。

蓝灯笼开首暂缓地,优雅地,飘向小孩。它悲观厌世挤压体内胶质层包裹的气体,发出曲调绵长的歌声,还押了人类的脚底。

(1)现在修改AndroidManifest.xml中的代码,给MyService加上一个action,如下所示:

“闭嘴!”蓝灯笼立刻膨胀成圆滚滚的圆球,“别忘了,当初管控委称大家游击队,是你查了人类书籍,告诉自己游击才是持久战的常有。你有本事不要看人类的书!”

俺们来大概分析一下以此自动生成的Java文件。完整版代码如下:

“快学大姨!”它说。

尽管上边的那种写法并不复杂,但总会有部分程序猿忘记打开线程,或者忘记调用stopSelf()方法。为了可以简不难单地开创一个异步的、会活动甘休的服务,Android专门提供了一个IntentService类,这几个类就很好的化解了上边所关联的三种进退两难。此外,可以启动IntentService很多次,而每一个耗时操作会以工作行列的法门在IntentService的onHandleIntent()回调方法中推行,并且每一次只会进行一个工作线程,执行完首个后,再履行第四个,以此类推。

“灯笼水母只在欢快时候,发出歌曲的同一的动静。它们母星被开发,就少有连锁数据了。这对人类而言,不是好事……”

文件结构如下:

紫灯笼靠近它的父三姨,没有伸出触手,而竭尽全力地将伞形躯体一收一合。

  • 1、Bind Service的介绍
  • 2、完成Service和Activity之间通讯步骤
  • 3、started服务与bind服务的界别
  • 4、Service的生命周期

“快点,要不姨妈发怒了。”蓝灯笼温柔地命令。

然后新建一个新的工程,起名为ClientTest,大家就尝试在那个顺序中远程调用MyService中的方法。

不,它感受到了其他存活于城市的灯笼水母。

我们在布局文件中进入了七个按钮,一个用于启动Service,一个用来甘休Service。

红幼虫贴着管道,用高频音:“叮、叮、叮……”

点击Unbind Service按钮后,再度点击Unbind
Service按钮按钮引发的题目:

小说头阵公众平台:“不设有”(搜索公众号:non-exist-FAA)

为掩护原创内容,所有情节欢迎个人转账,媒体转发请邮件联系

未经授权行使会招致没有前途

其一文件里,添加大家要求的工作方法。第01行是包名。注意不要写public等修饰符。(要是那几个文件写错了,程序会报错,前边的Java文件也不会自从生成)

中国青年网、中青报、未读、上海早报

很多Android初学者都可能会有诸如此类的可疑,Service和Thread到底有啥样关联吗?何时应该用Service,哪天又应当用Thread?答案可能会有点让你大吃一惊,因为Service和Thread之间没有其余涉及!

于是,就在旧历的三月三十日,地球上的灯笼水母纷繁升上夜空,共同歌唱古老的曲调,押着宇宙节律的韵脚,群落之间持续连接,布满苍穹,明灯一样,照亮了看不见星星的黑夜,再也尚未落回地面。

概念好服务之后,接下去看一下怎么着启动和停止一个劳动,那紧如果凭借Intent来落到实处的。注意startService()和stopService()方法都是概念在Context类当中的,所以可以在MainActivity中一贯调用那八个法子。

表演:双翅目

关于多线程的Handler机制,若是不知情的话,可以参照本人此外一篇博客:

“叔伯三姑生婴孩的办法。”

 1 package com.example.servicetest03;
 2 
 3 import android.app.Activity;
 4 import android.content.ComponentName;
 5 import android.content.Intent;
 6 import android.content.ServiceConnection;
 7 import android.os.Bundle;
 8 import android.os.IBinder;
 9 import android.os.RemoteException;
10 import android.view.View;
11 import android.view.View.OnClickListener;
12 import android.widget.Button;
13 import android.widget.Toast;
14 
15 
16 public class MainActivity extends Activity implements OnClickListener {
17     public static final String TAG = "MainActivity";
18     private Button button1_setStudent;
19     private Button button2_getStudent;
20     private IStudent studentImpl;
21     boolean mBound = false; // 一开始,并没有和Service绑定.这个参数是用来判断绑定状态
22 
23     @Override
24     protected void onCreate(Bundle savedInstanceState) {
25         super.onCreate(savedInstanceState);
26         setContentView(R.layout.activity_main);
27         button1_setStudent = (Button) findViewById(R.id.button1_setStudent);
28         button2_getStudent = (Button) findViewById(R.id.button2_getStudent);
29         button1_setStudent.setOnClickListener(this);
30         button2_getStudent.setOnClickListener(this);
31     }    
32 
33     
34     // 匿名内部类:服务连接对象
35     private ServiceConnection connection = new ServiceConnection() {
36         // 当服务异常终止时会调用。注意,解除绑定服务时不会调用
37         @Override
38         public void onServiceDisconnected(ComponentName name) {
39             mBound = false; // 服务异常终止时,状态为未绑定
40         }
41         // 和服务绑定成功后,服务会回调该方法。在这个方法里调用的业务对象中的内容
42         @Override
43         public void onServiceConnected(ComponentName name, IBinder service) {
44             studentImpl = IStudent.Stub.asInterface(service); // 得到person对象
45             mBound = true; //true说明是绑定状态
46         }
47     };
48     
49     //程序启动时,开始绑定服务
50     @Override
51     protected void onStart() {
52         super.onStart();
53         Intent bindIntent = new Intent(this, MyService.class);
54         bindService(bindIntent, connection, BIND_AUTO_CREATE);
55     }
56     
57     //程序退出时,取消绑定服务
58     @Override
59     protected void onDestroy() {
60         super.onDestroy();
61         // 如果和Service是绑定的状态,就解除绑定。
62         if (mBound) {
63             unbindService(connection);
64             mBound = false;
65         }
66     }
67     
68     
69     @Override
70     public void onClick(View v) {
71         switch (v.getId()) {
72         //点击button1_setStudent按钮,设置Student的值
73         case R.id.button1_setStudent:
74             try {
75                 studentImpl.setStudent("生命壹号", "男");
76                 Toast.makeText(this, "设置成功", Toast.LENGTH_SHORT).show();
77             } catch (RemoteException e) {
78                 // TODO Auto-generated catch block
79                 e.printStackTrace();
80             }
81             break;
82         //点击button2_getStudent按钮,获取Student的值
83         case R.id.button2_getStudent:
84             Student s;
85             try {
86                 s = studentImpl.getStudent();
87                 Toast.makeText(this, "name="+s.getName()+",sex="+s.getSex(), Toast.LENGTH_SHORT).show();
88             } catch (RemoteException e) {
89                 // TODO Auto-generated catch block
90                 e.printStackTrace();
91             }
92             break;
93 
94         default:
95             break;
96         }
97     }
98 }

人类文明到处的灯笼水母,纷繁过来地球,参预歌唱。

 

外界传来巡视车熄火儿的响声。

最近让大家重新运行一下先后吗,在MainActivity中点击一下Bind
Service按钮,LogCat里的打印日志如下图所示:

未来局签约小编,代表作《基因源》《公鸡王子》,喜爱理论与幻想的结合物,希望从实际元素中开掘越多创意点。

  • 通过started情势的劳动会直接运行在后台,必要由组件本身或外部组件来终止服务才会以停止运行
  • bind方式的劳务,生命周期就要借助绑定的零件

直径约30毫米的紫灯笼飘向蓝灯笼:“为何不留在北美洲。”

 

红灯笼狠狠撞向墙壁。它的散装还未落地,就改为藏黑色幼虫。

  • 服务对象同时只会有一个
  • 默许情形下,一个started的Service与开行他的组件在同一个线程中。上边的实例中,服务就是在主线程中运行的,如果是在劳务中成就耗时操作的话,不难造成主线程阻塞。

“灯笼水母集体意识深厚。拥有公共意识的公司军。不可以使用水来土屯的办法了。”

onStartCommand方法执行时,重返的是一个int型。这几个整型可以有多少个重返值:START_NOT_STICKY、START_STICKY、START_REDELIVER_INTENT

“还有格外,流窜到木卫二时横裂的,叫‘欧罗巴’,到了北美洲,我都不佳意思开口叫孩子。”

既然是在在同一个APP内模拟进度间通讯,其实就是完毕进度内通讯,可是原理都是一致的嘛。

“我最喜爱的科幻春晚节目”评选

 <service android:name=".MyService">        </service>

末段,外来生物管控委的老警察,提议了制造的答疑逻辑。

我们在第六段中的My瑟维斯02这一个工程文件中展开修改。代码已毕如下:

▲ 管控委走了,都出来吧(图源:deviantart.com)

图片 8

“怎么倒霉了?”

那边首先要提供一个无参的构造方法,并且必须在其中间调用父类的有参构造方法(9至12行),我们在第10行手动将劳动的名字改为“MyIntentService”。

“最开首就不应当糟蹋了它们的母星!”老警察升高音量:“就拿灯笼水母说,它们和人类智慧杰出,只是文明等级低。开发者还真把它们当水母了。大搞开采。原本灯笼水母的例行繁殖方式,像人类一夫一妻,最多三胎。但环境恶劣,它们会应激反应,采纳退化为幼虫再分歧生长的法子。灯笼幼虫大致能适应星际旅行的兼具恶劣气象。是人类让它们各处繁衍。”

(2)新建StudentImpl类,继承IStudent.Stub类。代码如下:(也就是说,按照步骤(1)中的java类,生成业务对象,即原理图中B应用的作业对象)

“事已至此,总不能再造一个母星。况且它们性格脆弱,崇拜人类,赖在此时不走。”

基本代码:12行和35行。

“检测到鸣叫。”

近日大家总计一下:

“不、不是水母,是外星人,但长得像灯笼水母,繁衍格局也专程像。”她抱起孩子。

因为那么些服务在运行截止后会自动终止,所以大家在onDestroy()方法中打印日志验证一下。

科幻春晚分答分会场

  • started服务能够给启动的服务目的传递参数,但不可以得到服务中艺术的重临值
  • bind服务可以给启动的劳动目的传递参数,也得以透过绑定的事务对象获得再次来到结果

——大家重临吗。

大旨代码是35行,再次回到这一个mBinder,是一个IBinder类型,就可以把那几个IBinder类型传递到MainActivity中,从而调用瑟维斯里面的格局。下边就要看一看,在MainActivity是哪些调用Service里面的多个艺术的。

但它退出了公共意识,轻轻说:“回不去了,回不去了。”

(2)办法二:新建别的一个工程,真正兑现长途通讯。那就是我们下一段(第六段)要讲的内容。

“——幼虫变水母,数量最少翻十倍;水母退化幼虫,再翻十倍。哪是管控委说的宽容游击队,大概是宽容公司军!”

 

“年轻人的想法啊。”老警察叹气,“刚才督察主题说,聚集巨大灯笼水母,为啥?”

新建一个Android项目ServiceTest,具体步骤如下:

5、IPC(进程间通信)具体的步子如下:

(5)在activity_main.xml中添加三个按钮button1_setStudent和button2_getStudent。activity_main.xml的代码如下:

今天再度运行一下MyService02这几个顺序,那样就把远程Service端的行事全方位做到了。

欢迎转发,但请保留文章原来出处→_→ 

来看上面的这张原理图:

俺们在这些类中放入了name和age这多个参数,并完毕了Parcelable接口。注意第44行至55行代码的改动。

咱俩照例在第二段中的项目ServiceTest基础上展开改动。

从Android
SDK中对IBinder/Binder的分解可见,IBinder/Binder是Android远程对象的宗旨接口,它是Android用于提供高质量IPC通讯而规划的一套轻量级远程调用机制的主干部分。该接口描述了与一个远道对象进行通讯的虚幻协议。

主题代码:31行至32行、35行至36行。

对选拔开发者来说,Android的IBinder/Binder框架落成了Android的IPC通讯。当然,IBinder/Binder框架也足以用来促成进度内通信(本地通讯),也可以完成经过间通讯(远程通讯)

注:bindService()和unbindService()方法都是Context类中的方法。

瑟维斯可以在很多场合使用,比如播放多媒体的时候用户启动了别的Activity,此时要在后台继续播放;比如检测SD闪存卡上文件的生成;比如在后台记录你的地理音信位置的转移等等,总而言之服务是藏在后台的。

(3)在activity_main.xml中持续添加四个按钮button3_bind_service和button4_unbind_service,用于绑定服务和注销绑定服务。最终,activity_main.xml的完全代码如下:

花了周末二日的年月,整理了弹指间当作Android四大组件之一的Service的基础知识,通过那篇文章,应该可以通晓:对Service的知道、在如何地点使用、怎么利用、要留意哪些难题等。

 

上边就因此代码来落成。

着力代码:16至28行、31行、37行。

<service android:name=".MyService"> </service>

(1)办法一:将本地的Service设置为远程。只需求在清单文件中登记Service的时候将它的android:process属性指定成:remote就足以了,代码如下所示:

再重回看IPerson.java文件的第9行定义了那样一个抽象类:

(4)在清单文件中添加权限:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button1_start_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Service" />

    <Button
        android:id="@+id/button2_stop_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Stop Service" />

    <Button
        android:id="@+id/button3_bind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="bind Service" />

    <Button
        android:id="@+id/button4_unbind_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="unbind Service" />

</LinearLayout> 

大家还足以在正在“设置–应用—运行”中找到那个服务,如下图所示:

 1 package com.example.servicetest;
 2 
 3 import android.app.Service;
 4 import android.content.Intent;
 5 import android.os.IBinder;
 6 import android.util.Log;
 7 
 8 public class MyService extends Service {  
 9       
10     public static final String TAG = "MyService";  
11   
12     //创建服务时调用
13     @Override  
14     public void onCreate() {  
15         super.onCreate();  
16         Log.d(TAG, "onCreate");  
17     }  
18   
19     //服务执行的操作
20     @Override  
21     public int onStartCommand(Intent intent, int flags, int startId) {  
22         Log.d(TAG, "onStartCommand");  
23         return super.onStartCommand(intent, flags, startId);  
24     }  
25       
26     //销毁服务时调用
27     @Override  
28     public void onDestroy() {  
29         super.onDestroy();  
30         Log.d(TAG, "onDestroy");  
31     }  
32   
33     @Override  
34     public IBinder onBind(Intent intent) {  
35         return null;  
36     }  
37 }

分析:

图片 9

37行中,将IBinder类型重回之后,就已经和Messenger实行绑定了。

【前言】

(1)新建一个MessengerService类,继承Service类,代码如下:

继承,新建IStudent.aidl,作为要求长途传递的事体方法。代码如下:

 1 package com.example.servicetest;
 2 
 3 import android.app.Service;
 4 import android.content.Intent;
 5 import android.os.Binder;
 6 import android.os.IBinder;
 7 import android.util.Log;
 8 
 9 public class MyService extends Service {  
10       
11     public static final String TAG = "MyService";  
12   
13     private MyBinder mBinder = new MyBinder();  
14   
15     @Override  
16     public void onCreate() {  
17         super.onCreate();  
18         Log.d(TAG, "onCreate");  
19     }  
20   
21     @Override  
22     public int onStartCommand(Intent intent, int flags, int startId) {  
23         Log.d(TAG, "onStartCommand");  
24         return super.onStartCommand(intent, flags, startId);  
25     }  
26   
27     @Override  
28     public void onDestroy() {  
29         super.onDestroy();  
30         Log.d(TAG, "onDestroy");  
31     }  
32   
33     @Override  
34     public IBinder onBind(Intent intent) {  
35         return mBinder;  //在这里返回新建的MyBinder类
36     }  
37   
38     //MyBinder类,继承Binder:让里面的方法执行下载任务,并获取下载进度
39     class MyBinder extends Binder {  
40   
41         public void startDownload() {  
42             Log.d("TAG", "startDownload() executed");  
43             // 执行具体的下载任务  
44         }
45         public int getProgress(){
46             Log.d("TAG", "getProgress() executed");  
47             return 0;
48         }
49   
50     }  
51   
52 }  

上边第06行的iin代表的是,查询当地对象回来的结果。

  • 创建一个类继承android.app.Service类,达成抽象方法onBind(),重写onCreate()、onStartCommand()、onDestry();
  • 在清单文件中安排Service。

(1)新建一个MyIntentService类,继承自IntentService,相提并论写父类的onHandleIntent()方法,代码如下:

  • 率先次先利用started方式来启动一个劳动
  • 随后可以使用bind的不二法门绑定服务,从而得以直接调用业务方法获得重回值

初始和甘休服务:

那就是说接下去的手续就和本段中的第6小节一样了,就不再多解释了,那里只贴代码:

主题代码是第38行:可以看到,那里首先利用了MyAIDLService.Stub.asInterface()方法将盛传的IBinder对象传换成了IPerson对象,接下去就足以调用在IPerson.aidl文件中定义的拥有接口了(41至44行)。调用之后,大家在后台打印输出。

要旨步骤如下:

上图的红框部分显得,Service和Activity并非在同一个线程内,连包名都不同。而IPeron也并非是地方的IPeron。

假定要让A应用来访问,该怎么做吗?

因为PersonImpl类继承了IPerson.Stub,而Stub继承了Binder,Binder又达成了IBinder。所以,PersonImpl可以知道为一个IBinder。于是能够在第35行重返PersonImpl的实例。

 1 package com.example.servicetest;
 2 
 3 import android.app.Activity;
 4 import android.content.Intent;
 5 import android.os.Bundle;
 6 import android.view.View;
 7 import android.view.View.OnClickListener;
 8 import android.widget.Button;
 9 
10 
11 public class MainActivity extends Activity implements OnClickListener {  
12       
13     private Button button1_start_service;  
14   
15     private Button button2_stop_service;  
16   
17     @Override  
18     protected void onCreate(Bundle savedInstanceState) {  
19         super.onCreate(savedInstanceState);  
20         setContentView(R.layout.activity_main);  
21         button1_start_service = (Button) findViewById(R.id.button1_start_service);  
22         button2_stop_service = (Button) findViewById(R.id.button2_stop_service);  
23         button1_start_service.setOnClickListener(this);  
24         button2_stop_service.setOnClickListener(this);  
25     }  
26   
27     @Override  
28     public void onClick(View v) {  
29         switch (v.getId()) {  
30         case R.id.button1_start_service:  
31             Intent startIntent = new Intent(this, MyService.class);  
32             startService(startIntent);  
33             break;  
34         case R.id.button2_stop_service:  
35             Intent stopIntent = new Intent(this, MyService.class);  
36             stopService(stopIntent);  
37             break;  
38         default:  
39             break;  
40         }  
41     }  
42   
43 }

图片 10

可以见到,在Start
Service按钮的点击事件里,咱们营造出了一个Intent对象,并调用startService()方法来启动MyService。然后在Stop
Serivce按钮的点击事件里,大家一致创设出了一个Intent对象,并调用stopService()方法来终止MyService。代码的逻辑分外简单。

图片 11

从而有许三人会把它们联系起来,主要就是因为Service的后台概念。Thread大家大家都了然,是用以开启一个子线程,在此间去实践一些耗时操作就不会堵塞主线程的运转。而Service我们最初知道的时候,总会觉得它是用来拍卖部分后台职分的,一些相比耗时的操作也得以放在此处运行,那就会令人发出模糊了。可是,假如自身报告您瑟维斯其实是运作在主线程里的,你还会以为它和Thread有怎样关系啊?

(2)在劳动中间(onStartCommand方法内部)使用stopSelf()方法。

俺们在第75行、86至87行使用到了IStudent中的业务方法。

后台打印日志如下:

parcelable Student;
 1 package com.example.servicetest02;
 2 
 3 import android.app.Activity;
 4 import android.content.ComponentName;
 5 import android.content.Intent;
 6 import android.content.ServiceConnection;
 7 import android.os.Bundle;
 8 import android.os.IBinder;
 9 import android.util.Log;
10 import android.view.View;
11 import android.view.View.OnClickListener;
12 import android.widget.Button;
13 
14 public class MainActivity extends Activity implements OnClickListener {
15     private Button button1_start_service;
16     private Button button2_stop_service;
17     private Button button3_bind_service;
18     private Button button4_unbind_service;
19     private MyService.MyBinder myBinder;
20     
21     boolean mBound = false; //一开始,并没有和Service绑定.这个参数是用来显示绑定状态
22     
23     //匿名内部类:服务连接对象
24     private ServiceConnection connection = new ServiceConnection() {
25         
26         //当服务异常终止时会调用。注意,解除绑定服务时不会调用
27         @Override
28         public void onServiceDisconnected(ComponentName name) {
29             mBound = false; //服务异常终止时,状态为未绑定
30         }
31         
32         //和服务绑定成功后,服务会回调该方法
33         @Override
34         public void onServiceConnected(ComponentName name, IBinder service) {
35             myBinder = (MyService.MyBinder) service;
36             //在Activity中调用Service里面的方法
37             myBinder.startDownload();
38             myBinder.getProgress();
39             mBound = true; //true说明是绑定状态
40         }
41     };
42     @Override
43     protected void onCreate(Bundle savedInstanceState) {
44         super.onCreate(savedInstanceState);
45         setContentView(R.layout.activity_main);
46         button1_start_service = (Button) findViewById(R.id.button1_start_service);
47         button2_stop_service = (Button) findViewById(R.id.button2_stop_service);
48         button3_bind_service = (Button) findViewById(R.id.button3_bind_service);
49         button4_unbind_service = (Button) findViewById(R.id.button4_unbind_service);
50         button1_start_service.setOnClickListener(this);
51         button2_stop_service.setOnClickListener(this);
52         button3_bind_service.setOnClickListener(this);
53         button4_unbind_service.setOnClickListener(this);
54     }
55     @Override
56     public void onClick(View v) {
57         switch (v.getId()) {
58         case R.id.button1_start_service:
59             Intent startIntent = new Intent(this, MyService.class);
60             startService(startIntent);
61             break;
62         case R.id.button2_stop_service:
63             Intent stopIntent = new Intent(this, MyService.class);
64             stopService(stopIntent);
65             break;
66         case R.id.button3_bind_service:
67             Intent bindIntent = new Intent(this, MyService.class);
68             bindService(bindIntent, connection, BIND_AUTO_CREATE);
69             break;
70         case R.id.button4_unbind_service:
71             //如果和Service是绑定的状态,就解除绑定。
72             if(mBound){
73                 unbindService(connection);
74                 mBound=false;
75             }
76             break;
77 
78         default:
79             break;
80         }
81     }
82 }

2、IntentService的作用:

六、使用Bind Service已毕IPC进程间通讯:(八个APP之间)
七、Messenger的使用

四、使用Bind Service完结Service和Activity之间的通讯

图片 12

内需留意的是:

有没有哪些措施能让它们俩的关联更加多一些吧?比如说在Activity中指挥Service去干什么,Service就去干什么。当然可以,只要求让Activity和Service建立关系就好了。

基本代码:14至19行,在子线程中处理具体的逻辑。

(3)新建Service类,代码如下:

(3)在MainActivity中进入和长距离的MyService建立关系的代码,如下所示:

  • 自定义类落成Parcelable接口
  • 新建同名的aidl文件,表明这些Parcelable类型的自定义类
  • 在必要长途传递的aidl文件中导包,引用进来

点击button1_start_service,服务启动。既然已经将Service的android:process属性指定成:remote,此时Service和Activity不在同一个线程内,那么固然在Service的onStartCommand()方法中实践耗时操作而不重复开启子线程,程序也不会阻塞。

  • 1、Bind Service的介绍
  • 2、在客户端绑定一个劳动的步子
  • 3、IPC(Inter-Process Communication)进度间通讯机制
  • 4、AIDL(Android Interface Definition Language)Android接口定义语言
  • 5、IPC(进度间通信)具体的步调如下
  • 6、让Activity与一个远道Service建立关联的步骤:(在同一个APP内模拟)
  • 7、AIDL匡助的自定义数据类型

 

兑现进程间通讯的三个点子:

咱俩依旧先回过头来再巩固一下本段中AIDL的知识吧。

 1 package com.example.servicetest;
 2 
 3 import android.app.IntentService;
 4 import android.content.Intent;
 5 import android.util.Log;
 6 
 7 public class MyIntentService extends IntentService{
 8 
 9     public MyIntentService() {
10         super("MyIntentService");//调用父类有参构造函数。这里我们手动给服务起个名字为:MyIntentService
11         // TODO Auto-generated constructor stub
12     }
13 
14     //该方法在会在一个单独的线程中执行,来完成工作任务。任务结束后,该Service自动停止
15     @Override
16     protected void onHandleIntent(Intent intent) {
17         // TODO Auto-generated method stub
18         for(int i = 0;i<3;i++) {
19             //打印当前线程的id
20             Log.d("MyIntentService","IntentService线程的id是:"+Thread.currentThread().getId());
21             try {
22                 Thread.sleep(1000);
23             } catch (InterruptedException e) {
24                 // TODO Auto-generated catch block
25                 e.printStackTrace();
26             }
27         }        
28     }
29 
30     @Override
31     public void onDestroy() {
32         // TODO Auto-generated method stub
33         super.onDestroy();
34         Log.d("MyIntentService","onDestroy");
35     }
36 }

(6)MainActivity中的代码,如下所示:

 1 package com.example.servicetest03;
 2 
 3 import android.app.Service;
 4 import android.content.Intent;
 5 import android.os.IBinder;
 6 import android.util.Log;
 7 
 8 public class MyService extends Service {  
 9       
10     public static final String TAG = "MyService";  
11   
12     private  StudentImpl studentImpl ;
13   
14     @Override  
15     public void onCreate() {  
16         super.onCreate();  
17         Log.d(TAG, "onCreate");  
18     }  
19   
20     @Override  
21     public int onStartCommand(Intent intent, int flags, int startId) {  
22         Log.d(TAG, "onStartCommand");  
23         return super.onStartCommand(intent, flags, startId);  
24     }  
25   
26     @Override  
27     public void onDestroy() {  
28         super.onDestroy();  
29         Log.d(TAG, "onDestroy");  
30     }  
31   
32     @Override  
33     public IBinder onBind(Intent intent) { 
34         Log.d("MyService", "onBind");
35         studentImpl = new StudentImpl();
36         return studentImpl;  //在这里返回新建的MyBinder类
37     }
38   
39 }

1、Bind Service的介绍:

在onServiceConnected()方法中,我们又通过向下转型取得了MyBinder的实例(34行),有了这几个实例,Activity和Service之间的关系就变得十分紧密了。现在大家得以在Activity中按照实际的景观来调用MyBinder中的任何public方法(36、37行),即落实了Activity指挥Service干什么Service就去干什么的效用。

运作程序,点击按钮,效果如下:

我们在本段中的第4小结讲到,AIDL协助的连串:八大主导数据类型、String类型、CharSequence、List、Map、自定义,那我们就来详细说下这一个自定义数据类型。

那样的话,一个简约的包括Service效率的先后就写好了。

图片 13

注解服务启动成功。

  • 1、IntentService的引入
  • 2、IntentService的作用
  • 3、IntentService的用法
  • 4、Service和Thread的关系

IPerson.java

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <Button
        android:id="@+id/button1_setStudent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="调用setStudent方法" />

    <Button
        android:id="@+id/button2_getStudent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="调用getStudent方法" />
</LinearLayout>

 

其实支出中的技巧;

3、IPC(Inter-Process Communication)进程间通信机制:

由于那是在不相同的进程之间传递数据,Android对那类数据的格式接济是老大有限的,基本上只好传递Java的中坚数据类型、字符串、List或Map等。那么一旦自己想传递一个自定义的类该如何做呢?这就务要求让那个类去落实Parcelable接口,并且要给这一个类也定义一个同名的AIDL文件进行宣示。那有些内容并不复杂,而且和Service关系不大。具体操作如下:

 

三、IntentService

证实那几个MessengerService和常见Service一样,也是运行在主线程当中的。

那么一旦本身再连接点四次button1_start_service按钮,后台增添的日记如下:

Intent bindIntent = new Intent(this, MyService.class);
bindService(bindIntent, connection, BIND_AUTO_CREATE);

除此以外索要留意,任何一个Service在总体应用程序范围内都是通用的,即MyService不仅可以和MainActivity建立关联,还是可以和其他一个Activity建立关系,而且在建立关系时它们都得以收获到平等的MyBinder实例。

六、使用Bind 瑟维斯已毕IPC进度间通讯:(四个APP之间)

着力代码:12行、35行、36行。

图片 14

除此以外注意粉红色箭头处,可以见见,这么些person其实就是personImpl,因为是在本地调用。所以说,近来的跨进度通讯其实并从未什么样本质上的法力,因为这只是在一个Activity里调用了同一个应用程序的瑟维斯里的法子。而跨进度通讯的真的含义是为了让一个应用程序去拜谒另一个应用程序中的Service,以落到实处共享Service的成效。那么下边大家自然要上学一下,如何才能在其他的应用程序中调用到My瑟维斯里的章程。

<service android:name=".MyIntentService"> </service>

文章来源:http://www.cnblogs.com/smyhvae/p/4070518.html

点击按钮(72行),发送音讯,让Messenger瑟维斯类里的Messenger去接受,然后交给handler去处理,从而执行handleMessage()里方法,也就是说,执行了Service里面的法门。

后台打印日志如下:

 1 package com.example.servicetest;
 2 
 3 import android.app.Activity;
 4 import android.content.ComponentName;
 5 import android.content.Intent;
 6 import android.content.ServiceConnection;
 7 import android.os.Bundle;
 8 import android.os.IBinder;
 9 import android.util.Log;
10 import android.view.View;
11 import android.view.View.OnClickListener;
12 import android.widget.Button;
13 
14 public class MainActivity extends Activity implements OnClickListener {
15 
16     private Button button1_start_service;
17     private Button button2_stop_service;
18     private Button button3_bind_service;
19     private Button button4_unbind_service;
20 
21     private MyService.MyBinder myBinder;
22     
23     //匿名内部类:服务连接对象
24     private ServiceConnection connection = new ServiceConnection() {
25         
26         //当服务异常终止时会调用。注意,解除绑定服务时不会调用
27         @Override
28         public void onServiceDisconnected(ComponentName name) {
29         }
30         
31         //和服务绑定成功后,服务会回调该方法
32         @Override
33         public void onServiceConnected(ComponentName name, IBinder service) {
34             myBinder = (MyService.MyBinder) service;
35             //在Activity中调用Service里面的方法
36             myBinder.startDownload();
37             myBinder.getProgress();
38         }
39     };
40 
41     @Override
42     protected void onCreate(Bundle savedInstanceState) {
43         super.onCreate(savedInstanceState);
44         setContentView(R.layout.activity_main);
45         button1_start_service = (Button) findViewById(R.id.button1_start_service);
46         button2_stop_service = (Button) findViewById(R.id.button2_stop_service);
47         button3_bind_service = (Button) findViewById(R.id.button3_bind_service);
48         button4_unbind_service = (Button) findViewById(R.id.button4_unbind_service);
49 
50         button1_start_service.setOnClickListener(this);
51         button2_stop_service.setOnClickListener(this);
52         button3_bind_service.setOnClickListener(this);
53         button4_unbind_service.setOnClickListener(this);
54     }
55 
56     @Override
57     public void onClick(View v) {
58         switch (v.getId()) {
59         case R.id.button1_start_service:
60             Intent startIntent = new Intent(this, MyService.class);
61             startService(startIntent);
62             break;
63         case R.id.button2_stop_service:
64             Intent stopIntent = new Intent(this, MyService.class);
65             stopService(stopIntent);
66             break;
67         case R.id.button3_bind_service:
68             Intent bindIntent = new Intent(this, MyService.class);
69             bindService(bindIntent, connection, BIND_AUTO_CREATE);
70             break;
71         case R.id.button4_unbind_service:
72             unbindService(connection);
73             break;
74 
75         default:
76             break;
77         }
78     }
79 
80 }

图片 15

其一绑定是异步的,bind瑟维斯()方法立时赶回,并且不给客户端再次来到IBinder对象。要接过IBinder对象,客户端必须创制一个ServiceConnection类的实例,并且把那么些实例传递给bindService()方法。ServiceConnection对象涵盖了一个系统调用的传递IBinder对象的回调方法。

专注:唯有Activity、Service、Content
Provider可以绑定服务;BroadcastReceiver广播接收器不可能绑定服务。

既然如此在瑟维斯里也要创造一个子线程,那干什么不直接在Activity里创立呢?那是因为Activity很难对Thread进行支配,当Activity被销毁之后,就一直不其余其余的法子可以再重新得到到以前创建的子线程的实例;而且在一个Activity中开创的子线程,另一个Activity不可能对其展开操作。但是Service就分化了,所有的Activity都足以与Service进行关联,然后能够很有利地操作其中的艺术,尽管Activity被销毁了,之后倘诺重新与瑟维斯建立关联,就又可以得到到原来的Service中Binder的实例。因而,使用Service来处理后台义务,Activity就足以放心地finish,完全不须要担心无法对后台职分举办支配的情形。

运作方面的次序,点击button1_start_service按钮,启动服务,后台打印日志如下:

若果要让A应用来做客,该如何是好啊?

上一段中的跨进度通讯其实并从未什么样本质上的功能,因为那只是在一个Activity里调用了同一个应用程序的Service里的情势。而跨进度通信的确实意义是为了让一个应用程序去拜访另一个应用程序中的Service,以落到实处共享Service的法力。那么下边我们本来要上学一下,怎么样才能在别的的应用程序中调用到MyService里的法门。

 1 package com.example.messengertest;
 2 
 3 import android.app.Service;
 4 import android.content.Intent;
 5 import android.os.Handler;
 6 import android.os.IBinder;
 7 import android.os.Message;
 8 import android.os.Messenger;
 9 import android.util.Log;
10 import android.widget.Toast;
11 
12 public class MessengerService extends Service{
13 
14     public static final int MSG_SAY_HELLO = 1;
15     
16     private Handler handler = new Handler() {
17         public void handleMessage(Message msg) {
18             switch (msg.what) {
19             case MSG_SAY_HELLO:
20                 //在服务里定义业务方法
21                 Toast.makeText(MessengerService.this, "hello", Toast.LENGTH_SHORT).show();
22                 Log.d("MessengerService", "MessengerService thread id is " + Thread.currentThread().getId()); //打印MessengerService的线程id
23                 break;
24             default:
25                 break;
26             }
27         }
28     };
29     
30     
31     private Messenger messenger = new Messenger(handler);
32     
33     
34     @Override
35     public IBinder onBind(Intent intent) {
36         // TODO Auto-generated method stub
37         return messenger.getBinder();
38     }
39 }

具体步骤如下:

在第四段中大家已经明白,假如想要让Activity与Service之间建立关系,要求调用bindService()方法,并将Intent作为参数传递进去,在Intent里指定好要绑定的Service,大旨代码如下:

<service android:name=".MyService" > </service> 

可以阅览,在IInterface接口里,定义了一个接口IBinder,那是IPC机制的主导接口。

(4)在清单文件中添加权限:

(4)调用unbindService()方法断开与劳动的链接。

此后,程序运行的时候使用的是其一Java文件,与aidl文件就不曾涉嫌了。

ClientTest中的Activity假设想要和MyService建立关联其实也简单,首先须求将IPerson.aidl文件从ServiceTest02项目中拷贝过来,注意要将原始的包路径一起拷贝过来,落成后项目标协会如下图所示:

添加的代码是第21行、29行、72行至74行。

<service android:name=".MyService"> </service> 
  1 /*
  2  * This file is auto-generated.  DO NOT MODIFY.
  3  * Original file: E:\\workspace\\xiongdilian\\ServiceTest02\\src\\com\\example\\servicetest02\\IPerson.aidl
  4  */
  5 package com.example.servicetest02;
  6 
  7 public interface IPerson extends android.os.IInterface {
  8     /** Local-side IPC implementation stub class. */
  9     public static abstract class Stub extends android.os.Binder implements
 10             com.example.servicetest02.IPerson {
 11         private static final java.lang.String DESCRIPTOR = "com.example.servicetest02.IPerson";
 12 
 13         /** Construct the stub at attach it to the interface. */
 14         public Stub() {
 15             this.attachInterface(this, DESCRIPTOR);
 16         }
 17 
 18         /**
 19          * Cast an IBinder object into an com.example.servicetest02.IPerson
 20          * interface, generating a proxy if needed.
 21          */
 22         public static com.example.servicetest02.IPerson asInterface(
 23                 android.os.IBinder obj) {
 24             if ((obj == null)) {
 25                 return null;
 26             }
 27             android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
 28             if (((iin != null) && (iin instanceof com.example.servicetest02.IPerson))) {
 29                 return ((com.example.servicetest02.IPerson) iin);
 30             }
 31             return new com.example.servicetest02.IPerson.Stub.Proxy(obj);
 32         }
 33 
 34         @Override
 35         public android.os.IBinder asBinder() {
 36             return this;
 37         }
 38 
 39         @Override
 40         public boolean onTransact(int code, android.os.Parcel data,
 41                 android.os.Parcel reply, int flags)
 42                 throws android.os.RemoteException {
 43             switch (code) {
 44             case INTERFACE_TRANSACTION: {
 45                 reply.writeString(DESCRIPTOR);
 46                 return true;
 47             }
 48             case TRANSACTION_setName: {
 49                 data.enforceInterface(DESCRIPTOR);
 50                 java.lang.String _arg0;
 51                 _arg0 = data.readString();
 52                 this.setName(_arg0);
 53                 reply.writeNoException();
 54                 return true;
 55             }
 56             case TRANSACTION_setSex: {
 57                 data.enforceInterface(DESCRIPTOR);
 58                 java.lang.String _arg0;
 59                 _arg0 = data.readString();
 60                 this.setSex(_arg0);
 61                 reply.writeNoException();
 62                 return true;
 63             }
 64             case TRANSACTION_setAge: {
 65                 data.enforceInterface(DESCRIPTOR);
 66                 int _arg0;
 67                 _arg0 = data.readInt();
 68                 this.setAge(_arg0);
 69                 reply.writeNoException();
 70                 return true;
 71             }
 72             case TRANSACTION_getPerson: {
 73                 data.enforceInterface(DESCRIPTOR);
 74                 java.lang.String _result = this.getPerson();
 75                 reply.writeNoException();
 76                 reply.writeString(_result);
 77                 return true;
 78             }
 79             }
 80             return super.onTransact(code, data, reply, flags);
 81         }
 82 
 83         private static class Proxy implements com.example.servicetest02.IPerson {
 84             private android.os.IBinder mRemote;
 85 
 86             Proxy(android.os.IBinder remote) {
 87                 mRemote = remote;
 88             }
 89 
 90             @Override
 91             public android.os.IBinder asBinder() {
 92                 return mRemote;
 93             }
 94 
 95             public java.lang.String getInterfaceDescriptor() {
 96                 return DESCRIPTOR;
 97             }
 98 
 99             @Override
100             public void setName(java.lang.String name)
101                     throws android.os.RemoteException {
102                 android.os.Parcel _data = android.os.Parcel.obtain();
103                 android.os.Parcel _reply = android.os.Parcel.obtain();
104                 try {
105                     _data.writeInterfaceToken(DESCRIPTOR);
106                     _data.writeString(name);
107                     mRemote.transact(Stub.TRANSACTION_setName, _data, _reply, 0);
108                     _reply.readException();
109                 } finally {
110                     _reply.recycle();
111                     _data.recycle();
112                 }
113             }
114 
115             @Override
116             public void setSex(java.lang.String sex)
117                     throws android.os.RemoteException {
118                 android.os.Parcel _data = android.os.Parcel.obtain();
119                 android.os.Parcel _reply = android.os.Parcel.obtain();
120                 try {
121                     _data.writeInterfaceToken(DESCRIPTOR);
122                     _data.writeString(sex);
123                     mRemote.transact(Stub.TRANSACTION_setSex, _data, _reply, 0);
124                     _reply.readException();
125                 } finally {
126                     _reply.recycle();
127                     _data.recycle();
128                 }
129             }
130 
131             @Override
132             public void setAge(int age) throws android.os.RemoteException {
133                 android.os.Parcel _data = android.os.Parcel.obtain();
134                 android.os.Parcel _reply = android.os.Parcel.obtain();
135                 try {
136                     _data.writeInterfaceToken(DESCRIPTOR);
137                     _data.writeInt(age);
138                     mRemote.transact(Stub.TRANSACTION_setAge, _data, _reply, 0);
139                     _reply.readException();
140                 } finally {
141                     _reply.recycle();
142                     _data.recycle();
143                 }
144             }
145 
146             @Override
147             public java.lang.String getPerson()
148                     throws android.os.RemoteException {
149                 android.os.Parcel _data = android.os.Parcel.obtain();
150                 android.os.Parcel _reply = android.os.Parcel.obtain();
151                 java.lang.String _result;
152                 try {
153                     _data.writeInterfaceToken(DESCRIPTOR);
154                     mRemote.transact(Stub.TRANSACTION_getPerson, _data, _reply,
155                             0);
156                     _reply.readException();
157                     _result = _reply.readString();
158                 } finally {
159                     _reply.recycle();
160                     _data.recycle();
161                 }
162                 return _result;
163             }
164         }
165 
166         static final int TRANSACTION_setName = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
167         static final int TRANSACTION_setSex = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
168         static final int TRANSACTION_setAge = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
169         static final int TRANSACTION_getPerson = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
170     }
171 
172     public void setName(java.lang.String name)
173             throws android.os.RemoteException;
174 
175     public void setSex(java.lang.String sex) throws android.os.RemoteException;
176 
177     public void setAge(int age) throws android.os.RemoteException;
178 
179     public java.lang.String getPerson() throws android.os.RemoteException;
180 }

3、IntentService的用法:

在眼前Activity和MyService建立关系之后,大家如故是调用了setName、setAge、setSex、getPerson()那多少个法子,远程的MyService会对传播的参数举行拍卖并赶回结果,然后将结果打印出来。

运作程序,点击按钮,显示效果如下:

  • onServiceConnected() 
    和劳动绑定成功后,系统会调用那一个情势来发送由服务的onBind()方法再次回到的IBinder对象
  • onServiceDisconnected()  
    当服务格外终止时会调用(如服务崩溃或被杀死时)。注意,在客户端解除绑定时不会调用该措施。

诸如此类,Acitivity就打响调用了长途Service的自定义类。

onBind()方法是Service中唯一的一个空洞方法,所以必要求在子类里心想事成。大家了解,Service可以有三种启动格局:一种是startService(),另一种是bindService()。第二种启动格局才会用到onBind()方法。大家那先用第一种格局启动Service,所以临时忽略onBind()方法。

我们在首先段中就已经说了,服务中的代码默许运行在主线程中,假若直白在劳务里实施一些耗时操作,不难导致ANR(Application
Not Responding)极度,所以就要求用到八线程的学问了。

以此绑定是异步的,bindService()方法马上回到,并且不给客户端重临IBinder对象。要收到IBinder对象,客户端必须创建一个ServiceConnection类的实例,并且把那个实例传递给bindService()方法。瑟维斯Connection对象涵盖了一个种类调用的传递IBinder对象的回调方法。

七、Messenger的使用:

(1)新建IPerson.aidl文件,代码如下所示:

 

自然,现在Activity和Service其实还没提到起来了吧,那些效能是在Bind
Service按钮的点击事件里做到的。可以看出,那里大家仍然是创设出了一个Intent对象,然后调用bindService()方法将Activity和Service举行绑定。bindService()方法接收多少个参数,第四个参数就是刚刚创设出的Intent对象,第一个参数是前方创制出的ServiceConnection的实例,第两个参数是一个标志位,那里流传BIND_AUTO_CREATE代表在Activity和Service建立关系后会自动成立Service(即使以前从未开创Service也尚无关系),那会使得MyService中的onCreate()方法得到实施,但onStartCommand()方法不会执行。

那大家经过代码来落到实处以下吧。新建一个簇新的工程MessengerTest。步骤如下:

使用Messenger来实现IPC的步骤:

当然了,那里的Messenger的兑现比较不难,若是之后要求已毕复杂IPC访问,如故必要协调去写AIDL才更为直白有效,可控性强。

 

本条Java文件实际上是一个接口,同时生成了在aidl文件中定义的七个方法,并抛出了长途调用的更加。我们按住Ctrl键,点开上图中蓝框部分的IInterface,查看一下源代码:

图片 16

随着创造MyBinder的实例(13行),然后在onBind()方法里重回这些实例(35行)。

点开上图中的红框部分,可以看来:

(2)调用bindService()方法来传递瑟维斯Connection类的贯彻;

(3)修改activity_main.xml代码,添加一个按钮,用于发送Message,代码如下:

(3)修改activity_main.xml代码,如下:

图片 17

 1 package com.example.servicetest02;
 2 
 3 import android.app.Activity;
 4 import android.content.ComponentName;
 5 import android.content.Intent;
 6 import android.content.ServiceConnection;
 7 import android.os.Bundle;
 8 import android.os.IBinder;
 9 import android.os.RemoteException;
10 import android.util.Log;
11 import android.view.View;
12 import android.view.View.OnClickListener;
13 import android.widget.Button;
14 
15 public class MainActivity extends Activity implements OnClickListener {
16 
17     public static final String TAG = "MainActivity";
18     private Button button_bind_service;
19     private Button button_unbind_service;
20 
21     private IPerson person;
22 
23     boolean mBound = false; // 一开始,并没有和Service绑定.这个参数是用来判断绑定状态
24 
25     // 匿名内部类:服务连接对象
26     private ServiceConnection connection = new ServiceConnection() {
27 
28         // 当服务异常终止时会调用。注意,解除绑定服务时不会调用
29         @Override
30         public void onServiceDisconnected(ComponentName name) {
31             mBound = false; // 服务异常终止时,状态为未绑定
32         }
33 
34         // 和服务绑定成功后,服务会回调该方法。在这个方法里调用的业务对象中的内容
35         @Override
36         public void onServiceConnected(ComponentName name, IBinder service) {
37             Log.d(TAG, "onServiceConnected");
38             person = IPerson.Stub.asInterface(service); // 得到person对象
39             Log.d("person", "person对象的内存地址是" + person); // 打印出person对象的内存地址
40             try {
41                 person.setName("生命壹号");
42                 person.setAge(22);
43                 person.setSex("男");
44                 String p = person.getPerson();
45                 Log.d("person", "person的信息是" + p);
46             } catch (RemoteException e) {
47                 // TODO Auto-generated catch block
48                 e.printStackTrace();
49             }
50             mBound = true; //true说明是绑定状态
51 
52         }
53     };
54 
55     @Override
56     protected void onCreate(Bundle savedInstanceState) {
57         super.onCreate(savedInstanceState);
58         setContentView(R.layout.activity_main);
59         button_bind_service = (Button) findViewById(R.id.button_bind_service);
60         button_unbind_service = (Button) findViewById(R.id.button_unbind_service);
61         button_bind_service.setOnClickListener(this);
62         button_unbind_service.setOnClickListener(this);
63 
64     }
65 
66     @Override
67     public void onClick(View v) {
68         switch (v.getId()) {
69         case R.id.button_bind_service:
70             Intent bindIntent = new Intent(this, MyService.class);
71             bindService(bindIntent, connection, BIND_AUTO_CREATE);
72             break;
73         case R.id.button_unbind_service:
74             // 如果和Service是绑定的状态,就解除绑定。
75             if (mBound) {
76                 unbindService(connection);
77                 mBound = false;
78             }
79             break;
80 
81         default:
82             break;
83         }
84     }
85 
86 }

(6)MainActivity中的代码,如下所示:

2、在客户端绑定一个劳务的步调:

然后怎么样大家想消除Activity和瑟维斯之间的关联如何是好呢?调用一下unbindService()方法就可以了,那也是Unbind
Service按钮的点击事件里心想事成的逻辑。

6、让Activity与一个中远距离Service建立关系的手续:(在同一个APP内模拟)

图片 18

Android的后台就是指,它的运转是截然不依赖UI的。固然Activity被销毁,或者程序被关门,只要经过还在,Service就可以持续运行。比如说有的应用程序,始终需求与服务器之间始终维持着心跳连接,就能够使用Service来完毕。你或许又会问,Service既然是运作在主线程里,在此间直接施行着心跳连接,难道就不会堵塞主线程的运转吧?当然会,然而大家得以在Service中再成立一个子线程,然后在此地去处理耗时逻辑就没难点了。

 

综述,传递自定义类,有多少个步骤:

(4)在MainActivity作为程序的主Activity,在里头参预启动Service和终止Service的逻辑,代码如下:

3、started服务与bind服务的界别:

事实上,onCreate()方法只会在Service第五回被创设的时候调用,而onStartCommand()方法在历次启动服务的时候都会调用

图片 19图片 20

上述那两种销毁的措施都很好通晓。那么只要大家既点击了Start
Service按钮,又点击了Bind
Service按钮会怎样呢?这些时候你会意识,不管您是单身点击Stop
Service按钮照旧Unbind 瑟维斯按钮,瑟维斯都不会被销毁,须要将Unbind Service按钮和Stop
Service按钮都点击一下(没有先后顺序),Service才会被灭绝
。也就是说,点击Stop
Service按钮只会让Service甘休,点击Unbind
Service按钮只会让Service和Activity解除关系,一个Service必需求在既没有和任何Activity关联又处理为止状态的时候才会被销毁。

三、IntentService

除此以外,还足以调用Context的bindService()来收获一个服务的恒久连接,那时就会回调服务中的onBind()方法。类似地,假如那些服务从前还未曾成立过,onCreate()方法会先于onBind()方法执行。之后调用方可以获得到onBind()方法里再次来到的IBinder对象的实例,那样,就能自由地和服务开展通信了。只要调用方和劳务中间的接连没有断开,服务就会直接维持运行处境。

代码解释:

五、使用Bind Service完结IPC进程间通讯:(在同一个APP内模拟)

那有些代码大家自然会更加熟知吧?没错,那和在ServiceTest02的MainActivity中的代码大概是完全相同的,只是在让Activity和瑟维斯建立关联的时候我们选择了隐式Intent,将Intent的action指定成了com.example.servicetest02.MyAIDLService(63行)。

留意这么些parcelable的第四个字母是小写。

综上可得,大家的确已经打响落到实处跨进程通信了,在一个进度中做客到了其它一个进度中的方法。
注意,那些Service是运行在主线程当中的,毕竟大家是在当地模拟的嘛。

那样的话,ClientTest中的代码也就整个成功了,现在运行一下以此项目,然后点击Bind
Service按钮,此时就会去和远程的MyService建立关联,观望LogCat中的打印信息如下所示:

4、Service的生命周期:

有别于一:生命周期

大家在第02行中,打印主线程的id。

 

 

图片 21

  • 在Service中开创一个Messenger对象并绑定一个Handler
  • 在onBind方法中经过Messenger.getIbinder方法重回一个IBinder对象。
  • 在调用的零部件中的ServiceConnection的onServiceConnected事件措施中根据iBinder对象来创制一个Messenger对象。这样,四个Messenger就同时绑定到一个IBinder上,从而完成通讯。
  • 在调用的零件中应用Messenger的send方法来发送音讯到Service的Messenger对象中。

一经大家再点击button2_stop_service按钮或者点击上图中的“Stop”,MyService服务就告一段落掉了:

新建一个全新的Android工程ServiceTest02。

图片 22

(1)新建一个Student类去落到实处Parcelable接口。Student类是当做传递的自定义类:

图片 23

图片 24

(4)接下去再修改MainActivity中的代码,让MainActivity和MyService之间创建关联,代码如下所示:

图片 25

10行:代表的是进程间通讯(远程通讯),此时第07行的if语句不树立,于是再次回到第10行的代办对象Proxy(obj)。

7、AIDL援救的自定义数据类型:

(1)已毕ServiceConnection抽象类。完结进度中,必须重写一下四个回调方法:

  • 应用AIDL定义业务接口,通过ADT工具来生成一个java类,此类完毕了经过间远程通讯的代办
  • 编排自己的业务类(继承生成的类中的Stub)来落成业务接口功效
  • 再通过绑定Service的不二法门来揭露此事情对象,给任何组件提供功用
  • 调用者组件通过bindService方法绑定服务,从而赢得绑定成功后的远程业务对象或本地工作对象,然后就足以调用相关职能。
  • 留神:一般在运用完绑定服务后,要求破除绑定。

(2)在清单文件中宣称:(和Activity标签并列)

(2)在清单文件中登记服务:(和Activity标签并列)

瑟维斯是Android中落到实处程序后台运行的解决方案,极度适合用于去执行怎么着不必要和用户交互而且还须要短时间运行的职责。无法运作在一个独门的长河当中,而是依靠与创建服务时所在的应用程序进程。只可以在后台运行,并且可以和别的零件进行互相。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图