由于各种原因,我无法让我的应用程序正常工作。
设计概述:我的目标是一个具有两个按钮(连接、断开连接)和一个显示从连接接收到的数据的文本视图的活动。我编写了一个“MySocket”服务来处理 WebSocket 连接(Gottox 的 Java 实现),每当 tit 从服务器接收到某些内容时,该服务就会向活动发布一条消息,然后活动将该数据附加到 textview 上。该服务必须从活动接收连接/断开连接提示,并能够将消息传递给活动。MySocket 还需要作为前台服务运行,以便无限期地保持连接,并向用户提供粘性通知。
我在各个地方都遇到了重大问题。首先,我注意到我可以启动另一个活动实例,而原始实例仍在更新中。android:launchMode="singleInstance">
我通过在清单中指定来解决这个问题。我遇到的问题是,当活动被销毁并创建新活动时,服务继续发布更新,但重点活动没有收到它们。如果原始活动被破坏并且服务处理程序没有更新,那么一旦活动被破坏,它肯定会抛出空指针异常,但应用程序继续运行。然后我尝试unbindService(mConnection)
在我的 onDestroy 方法中运行,但这抛出了java.lang.IllegalArgumentException: Service not registered:
The service is messing something这应该是重点活动,但似乎没有收到它。我怀疑我的前台服务执行不力是罪魁祸首,但我真的不知道。
有问题的两个类很长,所以我删除了 Logcat 行、全局变量和一些我确定是不相关的方法。我意识到架构是可怕的,但这已经接近我的工作了。如果代码太可怕而无法阅读,我很乐意有人提出替代结构,只要它达到预期的结果。
活动类:
@Override
public void onCreate(Bundle savedInstanceState)
{
...
mMessenger = new Messenger(mHandler);
connect.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
messageSocket("ACTION", "CONNECT");
}
});
@Override
protected void onDestroy()
{
super.onDestroy();
doUnbindService();
}
private ServiceConnection conn = new ServiceConnection()
{
public void onServiceConnected(ComponentName className, IBinder binder)
{
Log.d(debug, "Service Connected");
messenger = new Messenger(binder);
boundToService = true;
}
public void onServiceDisconnected(ComponentName className)
{
Log.d(debug, "Service Disconnected");
messenger = null;
boundToService = false;
}
};
void doBindService()
{
final Intent intent = new Intent(this, MySocket.class);
intent.putExtra("MESSENGER", messenger);
Thread t = new Thread()
{
public void run()
{
boundToService =
getApplicationContext().bindService(
intent,
conn,
Context.BIND_AUTO_CREATE
);
}
};
t.start();
}
和 MySocket 类:
class IncomingHandler extends Handler
{
@Override
public void onCreate()
{...}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground( id, showNotification() );
connect();
return START_STICKY;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground( id, showNotification() );
connect();
return START_STICKY;
}
private Notification showNotification()
{
nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
CharSequence text = "WebSocket currently active";
Notification notification = new Notification(R.drawable.ic_launcher,
text, System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, SocketTester.class), 0);
notification.setLatestEventInfo(this, "WebSocket Test", text,
contentIntent);
notification.flags = Notification.FLAG_FOREGROUND_SERVICE;
return notification;
}
@Override
public IBinder onBind(Intent intent)
{
Bundle extras = intent.getExtras();
Log.d(debug, "onBind called");
if (intent.getExtras() != null)
{
Log.d(debug, "Setting messenger");
outMessenger = (Messenger) extras.get("MESSENGER");
}
return inMessenger.getBinder();
}
@Override
public void handleMessage(Message msg)
{
Bundle data = msg.getData();
Message backMsg = Message.obtain();
Bundle bundle = new Bundle();
backMsg.setData(bundle);
if ("CONNECT".equals(data.getString(ACTION)))
{
Log.d(debug, "Connecting");
startService(new Intent(MySocket.this, MySocket.class));
/*startService now calls connect();*/
}
else if ("DISCONNECT".equals(data.getString(ACTION)))
{
if (socket != null)
{
socket.disconnect();
}
stopForeground( true );
stopSelf();
}
}
}