您的位置:首页 > 移动开发 > Android开发

android四大组件service

2015-11-10 22:48 447 查看

1、Service与Activity

service与activity都是android的基本组件,并且都是Context的子类,可以把service当作是没有界面的activity。与activity一样,不能在主线程中作耗时操作。都必须在清单文件中配置。

2、Service两种启动服务的方式和不同。

对于为什么会有两咱启动方式,他们是合适不同的场景的。使用startService启动的服务,它不会随着启动它的组件生命周期结束而结束,只要不调用停止服务或者手机结束进程,服务将一直处于运行中。

而通过bindStart()启动的服务是与启动它的组件生命周期相关联。如果启动它的组件销毁了,那么通过启动它的服务也就销毁了。

1. StartService()的生命周期:

onCreate()——如果服务已经创建,则不会再走onCreate()方法。

onStartCommand—-每一次调用都会执行:

当其它组件,比如一个activity,通过调用startService()请求started方式的服务时,系统将会调用本方法。 一旦本方法执行,服务就被启动,并在后台一直运行下去。 如果你的代码实现了本方法,你就有责任在完成工作后通过调用stopSelf()或stopService()终止服务。 (如果你只想提供bind方式,那就不需要实现本方法。)

onStart()——每一次调用都会执行

onDesotry()——如果不调用.stopService()或者调用Service.stopSelfResult(),service将一直处于开启的状态;

这类服务由其它组件调用startService()来创建。然后保持运行,且必须通过调用stopSelf()自行终止。其它组件也可通过调用stopService() 终止这类服务。服务终止后,系统会把它销毁。

2、 通过bindService()的方式启动启动服务

当其它组件需要通过bindService()绑定服务时(比如执行RPC),系统会调用本方法。 在本方法的实现代码中,你必须返回IBinder来提供一个接口,客户端用它来和服务进行通信。 你必须确保实现本方法,不过假如你不需要提供绑定,那就返回null即可。

bindService()— 调用

onCreate()—–首先会走onCreate()方法

onBind()——-绑定服务

Service running—–服务正在运行中

onUnbind()——-解除绑定

onDesotry()——销毁服务

服务由其它组件(客户端)调用bindService()来创建。然后客户端通过一个IBinder接口与服务进行通信。客户端可以通过调用unbindService()来关闭联接。多个客户端可以绑定到同一个服务上,当所有的客户端都解除绑定后,系统会销毁服务。(服务不需要自行终止。)

3、对于两种启动方式的混合启动。

通过startService()方式启动服务,服务就可以做到长驻内存中(不依赖于组件)。使用bindService()的方式启动服务,服务与绑定组件相依存,并且通过bind的方式可以与service进行很多的交互,在conn中可以获取服务中的信息:比如说连接的状态,如果有下载任务,还可以得到下载的进度,情况等。

但是有时候用过这两种服务的混合开启这种情况使用的也比较多,比如说音乐播放器必须运行在服务中,但又需要被前台activity调用这就要用混合服务的方式启动了。

先startService(),再bindService(),销毁时先unbindService(),再stopService()。

4 、IntentService

intentService可能使用的人比较少,甚至很多人都没听过。但intentService是非常好用和适用的。

利用继承Service写的服务通过startService()启动服务,这种服务一旦启动,就处于运行状态,如果想要在线程执行后停止服务,只能调用 stopSelf()的方法。

为了方便起见,也是减少一些可能发生的错误,比如说经常忘记开启,或者调用stopSelf()的方法。Android中提供了一个IntentService()类,这个类可以简单的创建一个异步的,会自动停止的服务。

IntentService的执行步骤:

创建一个子线程,并且执行onStartCommand()中收到的intent。

创建一个工作队列,每次向onHandleIntent()传入一个intent,

处理完所有的请求后,自动调用stopSelf()停止服务。

详见实例3

5、Service与Activity之间的通信和传递数据;

1、activity向service发送数据比较简单,与activity之间传递数据一样。

Intent intent =new Intent(this,MyService.class);

intent.putExtra(“name”,”yu”);

startService(intent);

String name=intent.getStringExtra(“name”);

Log.i(TAG,name);

2、service向activity传递数据或者更新UI

如果需要数据持久化:

1、在service得到网络数据保存到sp中数据,在activity中从sp中取出数据更新UI;

2、在service中得到网络数据保存到数据库中,在activity中查询数据库,并更新UI

如果不需要持久化:

3、能过BroadcastReceiver把service中的数据传递给activity,

4、如果服务通过bindService的方式启动,还可以通过onBind()方法来传递数据给activity

6、如何用Service开启一个长期运行,定时更新的任务。比如天气,或者新闻每隔三小时更新;

在activity中启动服务。

在服务中的onStartCommand中开启子线程,连网得到网络数据,并且调用AlermManager定时,用PendingIntent得到广播,并发送给广播。

在广播的onReceive()中再次启动服务,这样就形成了一个长期的在后台运行,并且定时刷新的服务。

详细实例4

1、通过startService启动服务代码:

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(MainActivity.this,MyStartService.class));

}
}


在MyStartService()中的代码:

public class MyStartService extends Service {
private static final String TAG="MyStartService";
//如果服务已经开启了,调用将不会再走onCreate()的方法
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG,"service onCreate()");
}
//每一次调用都是执行onStartCommand代码,在这段代码中主要做onStart()方法前的一些工作
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG,"service onStartCommend()");
return super.onStartCommand(intent, flags, startId);
}
//onStart方法是在onStartCommand执行后走的方法。
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i(TAG, "service onStart()");
}
//销毁服务;
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "service onDestory()");
}

@Override
public IBinder onBind(Intent intent) {
return null;
}
}


运行结果:第一次走了onCreate()的方法,再次则没有走onCreate()



2、通过bindService()启动服务代码

public class MyBindService extends Service {
private static final String TAG = "MyBindService";

//创建服务;
@Override
public void onCreate() {
Log.i(TAG, "service onCreate()");
super.onCreate();
}

//绑定服务,在绑定的服务中返回一个Bind对象;
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "service onBind()");
return mBinder;
}
//销毁服务
@Override
public void onDestroy() {
Log.i(TAG, "service onDestory()");
super.onDestroy();
}

private MyBinder mBinder = new MyBinder();

//创建MyBinder,继承Binder,调用bind启动服务时,把MyBindService返回
public class MyBinder extends Binder {
public MyBindService getService() {
return MyBindService.this;
}
}
}


在Activity中调用:注意!通过绑定的服务会随着组件的结束而结束,在onDestory()中调用解除绑定代码

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//通过startService()的方式启动服务;
//   startService(new Intent(MainActivity.this,MyStartService.class));

//通过bindService()的方式启动服务;
Intent intent = new Intent(MainActivity.this, MyBindService.class);
bindService(intent, conn, BIND_AUTO_CREATE);
}

ServiceConnection conn = new ServiceConnection() {

@Override
public void onServiceConnected(ComponentName name, IBinder service) {

}

@Override
public void onServiceDisconnected(ComponentName name) {
}

};

@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();

}
}


效果图:当Activity执行了onDestory()时,服务也就销毁了



3、 intentService实例:

public class HelloIntentService extends IntentService {

/**
* 构造方法是必需的,必须用工作线程名称作为参数
* 调用父类的[http://developer.android.com/reference/android/app/IntentService.html#IntentService(java.lang.String) IntentService(String)]构造方法。
*/
public HelloIntentService() {
super("HelloIntentService");
}

/**
* IntentService从缺省的工作线程中调用本方法,并用启动服务的intent作为参数。
* 本方法返回后,IntentService将适时终止这个服务。
*/
@Override
protected void onHandleIntent(Intent intent) {
// 通常我们会在这里执行一些工作,比如下载文件。
// 作为例子,我们只是睡5秒钟。
long endTime = System.currentTimeMillis() + 5*1000;
while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
}
}


继承IntentService后,增加了一个构造方法和一个onHandleIntent()方法的实现。

还可以加上其他方法,比如onCreate()、onStartCommand()、onDestroy(), 请确保调用一下父类的实现代码,以便IntentService能正确处理工作线程的生命周期。

实例4、在后台定时数据更新为例,比如说每隔三小时天气更新。

在activity中代码:

/**
* 如何做一个定时的,在后台运行的长期任务,比如天气,或者新闻每小时更新?
*
* 在activity中启动了service,然后在service中每隔10秒中启动广播,这样onReceive()方法得到执行,
在广播中再次开启service,这样就形成一个永久的循环,一个长期的在后台运行的任务也就启动起来。
*/
public class MainActivity extends Activity  {
private TextView tv_time;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_time= (TextView) findViewById(R.id.tv_time);
Intent intent=new Intent(this,AutoService.class);
startService(intent);
}

}


在AutoService中代码:

public class AutoService extends Service {
private static final String TAG="AutoService";
private String str_time="";
//不需要绑定
@Override
public IBinder onBind(Intent intent) {
return null;
}
//onStartCommand在onStart()方法前运行;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
//开启子线程,在这里做耗时操作;比如说获取天气信息;

Log.i(TAG, getTime());

}
}).start();
AlarmManager manager= (AlarmManager) getSystemService(ALARM_SERVICE);
int time=10*1000;
long triggerAtTIME= SystemClock.elapsedRealtime()+time;
Intent i=new Intent(this,AutoBroadcastReceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(this,0,i,0);
manager.set(AlarmManager.ELAPSED_REALTIME, triggerAtTIME, pi);
return super.onStartCommand(intent, flags, startId);
}

public String getTime(){
SimpleDateFormat sdf =new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss ");
Date date=new Date(System.currentTimeMillis());
String str=sdf.format(date);
return str;
}
}


在AutoBroadcastReceiver中代码:

public class AutoBroadcastReceiver extends BroadcastReceiver {
public static final String TAG="AutoBroadcaseReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, AutoService.class);
context.startService(i);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: