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

Service 绑定

2016-12-03 23:03 246 查看
一、Activity之间协调:

1.当在同一个进程中从一个Activity开启另一个Activity时,它们的生命周期方法是这样的:

A Activity 开启了 B Activity:

A调用onPause(),B调用onCreate(),onStart(),onResume(),此时B Activity与用户进行交互,

然后A Activity的onStop()方法调用,所以如果两个界面共享一些数据,如存储在数据库

中的数据,则应该在A Activity的onPause()方法中保存数据,而不是onStop()方法。

2.横竖屏切换

当用户旋转屏幕,切换屏幕状态时,会创建新的Activity实例。

二、Service的onStartCommand()方法返回值

1.一个服务的onStartCommand()方法必须返回一个整数值,这个整数值描述了在系统因为内存等问题杀死

该服务后,该服务在系统获得了可用内存等资源如何继续该服务,返回值必须为以下其中之一:

a.START_NOT_STICKY:不要重新创建该服务,除非有意图重新开启该服务;

b.START_STICKY:用一个空的意图重新创建该服务,如果有新的意图,则用新的意图开启,适用于媒体播放器等逻辑;

c.START_REDELIVER_INTENT:用上一次开启该服务的意图重启该服务,也就是继续进行上次未完成的任务,

适用于文件下载,上传等逻辑。

2.运行一个前台服务:

前台服务是用户主动意识到的一种服务,因此在内存不足时,系统也不会考虑将其终止。 前台服务必须为状态栏

提供通知,放在“正在进行”标题下方,这意味着除非服务停止或从前台移除,否则不能清除通知。

要让服务运行与前台,需调用startForeground()方法,接收两个参数,一个是通知的唯一标志性ID,一个是

notification对象,如:

Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
4000
注:ID值不能为0;

要从前台移除服务,请调用 stopForeground()。此方法接收一个布尔值,指示是否也移除状态栏通知。 此方法不会停止

服务。 但是,如果在服务正在前台运行时将其停止,则通知也会被移除。

3.定义可绑定的服务:

a.定义和客户(client)交互的接口有三种方式,分别是:

(1)继承Binder类,适用于此服务为应用进程所私有,且client跟该服务处于同一应用进程中;

实现步骤:服务中定义一个类继承Binder类,在服务的onBind()方法中返回一个自定义Binder实例对象,client在

onServiceConnected()方法中获取该对象;

(2)使用Messager类提供跨进程绑定服务:

实现步骤:

服务实现一个 Handler,由其接收来自client的每个调用的回调,

Handler 用于创建 Messenger 对象(对 Handler 的引用),

Messenger 创建一个 IBinder,服务通过 onBind() 使其返回client,

client使用 IBinder 将 Messenger(引用服务的 Handler)实例化,然后使用后者将 Message 对象发送给服务,

服务在其 Handler 中(具体地讲,是在 handleMessage() 方法中)接收每个 Message。

这样,client并没有调用服务的“方法”。而client传递的“消息”(Message 对象)是服务在其 Handler 中接收的。

如:
service:
public class MessengerService extends Service {
/** Command to the service to display a message */
static final int MSG_SAY_HELLO = 1;

/**
* Handler of incoming messages from clients.
*/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}

/**
* Target we publish for clients to send messages to IncomingHandler.
*/
final Messenger mMessenger = new Messenger(new IncomingHandler());

/**
* When binding to the service, we return an interface to our messenger
* for sending messages to the service.
*/
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
return mMessenger.getBinder();
}
}

Activity:
public class ActivityMessenger extends Activity {
/** Messenger for communicating with the service. */
Messenger mService = null;

/** Flag indicating whether we have called bind on the service. */
boolean mBound;

/**
* Class for interacting with the main interface of the service.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the object we can use to
// interact with the service. We are communicating with the
// service using a Messenger, so here we get a client-side
// representation of that from the raw IBinder object.
mService = new Messenger(service);
mBound = true;
}

public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
mBound = false;
}
};

public void sayHello(View v) {
if (!mBound) return;
// Create and send a message to the service, using a supported 'what' value
Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

@Override
protected void onStart() {
super.onStart();
// Bind to the service
bindService(new Intent(this, MessengerService.class), mConnection,
Context.BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
}(3)AIDL,有待后续拓展

4.客户端(client)绑定服务:

client调用bindService()方法,然后服务会调用onBind()方法返回IBinder对象,但是因为

这个绑定过程是异步的,bindService()调用后立即结束并不会返回IBinder()对象,因此需要一个ServiceConnection实例,

这个借口提供onServiceConnected()和onServiceDisconnected()回调方法,当服务已经绑定时会调用onServiceConnected()方法,

并获得IBinder实例对象;当服务崩溃或者被系统杀死时onServiceDisconnected()方法调用,而不是用户调用unbindService()时调用。

如:

LocalService mService;
private ServiceConnection mConnection = new ServiceConnection() {
// Called when the connection with the service is established
public void onServiceConnected(ComponentName className, IBinder service) {
// Because we have bound to an explicit
// service that is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}

// Called when the connection with the service disconnects unexpectedly
public void onServiceDisconnected(ComponentName className) {
Log.e(TAG, "onServiceDisconnected");
mBound = false;
}
};绑定服务:
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

5.bind service 生命周期:



6.Service完整生命周期:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android Service