长连接 - android 如何取得正在运行的service对象
巴扎黑
巴扎黑 2017-04-17 16:27:03
0
3
705

在写有关推送的代码,用的长连接的方式。
具体逻辑:登录时 启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;
    }
}
巴扎黑
巴扎黑

모든 응답(3)
阿神

긴 연결을 원하므로 서비스가 백그라운드에 상주해야 합니다. 따라서 BindService 메서드는 적합하지 않습니다. 애플리케이션과 원격 서비스 간의 통신에는 브로드캐스트(Broadcast)와 IPC의 두 가지 방법이 있습니다.

  • Broadcast 원격 서비스가 지속적으로 외부 세계로 브로드캐스트를 보내도록 하고, 애플리케이션은 브로드캐스트를 수신하여 하트비트 데이터를 업데이트합니다(업데이트해야 할 데이터가 이것이라고 가정). 방송은 비효율적이고 불안정하며 시스템 모니터링의 영향을 받아 특정 순간의 방송 데이터가 손실될 수 있지만 구현하기가 간단하고 데이터에 대한 엄격한 요구 사항이 없다면 이 방법을 사용하는 것을 고려해 볼 수 있습니다.

  • AIDL 방식인
  • IPC, AIDL에 익숙하신 분들은 원격 서비스와의 통신에 활용하시는 것을 적극 권장합니다. , 하지만 그냥 배우세요. 안드로이드에 속해요. 고급 지식도 나중에 큰 도움이 될 거예요.

서비스 객체를 얻으려는 것은 실제로 정확하지 않습니다. 서비스 객체가 존재하는지 사용자에게 알릴 수 있는 서비스 자체의 API는 없습니다. 마음이 바뀔 수 있습니다. 이전에 원격 서비스가 활성화되어 있다는 전제 하에 ActivityManager를 사용하여 애플리케이션 프로세스를 쿼리하고 원격 서비스 프로세스 이름을 일치시키면 원격 서비스가 존재하는 것입니다. 일반적으로 말하면 몇 가지 아이디어만 제공할 뿐입니다. 구체적인 구현을 위해서는 여전히 정보를 검색하고 개선해야 합니다.

刘奇

bindservice

洪涛

서비스 시작 방법에는 StartService 및 BindService가 포함됩니다.

이렇게 서비스를 시작해 보세요.

으아악

이것은 conn 개체입니다.

으아악

물론 Service에서 Onbind를 재정의해야 합니다. 이 메서드는 Service 개체가 포함된 Ibinder 개체를 반환합니다.

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿