关于Android service的一些基础知识集合

  1.什么是Service以及描述下它的生命周期。Service有哪些启动方法,有什么区别,怎样停用Service?

在Service的生命周期中,被回调的方法比Activity少一些,只有onCreate, onStart, onDestroy,
onBind和onUnbind。
通常有两种方式启动一个Service,他们对Service生命周期的影响是不一样的。
1 通过startService
    Service会经历 onCreate 到onStart,然后处于运行状态,stopService的时候调用onDestroy方法。
   如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。
  2 通过bindService  
    Service会运行onCreate,然后是调用onBind, 这个时候调用者和Service绑定在一起。调用者退出了,Srevice就会调用onUnbind->onDestroyed方法。
   所谓绑定在一起就共存亡了。调用者也可以通过调用unbindService方法来停止服务,这时候Srevice就会调用onUnbind->onDestroyed方法。
需要注意的是如果这几个方法交织在一起的话,会出现什么情况呢?
一个原则是Service的onCreate的方法只会被调用一次,就是你无论多少次的startService又bindService,Service只被创建一次。
如果先是bind了,那么start的时候就直接运行Service的onStart方法,
如果先是start,那么bind的时候就直接运行onBind方法。 
如果service运行期间调用了bindService,这时候再调用stopService的话,service是不会调用onDestroy方法的,service就stop不掉了,只能调用UnbindService, service就会被销毁
如果一个service通过startService 被start之后,多次调用startService 的话,service会多次调用onStart方法。多次调用stopService的话,service只会调用一次onDestroyed方法。
如果一个service通过bindService被start之后,多次调用bindService的话,service只会调用一次onBind方法。
多次调用unbindService的话会抛出异常。

2.service是否在main thread中执行, service里面是否能执行耗时的操作?

默认情况,如果没有显示的指定service所运行的进程, Service和activity是运行在当前app所在进程的main thread(UI主线程)里面 
service里面不能执行耗时的操作(网络请求,拷贝数据库,大文件 )
在子线程中执行 new Thread(){}.start();
特殊情况 ,可以在清单文件配置 service 执行所在的进程 ,让service在另外的进程中执行

 3.怎么让在启动一个Activity是就启动一个service?

在activity的onCreate()方法里面 startService();

4.Activity怎么和service绑定,怎么在activity中启动自己对应的service?

startService() 一旦被创建  调用着无关   没法使用service里面的方法
bindService () 把service 与调用者绑定 ,如果调用者被销毁, service会销毁
bindService() 我们可以使用service 里面的方法
       bindService().  让activity能够访问到 service里面的方法
       构建一个intent对象,
Intent service = new Intent(this,MyService.class);
 通过bindService的方法去启动一个服务,
    bindService(intent, new MyConn(), BIND_AUTO_CREATE);
       ServiceConnection 对象(重写onServiceConnected和OnServiceDisconnected方法) 和BIND_AUTO_CREATE.
       private class myconn implements ServiceConnection
       {
              public void onServiceConnected(ComponentName name, IBinder service) {
                     // TODO Auto-generated method stub
                     //可以通过IBinder的对象 去使用service里面的方法
              }
              public void onServiceDisconnected(ComponentName name) {
                     // TODO Auto-generated method stub      
              } 
       }

5.不用service,B页面为音乐播放,从A跳转到B,再返回,如何使音乐继续播放?

这个问题问的很山寨.默认不做任何处理,B里面的音乐都能播放.
遇到问题, 可以随机应变,灵活发挥,多考虑些细节,比如说这个题就可以这样说,说说你对startActivityForResult的理解()
B的结束的时候 setResult()
 
A会调用到onActivityResult()
就会获取到resultCode 
A开启B的时候,用startActivityForResult()方法, B返回的时候把播放的状态信息返回给A ,A继续播放音乐.
seekTo(resultCode)

6.什么是IntentService?有何优点?

普通的service ,默认运行在ui main 主线程
    Sdk给我们提供的方便的,带有异步处理的service类,
       可以在OnHandleIntent() 处理耗时的操作

 7.什么时候使用Service?

后台操作,耗时操作的时候
       拥有service的进程具有较高的优先级
    官方文档告诉我们,Android系统会尽量保持拥有service的进程运行,只要在该service已经被启动(start)或者客户端连接(bindService)到它。当内存不足时,需要保持,拥有service的进程具有较高的优先级。
1. 如果service正在调用onCreate,  onStartCommand或者onDestory方法,那么用于当前service的进程相当于前台进程以避免被killed。
2. 如果当前service已经被启动(start),拥有它的进程则比那些用户可见的进程优先级低一些,但是比那些不可见的进程更重要,这就意味着service一般不会被killed.
3. 如果客户端已经连接到service (bindService),那么拥有Service的进程则拥有最高的优先级,可以认为service是可见的。
4. 如果service可以使用startForeg round(int, Notification)方法来将service设置为前台状态,那么系统就认为是对用户可见的,并不会在内存不足时killed。
如果有其他的应用组件作为Service,Activity等运行在相同的进程中,那么将会增加该进程的重要性。
       1.Service的特点可以让他在后台一直运行,可以在service里面创建线程去完成耗时的操作.
new Thread(){
TimerTask // 循环的执行一个定时的任务
 
}.start();    
       2.Broadcast receiver捕获到一个事件之后,可以起一个service来完成一个耗时的操作.
ANR  new Service()
 
       3.远程的service如果被启动起来,可以被多次bind, 但不会重新create.  索爱手机X10i的人脸识别的service可以被图库使用,可以被摄像机,照相机等程序使用.
画廊 摄像机 照相机  bindService()  Ibinder的对象, 访问service

8.如何在让Service杀不死?

Android开发的过程中,每次调用startService(Intent)的时候,都会调用该Service对象的onStartCommand(Intent,int,int)方法,然后在onStartCommand方法中做一些处理。
从Android官方文档中,我们知道onStartCommand有4种int返回值,首先简单地讲讲int返回值的作用。
一、onStartCommand有4种返回值:
START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
 
二、创建不被杀死的service
1.在service中重写下面的方法,这个方法有三个返回值, START_STICKY(或START_STICKY_COMPATIBILITY)是service被kill掉后自动重写创建
@Override  public int onStartCommand(Intent intent, int flags, int startId)  {   return START_STICKY_COMPATIBILITY;    //return super.onStartCommand(intent, flags, startId);  }

 @Override  public int onStartCommand(Intent intent, int flags, int startId)  {   flags = START_STICKY;   return super.onStartCommand(intent, flags, startId);   // return START_REDELIVER_INTENT;  }
@Override public void onStart(Intent intent, int startId) { // 再次动态注册广播 IntentFilter localIntentFilter = new IntentFilter("android.intent.action.USER_PRESENT"); localIntentFilter.setPriority(Integer.MAX_VALUE);// 整形最大值 myReceiver searchReceiver = new myReceiver(); registerReceiver(searchReceiver, localIntentFilter); super.onStart(intent, startId); }
2.在Service的onDestroy()中重启Service.
 public void onDestroy()  {   Intent localIntent = new Intent();   localIntent.setClass(this, MyService.class); // 销毁时重新启动Service   this.startService(localIntent);  }
3.创建一个广播
public class myReceiver extends BroadcastReceiver {  @Override  public void onReceive(Context context, Intent intent)  {   context.startService(new Intent(context, Google.class));  } }
4.AndroidManifest.xml中注册广播myReceiver及MyService服务
<receiver android:name=".myReceiver" >             <intent-filter android:priority="2147483647" ><!--优先级加最高-->                 <!-- 系统启动完成后会调用 -->                 <action android:name="android.intent.action.BOOT_COMPLETED" />                                <!-- 解锁完成后会调用 -->                 <action android:name="android.intent.action.USER_PRESENT" />                 <!-- 监听情景切换 -->                 <action android:name="android.media.RINGER_MODE_CHANGED" />                            </intent-filter> </receiver>
<service android:name=".MyService" >
注:解锁,启动,切换场景激活广播需加权限,如启动完成,及手机机状态等。
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 亲测ZTE U795手机Android 4.0.4版本adb push到system\app下android:persistent="true" 变成核心程序,在360杀掉进程的时候,myReceiver照样有效,保证service重生。呃
KILL问题: 1. settings 中stop service onDestroy方法中,调用startService进行Service的重启。 2.settings中force stop 应用 捕捉系统进行广播(action为android.intent.action.PACKAGE_RESTARTED) 3. 借助第三方应用kill掉running task 提升service的优先级,程序签名,或adb push到system\app下等
相较于/data/app下的应用,放在/system/app下的应用享受更多的特权,比如若在其Manifest.xml文件中设置persistent属性为true,则可使其免受out-of-memory killer的影响。如应用程序'Phone'的AndroidManifest.xml文件:
    <application android:name="PhoneApp"
                 android:persistent="true"
                 android:label="@string/dialerIconLabel"
                 android:icon="@drawable/ic_launcher_phone">
         ...
    </application>
设置后app提升为系统核心级别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值