mainactivity的CODE
package com.example.servicetosendstatusbarmessage;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity{
private Thread thread;
private Button tb,nbs,bs,end;
private String title,message,name="新消息";
private boolean bound=false;
Messenger messenger=null;
LocalService myintentService;
Intent intent,intent1;
private boolean isinteerupt=true,Beginintentservice=false,Beginservice=false;
int NOTIFYID_1=1; //消息推送码
final static int isFromtb=1,isFromwithoutBind=0x11;
Intent intent2;
NotificationManager notificationManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
notificationManager= //获取通知管理器
(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
tb=(Button)findViewById(R.id.threadSendMessage);
nbs=(Button)findViewById(R.id.withoutBindService);
bs=(Button)findViewById(R.id.withBindService);
end=(Button)findViewById(R.id.end);
intent=new Intent(MainActivity.this,LocalService.class);
intent2=new Intent(MainActivity.this,withoutBind.class);
bindService(intent2,connection,Context.BIND_AUTO_CREATE);
//开启新线程推送消息的按钮的监听
tb.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
isinteerupt=!isinteerupt;
if(isinteerupt)
{
tb.setText("子线程推送消息");
handler.removeCallbacks(runnable); //停止计时器
Log.i("提示:","中断线程");
}
else
{
tb.setText("暂停推送");
handler.post(runnable);//启动计时器,每两秒执行一次runnable.
Log.i("提示:","开始线程");
}
}
});
//开启非绑定类服务(黑科技,双进程互相启动)推送消息的按钮的监听
nbs.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Beginintentservice=!Beginintentservice;
if(Beginintentservice) {
nbs.setText("暂停推送");
startService(intent);
Log.i("LocalService","start");
}
else {
stopService(intent);
nbs.setText("开始推送");
}
}
});
//开启绑定使用messenger的服务推送消息的按钮的监听
bs.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Beginservice=!Beginservice;
if(Beginservice) {
bs.setText("暂停推送");
startService(intent2);
//如果连接服务成功,则绑定到服务
if(bound)
{
Log.i("BindService","Successful");}
//创建一个message消息并发送给服务端
Message msgFromClient = Message.obtain(null, 0x111,0,0);
msgFromClient.replyTo = messenger1;
try {
messenger.send(msgFromClient);
}
catch(RemoteException e){
Log.i("error",e.toString());
}
}
else {
bs.setText("开始推送");
stopService(intent2);
}
}
});
//结束按钮的监听
end.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
finish();
Log.i("结束activity","finish");
}
});
}
/*
* 重写服务连接以及断开连接方法
*/
private ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName classname,IBinder service) {
messenger=new Messenger(service);
bound=true;
}
public void onServiceDisconnected(ComponentName arg0) {
messenger=null;
bound=false;
}
};
/*
* 创建一个handler对象并重写runnable的run方法,实现,当线程启动时,自动启动消息推送
*/
Handler handler=new Handler();
Runnable runnable=new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
message="这个消息来自于子线程,APP结束后将会被结束";
//当线程不没有被中断,重复执行消息推送
title="线程的推送消息"+NOTIFYID_1;
Log.i("当前消息数:",String.valueOf(NOTIFYID_1));
statusBarSend();
handler.postDelayed(runnable, 2000); //自身调用自身,陷入2秒的定时循环
}
};
/*
* 实现状态栏推送消息的方法
*/
public void statusBarSend() {
@SuppressWarnings("deprecation")
Notification.Builder begin=new Notification.Builder(MainActivity.this);
begin.setSmallIcon(R.drawable.ic_launcher);
begin.setContentTitle(title);
begin.setContentText(message);
begin.setTicker(name);
begin.setWhen(System.currentTimeMillis()); //发送时间
Notification notification1 = begin.build();
notificationManager.notify(NOTIFYID_1, notification1); // 通过通知管理器发送通知
NOTIFYID_1++;
}
/*
* 创建messenger对象来处理由服务端发送的消息
* @see android.app.Activity#onDestroy()
*/
private Messenger messenger1=new Messenger(new Handler() {
@SuppressLint("HandlerLeak")
@Override
public void handleMessage(Message msgFromwithoutBind) {
switch(msgFromwithoutBind.what) {
case isFromwithoutBind:
Log.i("MainActivity","Message receive");
}
}
});
@Override
protected void onDestroy() {
if(thread!=null) {
thread.interrupt();
thread=null;
}
super.onDestroy();
}
}
withoutBind服务的CODE:
/*
* 该service是使用messenger类来实现服务以及与之绑定的组件之间的通信,服务端通过messenger来返回Ibinder对象
* 客户端通过接收IBinder对象来获取服务。同时客户端可以发送message给服务端,服务端接收到对应的message
* 之后,服务端将会在handleMessage里面处理这些消息
*/
package com.example.servicetosendstatusbarmessage;
import java.lang.ref.WeakReference;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
public class withoutBind extends Service{
private static final int isFromMainActivity=0x111;
NotificationManager notificationManager;
//需要注意的是,内部类若是非静态,那么除非messageQueue消息全部处理完毕,否则将会阻止垃圾回收站回收外部类,
//当然这个问题只存在于主线程上,若是运行于子线程则没有影响,若要定义为非静态,必须在最后清空messageQueue
static class MyHandler extends Handler{
WeakReference<withoutBind> mService;
public MyHandler(withoutBind service) {
mService = new WeakReference<withoutBind>(service);
}
@Override
public void handleMessage(Message msg) {
// withoutBind mainService = mService.get(); //通过mService.get()获取withoutBind的引用(即上下文context)
Message msgToClient=Message.obtain(msg); //回复给客户端的消息
msgToClient.what=0x11;
switch(msg.what) {
case isFromMainActivity:
//TODO
Log.i("withoutBind", "Message receive");
try {
msg.replyTo.send(msgToClient); //回复客户端,注意的是,需要在客户端传递过来的message里面添加客户端messenger(该添加操作在客户端实现)
Log.i("reply","successful");
}catch(RemoteException e) {
Log.i("error","reply error");
}
default:
super.handleMessage(msg);
}
}
}
Messenger messenger=new Messenger(new MyHandler(this));
@Override
public IBinder onBind(Intent intent) {
Log.i("onBinder","start");
return messenger.getBinder();
}
}
LocalService的CODE:
package com.example.servicetosendstatusbarmessage;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class LocalService extends Service {
private MyBinder binder;
private MyConn conn;
private String title,message,name="新消息";
int NOTIFYID_1=1; //消息推送码
NotificationManager notificationManager;
@Override
public IBinder onBind(Intent intent) {
Log.i("LocalService", "onBind");
return binder;
}
@Override
public void onCreate() {
super.onCreate();
Log.i("LocalService", "onCreate");
binder = new MyBinder();
if (conn == null) {
conn = new MyConn();
}
this.bindService(new Intent(this, RemoteService.class),
conn, Context.BIND_AUTO_CREATE);
start();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// start();
Log.i("LocalService", "onStartCommand");
this.bindService(new Intent(this, RemoteService.class),
conn, Context.BIND_AUTO_CREATE);
return START_STICKY;
}
//@Override
// public void onStart(Intent intent, int startId) {
// super.onStart(intent, startId);
// Log.i("LocalService", "onStart");
// this.bindService(new Intent(this, RemoteService.class), conn, Context.BIND_IMPORTANT);
// start();
// }
class MyBinder extends ServiceProcess.Stub {
@Override
public String getProcessName() throws RemoteException {
return "LocalService";
}
}
class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.i("LocalService", "远程服务启动");
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.i("LocalService", "远程服务断开");
LocalService.this.startService(new Intent(LocalService.this,
RemoteService.class));
LocalService.this.bindService(new Intent(LocalService.this,
RemoteService.class), conn, Context.BIND_AUTO_CREATE);
}
}
@Override
public void onDestroy() {
super.onDestroy();
unbindService(conn);
}
public void start() {
handler.post(runnable);//启动计时器,每两秒执行一次runnable.
}
public void end() {
handler.removeCallbacks(runnable); //停止计时器
}
Handler handler=new Handler();
Runnable runnable=new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
message="这个消息来自于未绑定服务,系统不会自动杀死该进程";
//当线程不没有被中断,重复执行消息推送
title="不绑定的服务推送消息"+NOTIFYID_1;
Log.i("当前消息数:",String.valueOf(NOTIFYID_1));
statusBarSend();
handler.postDelayed(runnable, 2000); //自身调用自身,陷入2秒的定时循环
}
};
/*
* 实现状态栏推送消息的方法
*/
public void statusBarSend() {
notificationManager= //获取通知管理器
(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
@SuppressWarnings("deprecation")
Notification.Builder begin=new Notification.Builder(LocalService.this);
begin.setSmallIcon(R.drawable.ic_launcher);
begin.setContentTitle(title);
begin.setContentText(message);
begin.setTicker(name);
begin.setWhen(System.currentTimeMillis()); //发送时间
Notification notification1 = begin.build();
notificationManager.notify(NOTIFYID_1, notification1); // 通过通知管理器发送通知
NOTIFYID_1++;
}
}
RemoteService的代码:
package com.example.servicetosendstatusbarmessage;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class RemoteService extends Service {
private MyBinder binder;
private MyConn conn;
@Override
public IBinder onBind(Intent intent) {
Log.i("RemoteService", "onBind");
return binder;
}
@Override
public void onCreate() {
super.onCreate();
Log.i("RemoteService", "onCreate");
binder = new MyBinder();
if (conn == null) {
conn = new MyConn();
}
this.bindService(new Intent(this, LocalService.class), conn,
Context.BIND_AUTO_CREATE);
}
@Override
public int onStartCommand(Intent intent, int flags,int startId) {
// super.onStartCommand(intent, startId);
Log.i("RemoteService", "onStartCommand");
this.bindService(new Intent(this, LocalService.class), conn,
Context.BIND_AUTO_CREATE);
return START_STICKY;
}
class MyBinder extends ServiceProcess.Stub {
@Override
public String getProcessName() throws RemoteException {
return "RemoteService";
}
}
class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.i("RemoteService", "本地服务启动");
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.i("RemoteService", "本地服务断开");
RemoteService.this.startService(new Intent(RemoteService.this,
LocalService.class));
RemoteService.this.bindService(new Intent(RemoteService.this,
LocalService.class), conn, Context.BIND_AUTO_CREATE);
}
}
@Override
public void onDestroy() {
super.onDestroy();
unbindService(conn);
}
}
在SRC的资源包目录下创建ServiceProcess.aidl
// ServiceProcess.aidl
package com.example.servicetosendstatusbarmessage;
// Declare any non-default types here with import statements
interface ServiceProcess {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
String getProcessName();
}
编译后会在gen的包里自动生成JAVA文件:
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: G:\\安卓\\ServiceToSendStatusBarMessage\\src\\com\\example\\servicetosendstatusbarmessage\\ServiceProcess.aidl
*/
package com.example.servicetosendstatusbarmessage;
// Declare any non-default types here with import statements
public interface ServiceProcess extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.example.servicetosendstatusbarmessage.ServiceProcess
{
private static final java.lang.String DESCRIPTOR = "com.example.servicetosendstatusbarmessage.ServiceProcess";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.example.servicetosendstatusbarmessage.ServiceProcess interface,
* generating a proxy if needed.
*/
public static com.example.servicetosendstatusbarmessage.ServiceProcess asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.example.servicetosendstatusbarmessage.ServiceProcess))) {
return ((com.example.servicetosendstatusbarmessage.ServiceProcess)iin);
}
return new com.example.servicetosendstatusbarmessage.ServiceProcess.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
java.lang.String descriptor = DESCRIPTOR;
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(descriptor);
return true;
}
case TRANSACTION_getProcessName:
{
data.enforceInterface(descriptor);
java.lang.String _result = this.getProcessName();
reply.writeNoException();
reply.writeString(_result);
return true;
}
default:
{
return super.onTransact(code, data, reply, flags);
}
}
}
private static class Proxy implements com.example.servicetosendstatusbarmessage.ServiceProcess
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public java.lang.String getProcessName() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getProcessName, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_getProcessName = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public java.lang.String getProcessName() throws android.os.RemoteException;
}