主要活動應啓動處理套接字通信的服務。這只是一個測試:Android:startService不會啓動目標服務
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.setContentView(R.layout.contacts_test);
this.startService(new Intent(getApplicationContext(), WebSocketService.class));
final WebSocketService service = WebSocketService.getInstance();
service.runWhenConnected(new Runnable() {
@Override
public void run() {
service.getWebSocket().emit("login", new Credentials("...", "..."));
}
});
service.registerHandler("login successful", new WebSocketEventHandler() {
@Override
public void onEvent(WebSocket webSocket, Object... args) {
Log.i("SOCKET-IO", "Login successful");
}
});
}
您可能會在下面找到該服務的代碼。但在開始閱讀之前,請注意控制流程甚至不會達到服務構造函數或onCreate方法;這是我無法理解的。該服務在聲明中聲明:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.gtd.test"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="15"/>
<application android:label="@string/app_name" android:icon="@drawable/tmp">
<activity android:name="MyActivity" android:label="@string/app_name" android:theme="@style/LightCustomTheme"> </activity>
<activity android:name="PickersTestActivity" android:theme="@style/LightCustomTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".ContactsTestActivity" android:theme="@style/LightCustomTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service android:name="org.pickme.service.WebSocketService" android:enabled="true">
<intent-filter>
<action android:name="org.pickme.service.WebSocketService" />
</intent-filter>
</service>
</application>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
</manifest>
我正在使用Gottox java客戶端用於socket.io。但套接字甚至沒有啓動,所以這不是問題(並且在服務之外使用它)。
package org.pickme.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import io.socket.IOAcknowledge;
import io.socket.IOCallback;
import io.socket.SocketIO;
import io.socket.SocketIOException;
import org.json.JSONObject;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class WebSocketService extends Service {
private static final String SERVER_ENDPOINT = "http://192.168.1.83:3000";
private static WebSocketService instance;
private SocketIO socket;
private WebSocket socketWrapper;
private boolean initialized;
private Thread connectionThread;
private IOCallback ioCallback;
private Runnable connectHandler, disconnectHandler;
private Map<String, List<WebSocketEventHandler>> eventHandlers;
public static WebSocketService getInstance() {
return instance;
}
public boolean isConnected() {
return socket.isConnected();
}
public boolean isInitialized() {
return initialized;
}
public WebSocket getWebSocket() {
return socketWrapper;
}
public WebSocketService() {
this.ioCallback = new CallbackStub();
this.eventHandlers = new HashMap<String, List<WebSocketEventHandler>>();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
this.initialized = false;
try {
this.socket = new SocketIO(SERVER_ENDPOINT);
this.initialized = true;
} catch (MalformedURLException e) {
this.initialized = false;
return;
}
this.initWrappers();
this.connectionThread.start();
WebSocketService.instance = this;
}
@Override
public void onDestroy() {
super.onDestroy();
this.socket.disconnect();
WebSocketService.instance = null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
private void initWrappers() {
final IOCallback callbackReference = this.ioCallback;
final SocketIO socketReference = this.socket;
this.socketWrapper = new WebSocket() {
@Override
public void emit(String event, Object... args) {
socketReference.emit(event, args);
}
@Override
public void disconnect() {
socketReference.disconnect();
}
};
this.connectionThread = new Thread(new Runnable() {
@Override
public void run() {
socketReference.connect(callbackReference);
}
});
}
public void runOnConnect(Runnable connectHandler) {
this.connectHandler = connectHandler;
}
public void runOnDisconnect(Runnable disconnectHandler) {
this.disconnectHandler = disconnectHandler;
}
public void runWhenConnected(Runnable runnable) {
if (this.isConnected() && (runnable != null))
runnable.run();
else
this.runOnConnect(runnable);
}
public void registerHandler(String event, WebSocketEventHandler handler) {
List<WebSocketEventHandler> handlersList;
if (eventHandlers.containsKey(event))
handlersList = eventHandlers.get(event);
else
eventHandlers.put(event, handlersList = new ArrayList<WebSocketEventHandler>());
handlersList.add(handler);
}
public void unregisterHandler(String event, WebSocketEventHandler handler) {
if (!eventHandlers.containsKey(event))
return;
List<WebSocketEventHandler> handlersList = eventHandlers.get(event);
handlersList.remove(handler);
}
public void unregisterHandlers(String event) {
if (!eventHandlers.containsKey(event))
return;
List<WebSocketEventHandler> handlersList = eventHandlers.get(event);
eventHandlers.clear();
eventHandlers.remove(event);
}
public void unregisterAllHandlers() {
eventHandlers.clear();
}
private class CallbackStub implements IOCallback {
@Override
public void onDisconnect() {
if (WebSocketService.this.disconnectHandler != null)
WebSocketService.this.disconnectHandler.run();
}
@Override
public void onConnect() {
if (WebSocketService.this.connectHandler != null)
WebSocketService.this.connectHandler.run();
}
@Override
public void onMessage(String data, IOAcknowledge ack) { }
@Override
public void onMessage(JSONObject json, IOAcknowledge ack) { }
@Override
public void on(String event, IOAcknowledge ack, Object... args) {
if (!WebSocketService.this.eventHandlers.containsKey(event)) {
Log.i("WEBSOCKET-SERVICE", event + " unhandled");
return;
}
List<WebSocketEventHandler> handlers = WebSocketService.this.eventHandlers.get(event);
for (WebSocketEventHandler handler : handlers)
handler.onEvent(WebSocketService.this.socketWrapper, args);
}
@Override
public void onError(SocketIOException socketIOException) {
Log.e("SOCKET-IO", socketIOException.getMessage(), socketIOException);
}
}
}
編輯:
- 的WebSocketService 構造函數和的onCreate永遠不會調用。
- 此外,無論是否使用意圖過濾器都會發生相同的情況。
- 我無法使用綁定,因爲即使活動終止,我也需要該服務繼續運行。
- runWhenConnected不在主線程中調用。但是,如果這是一個例外將會提出。
好吧,我不知道onCreate是打電話按順序編輯。它現在有效。 – Totem 2014-11-23 20:40:36