我正在构建一个使用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类中的原因是,只要应用程序运行,我就希望它能够运行;并且所有活动都需要访问它。
答案 0 :(得分:1)
这是编写代码的好方法吗?
我想说从Service
类启动Android应用程序组件(例如Activity
或Application
)并不是一个好的编程习惯。您应该从Activity
或BroadcastReceiver
组件启动服务。最后在Application onCreate
内部运行代码,因为在启动应用程序时会为您的应用程序创建新进程。如果您从启动器启动应用并且主Activity
启动或BroadcastReceiver
已接听电话,则会发生这种情况。此时,您可以从其中任何一个开始Service
。
有没有办法停止应用程序销毁服务?
您可以停止活动Service
中的onDestroy()
。如果您不希望在每次配置更改(例如屏幕轮换)时停止服务,则可以检查onDestory
方法是否正在销毁,或仅通过isChangingConfigurations
Activity
方法重新加载并决定停止或不基于该知识Service
。