本文主要是针对Service的应用练习。我将从Local Service Sample和Remote Messenger Service Sample两个方向来描述。
Local Service Sample
1.怎么生成一个IBinder对象?
查看IBinder源码
* Base interface for a remotable object, the core part of a lightweight
* remote procedure call mechanism designed for high performance when
* performing in-process and cross-process calls. This
* interface describes the abstract protocol for interacting with a
* remotable object. Do not implement this interface directly, instead
* extend from {@link Binder}.
从源码最后一句我们可以知道只需要继承Binder即可
public class LocalService extends Service {
private final IBinder mBinder = new LocalBinder();
private NotificationManager mNm;
private int NOTIFICATION = R.string.local_service_started;
public LocalService() {
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder{
LocalService getService(){
return LocalService.this;
}
}
@Override
public void onCreate() {
mNm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
showNotification();
}
@Override
public void onDestroy() {
mNm.cancel(NOTIFICATION);
Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
}
private void showNotification() {
CharSequence text = getText(R.string.local_service_started);
PendingIntent contentIntent =
PendingIntent.getActivity(this,0,new Intent(this,TestServiceActivity.class),0);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.gson)//状态栏的图标
.setTicker(text)//刚进来时候的文本
.setWhen(System.currentTimeMillis())//时间邮票
.setContentTitle("uart")//进入的标签文本
.setContentText("123456")//进入的文本内容
.setAutoCancel(true)
.setContentIntent(contentIntent)//当intent进入被点击的时候
.build();
mNm.notify(NOTIFICATION,notification);
}
}
2.怎么绑定服务?
public boolean bindService(Intent service, ServiceConnection conn,int flags);查看ServiceConnection的源码可以知道必须在主线程中调用onServiceConnected和onServiceDisconnected方法。
public class ServiceActivity extends AppCompatActivity {
private boolean mShouldUnbind;
private LocalService mBoundService;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mBoundService = ((LocalService.LocalBinder) service).getService();
Toast.makeText(ServiceActivity.this, R.string.local_service_connected,
Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
mBoundService = null;
Toast.makeText(ServiceActivity.this, R.string.local_service_disconnected,
Toast.LENGTH_SHORT).show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service);
doBindService();
}
void doBindService() {
if (bindService(new Intent(ServiceActivity.this, LocalService.class), mConnection, BIND_AUTO_CREATE)) {
mShouldUnbind = true;
} else {
Log.e("MY_APP_TAG", "Error: The requested service doesn't " +
"exist, or this client isn't allowed access to it.");
}
}
void unBindService() {
if (mShouldUnbind) {
unbindService(mConnection);
mShouldUnbind = false;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unBindService();
}
}
Remote Messenger Service Sample
查看Messenger源码可知:the implementation underneath is just a simple wrapper around a Binder that is used to perform the communication。IBinder对象可以通过Messenger对象产生。查看Messenger源码我们可以通过Messenger(Handler target)方法产生一个Messenger对象。
public class RemoteService extends Service {
private NotificationManager notificationManager;
private Messenger messenger = new Messenger(new RemoteHandler());
static final int CHANGE_TEXT = 1;
class RemoteHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case CHANGE_TEXT:
Message message = Message.obtain(null, CHANGE_TEXT);
message.arg1 = 123;
try {
msg.replyTo.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
super.handleMessage(msg);
}
}
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
@Override
public void onCreate() {
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
showNotification();
}
private void showNotification() {
Notification build = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)//状态栏的图标
.setTicker("通过远程服务启动通知")//刚进来时候的文本
.setWhen(System.currentTimeMillis())//时间邮票
.setContentTitle("uart")//进入的标签文本
.setContentText("123456")//进入的文本内容
.setAutoCancel(true)
.build();
notificationManager.notify(0, build);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
在客户端接受RemoteService。需要两个Messenger(一个用来接受IBinder并发送消息,一个用来处理接受到的Message对象)
public class RemoteActivity extends AppCompatActivity {
private TextView textView;
public static final int CHANGE_TEXT = 1;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
requestMessenger = new Messenger(service);
Log.e("TAG", "远程服务已经绑定");
}
@Override
public void onServiceDisconnected(ComponentName name) {
requestMessenger = null;
reviceMessage = null;
Log.e("TAG", "远程服务已经解绑");
}
};
private Messenger requestMessenger;
private Messenger reviceMessage = new Messenger(new RemoteHandler());
class RemoteHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case CHANGE_TEXT:
int obj = msg.arg1;
textView.setText(obj + "");
break;
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_remote);
textView = (TextView) findViewById(R.id.text);
onBindService();
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message = Message.obtain(null, CHANGE_TEXT);
message.replyTo = reviceMessage;
try {
if(requestMessenger != null) {
requestMessenger.send(message);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
private void onBindService() {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example.myapplication","com.example.myapplication.RemoteService"));
intent.setPackage(getPackageName());
bindService(intent,connection,BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
onUnBindService();
}
private void onUnBindService(){
unbindService(connection);
}
}
功能清单文件对RemoteService进行设置
<service
android:name=".RemoteService"
android:process=":remote"
android:enabled="true"
android:exported="true">
</service>