2014-12-03 4 views
1

Я создаю приложение чата, которое использует веб-сокет. Я написал службу, которая вызывается в классе 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 является то, что я хочу, чтобы это было до тех пор, пока приложение запускается; и также необходимо, чтобы к ним обращались все виды деятельности.

+0

Как это может быть null, если единственным местом, когда вы его устанавливаете, является: mConnection = new ServiceConnection() {...? – pskink

ответ

1

Это хороший способ написать код?

Я бы сказал, что это не является хорошей практикой программирования для запуска Android компонентов приложения, как Service или Activity из Application класса. Вы должны начать обслуживание с Activity или BroadcastReceiver компонента. В конце код внутри Application onCreate запускается, потому что новый процесс создается для вашего приложения при его запуске. Это произойдет, если вы запустили приложение с пускового устройства, а начало Activity началось или BroadcastReceiver получил звание. В этот момент вы можете начать с Service из любого из них.

И есть ли способ прекратить обслуживание приложения уничтожить?

Вы можете остановить Service от Activity's onDestroy(). Если вы не хотите останавливать службу при каждом изменении конфигурации (например, вращение экрана), вы можете проверить способ onDestory, является ли он уничтожением или только перезарядка по isChangingConfigurations методу Activity и принять решение остановиться или нет Service на основе этих знаний.

+0

Спасибо за ответ, это почти то, что мне нужно, но прежде чем я помету его как правильное, пожалуйста, дайте мне еще несколько советов. Причина, по которой я поместил ее в класс Application, заключается в том, что мне нужно, чтобы она была глобальной: например, я хочу, чтобы эта служба всегда поддерживала соединение с веб-сокетом, пока приложение работает. И я хочу использовать его методы (например, «sendMessage» для доступа к другим видам деятельности. Пожалуйста, скажите мне, как я должен архитектовать свое приложение. Буду очень признателен. Спасибо –

+0

Что делать, если я старую сервис? –

+0

Как вы знаете «Сервис» в ОС Android может по существу принимать две формы: начальную и ограниченную. После запуска служба может работать в фоновом режиме на неопределенный срок, даже если компонент, который начал ее, уничтожен. Связанная служба предлагает интерфейс клиент-сервер, который позволяет компонентам для того, чтобы взаимодействовать с сервисом, отправлять запросы и получать результаты, поэтому запустите свою «Сервис» в главной «Деятельности». Затем привязаны к «Сервису» от каждой «Деятельности», которая хотела бы связываться с ней и не была связана, когда определенная «Активность» Если вы оставите свое приложение, прекратите свое обслуживание. –

Смежные вопросы