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; }