在写有关推送的代码,用的长连接的方式。
具体逻辑:登录时 启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;
}
}
長時間の接続が必要なため、サービスをバックグラウンドに常駐させる必要があるため、bindService メソッドは実行できません。ハートビートサービスをアプリケーションから独立させるには、リモートサービスが必要です。 アプリケーションとリモートサービス間の通信には、ブロードキャストとIPCの2つの方法があります。
Broadcast
では、リモート サービスが継続的に外部にブロードキャストを送信し、アプリケーションがそのブロードキャストを受信してハートビート データを更新します (更新する必要があるデータがこれであると仮定します)。欠点は次のとおりです。ブロードキャストは非効率的で、不安定で、システム監視の影響を受けて、特定の瞬間にブロードキャスト データが失われる可能性がありますが、実装はシンプルで簡単です。データに関する厳密な要件がない場合は、この方法の使用を検討できます。IPC
これは AIDL メソッドです。AIDL に精通している場合は、これを使用してリモート サービスと通信することを強くお勧めします。 、しかしそれを学ぶだけでAndroidに属します 高度な知識も将来的に役立ちます。Service オブジェクトを取得したいのですが、サービス オブジェクトが存在するかどうかをユーザーに伝えるサービス自体の API はありません。リモート サービスが以前に有効になっているという前提で、ActivityManager を使用してアプリケーション プロセスをクエリし、プロセス名が存在する場合はリモート サービスのプロセス名を照合することができます。一般的に、これはいくつかのアイデアを提供するだけです。特定の実装では、情報を検索して改善する必要があります。
bindservice
サービスの起動メソッドには、StartService と BindService があります。
このようにサービスを開始します。
リーリーこれは conn オブジェクトです。
リーリーもちろん、Service で Onbind をオーバーライドする必要があります。このメソッドは、Service オブジェクトを含む Ibinder オブジェクトを返します。