Служба в классе приложения, выполняющая сбой соединения через веб-сокет
Я создаю приложение чата, которое использует веб-сокет. Я написал сервис, который называется в классе приложения. Проблема в том, что иногда mConnection становится нулевым, когда я просто запускаю приложение после сбоя. Я думаю, что это происходит из-за того, что служба запускается в фоновом режиме, даже когда я закрываю приложение, и когда я снова запускаю его, он не может создать новый сервис и связать его с ним. Мои вопросы: это хороший способ написания кода? И есть ли способ остановить сервис на уничтожение приложения?
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 ответ
Это хороший способ написания кода?
Я бы сказал, что это плохая практика программирования - запускать такие компоненты приложения Android, как Service
или же Activity
от Application
учебный класс. Вы должны начать обслуживание с Activity
или же BroadcastReceiver
составная часть. В конце кода внутри Application onCreate
запускается потому, что новый процесс создается для вашего приложения при запуске. Это произойдет, если вы запустите приложение из панели запуска и основной Activity
начинается или BroadcastReceiver
был дан вызов. В этот момент вы можете начать Service
от любого из них.
И есть ли способ остановить сервис на уничтожение приложения?
Вы можете остановиться Service
от деятельности onDestroy()
, Если вы не хотите останавливать Сервис при каждом изменении конфигурации (например, поворот экрана), вы можете проверить onDestory
метод, будь то уничтожение или перезагрузка только через isChangingConfigurations
метод Activity
и решили остановиться или нет Service
основываясь на этом знании.