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

时间:2014-12-03 16:09:22

标签: android service java-websocket

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

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类中的原因是,只要应用程序运行,我就希望它能够运行;并且所有活动都需要访问它。

1 个答案:

答案 0 :(得分:1)

  

这是编写代码的好方法吗?

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

  

有没有办法停止应用程序销毁服务?

您可以停止活动Service中的onDestroy()。如果您不希望在每次配置更改(例如屏幕轮换)时停止服务,则可以检查onDestory方法是否正在销毁,或仅通过isChangingConfigurations Activity方法重新加载并决定停止或不基于该知识Service