在写有关推送的代码,用的长连接的方式。
具体逻辑:登录时 启service,service中启一个线程,线程中构建一个CommunicateManegr对象,此对象里面有一个BlockingDeque双端队列处理包的顺序问题, 还有若干线程分别处理心跳包、登录包、推送消息、其它业务消息、断线重连、心跳检测等操作。
初次运行程序,长连接建立起来;然后退出系统,为了保持长连接,后台服务仍运行。再次运行程序时,需要判断后台服务是否仍在运行,仍在运行的话,需要取出之前运行的service对象,添加一些登录包。
这里的取出之前运行的service对象,如何取出?
不局限与取出之前运行的service对象的问题,是否从一开始 我关于长连接的处理逻辑就有一些理解不当的地方?
伪代码:
class MyService extends Service{
public CommnicateManager cManager;
@Override
public void onCreate() {
new Thread(new Runnable() {
@Override
public void run() {
CommunicateManager manager = CommunicateManager.getInstance();
cManager = manager;
manager.connect();
manager.add(LoginPackage);//添加登录包
manager.add(registerPackage);//添加注册包
manager.startHeardBeatThread();//开启心跳线程
manager.startCommunicate();//开启其它线程
}
}.start();
}
}
public class LoginActivtiy extends BaseActivity implements OnClickListener {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.login:
if (isServiceWork(LoginActivtiy.this,"com.example.service")){//判断第一次运行的服务是否存在
//TODO: 需要得到第一次运行的服务对象service 如何得到??? manager.add(loginPackage)
}else{
startService(myService);
}
break;
default:
break;
}
}
//判断某个服务是否正在运行的方法
public boolean isServiceWork(Context mContext, String serviceName) {
boolean isWork = false;
ActivityManager myAM = (ActivityManager) mContext
.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningServiceInfo> myList = myAM.getRunningServices(200);
// List<RunningAppProcessInfo> apps = myAM.getRunningAppProcesses();
if (myList.size() <= 0) {
return false;
}
for (int i = 0; i < myList.size(); i++) {
String mName = myList.get(i).service.getClassName().toString();
if (mName.equals(serviceName)) {
isWork = true;
break;
}
}
return isWork;
}
}
Since you want a long connection, the service must be resident in the background. Therefore, the bindService method is not feasible. You need a remote service. Use the startService method to make the heartbeat service independent of the application. As for the communication between the application and the remote service, there are two methods, Broadcast and IPC.
Broadcast
allows your remote service to continuously send broadcasts to the outside world. The application receives the broadcasts and updates the heartbeat data (assuming that the data that needs to be updated is this). The disadvantage is that broadcasts are inefficient and unstable. It is susceptible to the influence of system monitoring and may lose broadcast data at certain moments. However, it is simple and easy to implement. If you do not have strict requirements on data, you can consider using this method;Broadcast
,让你的remote service不断的向外发送广播,应用接收广播并更新心跳数据(假设需要更新的数据是这个),缺点就是广播是低效且不稳定,易受系统监控影响,有可能丢失某一些时刻的广播数据,不过简单,容易实现,对数据不严格要求可以考虑使用这个方式;IPC
IPC
, which is the AIDL method. If you are familiar with AIDL, it is strongly recommended that you use this to communicate with the remote service. If you are not familiar with it, it will be difficult, but just learn it. Advanced knowledge of Android will also be of great help in the future. 🎜 🎜As for what you want to get the Service object, it is indeed not very accurate. There is no API of the service itself that can tell the user whether the service object exists. You can change your mind. On the premise that the remote service is enabled earlier, you can use ActivityManager to query the application process and match the remote service process name. If the process name exists, then the remote service exists. Generally speaking, it only provides some ideas, and you still need to find information to complete the specific implementation. 🎜bindservice
Service startup methods include StartService and BindService.
Start the Service like this.
This is a conn object.
Of course you have to override Onbind in Service. This method will return an Ibinder object, which contains the Service object.