android - 应用程序类中的服务执行 Web 套接字连接崩溃

标签 android service java-websocket

我正在构建一个使用网络套接字的聊天应用程序。我写了一个服务,在 Application 类中调用。问题是,有时当我在崩溃后启动应用程序时,mConnection 变为空。我认为这是因为即使我退出应用程序,服务也在后台运行,当我再次启动它时,它无法创建新服务并绑定(bind)到它。 我的问题是:这是编写代码的好方法吗?有没有办法在应用程序销毁时停止服务?

public class MyApplication extends Application{
  private final AtomicInteger refCount = new AtomicInteger();
    public ConnectionService mConnectionService;
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder binder) {
            ConnectionService.MyBinder b = (ConnectionService.MyBinder) binder;
            mConnectionService = b.getService();
            Log.d("MyApplication", "MyApplication has been bounded");
        }

        public void onServiceDisconnected(ComponentName className) {
            mConnectionService = null;
            Log.d("MyApplication", "MyApplication has been unbounded");
        }
    };

    @Override
    public void onCreate() {
        Intent intent = new Intent(this, ConnectionService.class);
        getApplicationContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    public ConnectionService getConnectionService() {
        refCount.incrementAndGet();
        Log.d("MyApplication", "getConnectionService, current: "+refCount);
        return mConnectionService;
    }

    public void releaseConnectionService() {

        if (refCount.get() == 0 || refCount.decrementAndGet() == 0) {
            mConnectionService.stopSelf();
            Log.d("MyApplication", "MyApplication has been stopped ");
        }
        Log.d("MyApplication", "releaseConnectionService, current: "+refCount);
    }

另一个类看起来像这样:

    public class LobbyActivity extends Activity{
    ListView lvContacts;
    Gson gson;
    LoginData mLoginData;
    MyReceiver receiver;
    ArrayList<User> users;
    LobbyAdapter lobbyAdapter;
    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    gson = new Gson();
    Intent intent = getIntent();
    String loginDataJson = intent.getStringExtra("LoginData");
    mLoginData = gson.fromJson(loginDataJson, LoginData.class);
    getActionBar().setTitle(mLoginData.getUsername());
    setContentView(R.layout.activity_lobby);    
    users = new ArrayList<User>();

    lvContacts = (ListView)findViewById(R.id.lvContacts);
    lobbyAdapter=new LobbyAdapter(users, this);
    lvContacts.setAdapter(lobbyAdapter);

    Commands cmd = new Commands(getApplicationContext());
    cmd.sendCommand(Commands.COMMAND_GET_MANAGER_LIST);
    cmd.sendCommand(Commands.COMMAND_GET_USER_LIST);

    receiver = new MyReceiver(new Handler()) {
        @Override
        public void onReceive(Context context, Intent intent) {
            String message = intent.getStringExtra(ConnectionService.MESSAGE);
            String notification = intent.getStringExtra(ConnectionService.NOTIFICATION);
            if (message!=null){
                try {
                    switch (Utils.getCommand(message)) {
                    case Commands.COMMAND_GET_USER_LIST:
                        ArrayList<User> user = new ArrayList<User>();
                        user  = (gson.fromJson(message, UserList.class)).users;
                        users.addAll(user);
                        lobbyAdapter.notifyDataSetChanged();

                        break;

                    default:
                        break;
                    }



                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }
    };
    LocalBroadcastManager.getInstance(this).registerReceiver(receiver,
            new IntentFilter(MainActivity.BROADCAST_ACTION));

}
    class UserList{
        String cmd;
        ArrayList<User> users; 
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        ((MyApplication)getApplicationContext()).releaseConnectionService();
    }

}

我之所以将服务放在 Application 类中,是因为我希望它在应用程序运行时一直运行;并且所有 Activity 都需要访问它。

最佳答案

Is it a good way of writing the code?

我要说的是,从 Application 类启动 Android 应用程序组件(如 ServiceActivity)并不是一个好的编程习惯。您应该从 ActivityBroadcastReceiver 组件启动服务。最后 Application onCreate 中的代码运行,因为新进程是在您的应用程序启动时创建的。如果您从启动器启动应用程序并且主 Activity 启动或 BroadcastReceiver 已收到调用,则会发生这种情况。此时您可以从其中任何一个启动 Service

And is there a way to stop the service on the application destroy?

您可以从 Activity 的 onDestroy() 停止 Service。如果您不想在每次配置更改(如屏幕旋转)时停止服务,您可以检查 onDestory 方法是否正在销毁或仅通过 isChangingConfigurations 方法重新加载 Activity 并根据这些知识决定是否停止 Service

关于android - 应用程序类中的服务执行 Web 套接字连接崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27276395/

相关文章:

android - 即时应用最小 sdk 版本

java - Spring-Websocket:满足条件时向订阅者发送更新

android - 如果我从 Activity 中的 onCreate startService,finish() Activity 然后再次启动应用程序,会发生什么情况?

android - 如果服务停止,后台线程会发生什么?

Android 应用内计费 : Receiver's onReceive never getting called even after a successful purchase

java - Vert.x websocket 客户端 - 400 错误请求

websocket - 使用 spring websockets 阻止消息等待 10000 等待 BLOCKING..

Android 将文件 append 到 zip 文件而不必重新编写整个 zip 文件?

android - 如何在android中使用https url调用webservice

javascript - React-native 第一次运行