Android 服务入门
前言:硬着头皮把数据库SQLite看完了,接下来就是android服务了,因为自己本身就是菜鸟,所以呢,也只是做做笔记,技术上的东西就别指望我了。
1.什么是服务呢?举个例子,百度地图,美团外卖,OFO,可以获取你的位置,就提供了位置服务,通知服务基本上每个APP都会有。再举个例子,你开启一个网易云在后台运行,你希望切换到另外一个应用依旧可以听到音乐,这也是服务。
2.服务是没有用户界面的,它是背后默默为人民服务的。只要运行了服务,你就可以放手地去做其他事情了。
3.有两种类型的服务,-----Start services-----启动服务-----从互联网下载一个大文件,-----Bound services-----绑定服务-----汽车里程表。
4.先说一下Start Services,代码中用extends Service类或者extends IntentService类 创建一个服务。顾名思义,前者提供了基本的服务功能,后者还可以和意图Intent挂钩。新建服务时,最好通过File-----New-----Service-----创建新的IntentService-----服务命名自定义。比如啊,创建一个IntentService,服务运行在onHandleIntent这个方法中,是复写的方法。
5.继续IntentService,再建立一个活动,方便调用服务。主要业务逻辑都在onHandlerIntent中进行,这里用了一个synchronized(this){wait(10000)}内部方法,现学现卖一下,意思就是同步。这里wait(10000)和时间挂钩了,等待10s,所以肯定不会那么简单,总之知道怎么用就行了。
6.服务要在AndroidManifest.xml进行声明。与Activity同一级,<service android:name=.服务名 android:exported="false"></> 那exported是什么意思呢,就是告诉Android,这个服务可以有其他应用使用,false表示这个服务只能在当前应用中使用。
7.活动怎么调用服务呢,在主布局中增加一个按钮,单击按钮调用活动的onClick方法。在方法中 Intent intent=new Intent(this,服务名.class)-----intent.putExtra(字符串,意图文本)-----startService(intent),是不是超像调用活动,也许啊,就是那些谷歌开发人员懒得重新建一个服务的调用,就直接在原有的基础上多写一个构造函数吧。
8.如何和主线程挂钩呢,这里服务也为我们提供了一个方法,onStartCommand-----在每次启动意图服务时,都会调用这个方法,比onHandleIntent方法还要快。所以呢,在onStartCommand创建一个处理消息的Handler就可以向主线程传递消息了。昨天也写了一篇博客,Handler必须要定义在主线程中,他就是主线程定义的一个使者,为了监督子线程的工作情况的。
9.服务中的用一个Toast访问屏幕咋办呢?有了handler之后就方便很多了,直接handler.post复写一个run方法,再Toast就可以了 吗?可是服务中的上下文是无法访问屏幕的,那咋办呢?getApplicationContext()不就可以了嘛!
10.Toast个人感觉用户体验并不是特别好,所以这里要多改进改进,试着用别的方法来替换Toast()方法。就用通知吧,一般应用都会有的,其实也很烦,但是也要学啊。-----主要方法就是,在服务中创建一个NotificationManager对象,用来访问Android的通知服务的。
11.怎么在服务中创建一个通知呢
Notification notification=new Notification.Builder(this).多个set.build() 即可。set什么东西呢?比如啊,通知图标,标题,文本,声音,通知个数,优先级,如果不会-----就在goole或者baidu上搜索关键字-----使用通知生成器创建通知。
12.当你点击一个通知时,你想跳到活动中去咋办呢?这就有点小复杂了。
(1)创建一个显示意图,就和之前活动跳转一样。
(2)将这个意图传递到TaskStackBuilder -----它允许访问后退按钮使用的活动历史-----就是保证活动启动时后退按钮可以正常工作而已-----不要想得太复杂了。
(3)从TaskStackBuilder得到挂起意图 用 PendingIntent 接收stackBuilder对象的getPendingIntent()函数。里面有两个参数,一个是标志,一个是挂起意图的行为。
(4)向通知增加意图 -----notification.setContentIntent(pendingIntent)
(5)用通俗的话来讲,就是-----挂起意图被玩来玩去-----先从服务中创建-----在被TaskStackBuilder玩弄是非-----在从getPendingIntent中得到-----最后回到通知的怀抱。
13.回到通知的怀抱之后,就要发起总攻了,那就是Android的通知服务-----完成在设备上显示的大业。首先要有一个旗号,才能鼓舞更多的人,就是通知的ID-----其次直接getSystenService()来获得访问权限-----通过这个“通知经理”来创建通知。这样,所有的通知基本上都通过这个经理组织起来了。
14.简单讲一下整个过程,首先呢,MainActivity通过一个意图-----联系到MessageService服务(类似于一个活动一样传递即可)-----执行服务中的代码,主要是修改onHandleIntent,顾名思义就是消息处理中心-----然后里面随便写一个方法-----方法实现了将普通意图升级成挂起意图-----挂起意图升级为通知-----通知最后告诉Android先生。
15.然后就是绑定服务呢,一听这个名字,就是牢牢绑住用户-----所以更具有交互性-----类似于汽车的里程表。它怎么工作呢?
16.主要有以下几个步骤-----如监听用户行走路径-----用到了位置服务
(1)定义一个OdometerBinder-----只要继承Binder即可。利用这个对象可以把活动连接到OdometerService 。
(2)创建一个LocationListener,向Android的位置服务注册这个监听器-----计算已经走过的里程数
(3)创建一个公共getMiles()方法-----活动可以使用这个方法得到走过的里程数。
17.怎么绑定呢?主活动创建一个ServiceConnection对象-----活动通过这个连接将一个意图传递到服务-----绑定服务创建一个Binder对象-----服务通过连接发回Binder-----活动接收到Binder对象后,取出Service对象,使用这个服务。
18.用通俗的话讲,就是ServiceConnection作为一个中介代理,左边是MainActivity,右边是Service,总之,ServiceConnection就像一座桥一样,连通了这条路,缺一不可。
19.在这条路中来回穿梭的车子,就是Binder了。活动使用OdometerBinder类部类来获得OdometerService的一个引用。
20.Service类提供了4大天王,onCreate是创建服务,onStartCommand是第一次启动,onBind是绑定到服务,onDestroy是撤销服务。
21.所以说,如何得到设备的位置呢?just a LocationListener-----它有four个override-----onLocationChanged-----onProviderDisabled-----onProviderEnabled-----onStatusChanged
22.然后是注册监听器,基本使用这些高档的方法,都要问一下Android君,我可以用一下位置服务吗?安卓君派一个经理-----这里是LocationManager-----帮助他完成大业。
23.经理是可以轻松得到信息的,活动不知道啊,那怎么办呢?创建一个方法来访问服务嘛-----可以提供更加精准的人性化的数据,如提供几千米,几英里-----国人一般用千米。
24.简单总结一下,首先是一个自定义服务继承Service-----里面有一个自定义Binder继承Binder-----复写一个onBind将活动绑定到服务-----复写一个onCreate方法用来创建服务是建立位置监听器-----onCreate里面的监听器有4个方法要复写-----最重要的是onLocationChanged-----onCreate最后要向位置Android君请求,之后向位置服务注册位置监听器-----最后自定义一个方法在活动中得到数据,如转换公里数。
25.这里涉及到了GPS,安卓君对这个东西管理得比较严格,所以在AndroidManifest.xml中要声明一下权限-----否则会崩溃哒。其次服务也要声明,任何服务都要声明,每个服务都会有一个名字,android:exported-----只有这个应用才使用这个服务,android:enabled-----应用能否使用这个服务。
26.紧接着就是用测试了,用一个Main活动来处理。将她绑定到服务-----更新文本视图。
27.怎么绑定呢?just a ServiceConnection-----它有两个方法-----onServiceConnected用来建立与服务的连接-----onServiceConnected用来失去服务连接。
28.Main中的私有成员,我称私有成员为-----仅仅是从别人那里得到暂用一下-----别人那得到是将别的东西赋给它-----暂用一下是得到之后肯定要用什么方法。
29.Main活动启动时要绑定到服务,怎么绑定呢?just in onStart---复写Main中的onStart方法-----创建一个显示意图,指定你要绑定的服务-----然后活动提供了一个重要的方法-----bindService来将意图和连接挂钩。
30.有了onStart方法,当然不能少了onStop方法了,just 啊unbindService方法来解除服务绑定。
31.然后就是布局要显示什么东西了。注意要用到视图更新,就要用到handler来处理,handler可以分两部分,也可以简写,前面我也写了一篇博客-----线程+handler+Thread,这里提供了一个更加简单的方法,handler.post(new Runnable(){.....}),我在想这个创造这个函数的人是不是太懒了,感觉只适合牛人用。
32.整理一下思路,首先在Main中建立两个私有成员-----自定义服务类-----boolean是否绑定到服务。然后是定义一个ServiceConnection-----用来连接服务时得到一个自定义服务的引用-----复写了onServiceConnected-----复写了onServiceDisConnected 。然后是一个onCreate函数-----里面加载布局和视图更新的函数。 然后是复写onStart方法-----驱动活动是绑定服务-----用了一个bindService方法(活动本身有的)。 然后是复写onStop方法-----活动停止是解除服务绑定。 注意点就是视图更新的函数用了handler来处理。
33.整个服务就看的差不多了,目的很简单,就只知道整个流程,用的时候会用-----现在时间紧迫,不求精通-----以后有空再深入研究一下。
早安!2017/7/11 7:50