需求:
一个手机中只能启动service的一个实例,任意一个app启动该service前先检测是否已经有其他app启动了该service,如果已经运行则直接绑定,如果没有service的实例,则启动一个。
ShareService代码
public class ShareService extends Service {
private static final String TAG = ShareService.class.getSimpleName();
public static final String SERVICE_NAME = "com.efrobot.library.shareservice.ShareService";
private static Handler handler;
private static Messenger messenger;
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "Service onCreate");
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.i(TAG, "msg what=" + msg.what);
Log.i(TAG, "msg obj=" + ((Bundle) msg.obj).getString("key"));
int pid = android.os.Process.myPid();
Log.i(TAG, "pid=" + pid);
try {
msg.replyTo.send(msg);
Log.i(TAG, "replyTo");
} catch (RemoteException re) {
Log.e(TAG, "replyTo error", re);
}
}
};
messenger = new Messenger(handler);
}
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind");
return messenger.getBinder();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand");
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
Log.i(TAG, "Service onDestroy");
super.onDestroy();
}
}
app代码
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private Messenger mService = null;
private String packageName;
private static Messenger messenger;
private static Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent();
boolean noService = noService();
if (noService) {
intent.setClass(this, ShareService.class);
startService(intent);
} else {
intent.setComponent(new ComponentName(packageName, ShareService.SERVICE_NAME));
}
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
Button btnSendToService = (Button) findViewById(R.id.btn_send_to_service);
btnSendToService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bundle bundle = new Bundle();
bundle.putString("key", "I am another");
Message message = Message.obtain(null, 100, 0, 0);
message.obj = bundle;
message.replyTo = messenger;
try {
mService.send(message);
} catch (RemoteException re) {
Log.e(TAG, "send message error", re);
}
}
});
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.i(TAG, "msg what=" + msg.what);
Log.i(TAG, "msg obj=" + ((Bundle) msg.obj).getString("key"));
int pid = android.os.Process.myPid();
Log.i(TAG, "pid=" + pid);
}
};
messenger = new Messenger(handler);
}
private boolean noService() {
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> l = am.getRunningServices(Integer.MAX_VALUE);
Iterator<ActivityManager.RunningServiceInfo> i = l.iterator();
while (i.hasNext()) {
ActivityManager.RunningServiceInfo runningServiceInfo = i.next();
if (runningServiceInfo.service.getClassName().equals(ShareService.SERVICE_NAME)) {
packageName = runningServiceInfo.service.getPackageName();
return false;
}
}
return true;
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// 当与service的连接已经建立时被调用.给了我们可以用来
//与service交互的对象.我们正在使用一个Messenger与service通信,
// 所以在这里我们从原始IBinder 对象获取一个客户端的Messenger的代表
Log.i(TAG, "" + service);
mService = new Messenger(service);
// mBound = true;
}
public void onServiceDisconnected(ComponentName className) {
// 当与service的连接意外断开时被调用-- 也就是,service的进程崩溃了
// mService = null;
// mBound = false;
}
};
@Override
public void onDestroy() {
Log.i(TAG, "MainActivity onDestroy");
super.onDestroy();
unbindService(mConnection);
}
}
service的AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.efrobot.library.shareservice">
<application
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true">
<service
android:name=".ShareService"
android:exported="true"
android:process=":remote" />
</application>
</manifest>