我無法讓我的應用程序爲各種reasosn正常工作。如何讓服務綁定到正確的活動實例?
設計概述: 我的目標是一個活動,它有兩個按鈕(連接,斷開)和一個顯示從連接收到的數據的文本視圖。我編寫了一個處理WebSocket連接(Gottox的Java實現)的「MySocket」服務,並且此服務在tit接收到來自服務器的某些內容時向該活動發佈消息,然後該活動將該數據附加到textview上。該服務必須接收來自活動的連接/斷開連接提示,並且能夠將消息傳遞給活動。 MySocket還需要作爲前臺服務運行,以便無限期地保持連接,並向用戶提供粘性通知。
我在各個地方都遇到過這個問題。首先,我注意到我可以開始另一個活動實例,而原始內容仍在更新中。我通過在清單中指定android:launchMode="singleInstance">
來解決這個問題。我遇到的問題是,當活動被摧毀並創建一個新的活動時,該服務繼續發佈更新,但重點活動沒有收到它們。如果原始活動被破壞,服務處理程序沒有更新,那麼一旦活動被銷燬,它肯定會拋出空指針異常,但應用程序仍在運行。然後,我嘗試在我的onDestroy方法中運行unbindService(mConnection)
,但是投擲了一個java.lang.IllegalArgumentException: Service not registered:
該服務正在傳送東西這應該是重點活動,但似乎沒有收到它。我懷疑我的前臺服務不好的實施是怪,但我真的沒有線索。
問題的兩個類都是LONG,所以我刪除了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();
}
}
}
我將爲您提供與另一個架構,但你必須解釋,你願意在你的應用程序中做什麼,應該是關鍵點。謝謝:) – SALMAN 2012-07-22 00:04:00
需要一個活動,顯示數據通過websocket傳遞,並提供用戶打開和關閉連接,一旦打開,連接應該保持打開狀態,直到用戶關閉爲止,還必須有一個粘性通知讓用戶知道連接仍然是操作恩。 – Chironex 2012-07-22 15:19:25
ok爲什麼不保存你的數據,它已被rec。通過SharedPreference in Service類中的websocket連接,因此,您可以收集數據並顯示您想要的任何活動? – SALMAN 2012-07-22 17:16:33