我是Android开发的新手,我希望我的应用程序能够检测套接字事件,即使应用程序未通过后台服务处于活动状态(因此我可以执行推送通知,例如,如果有一个套接字事件触发的新消息Whatsapp和其他人如何做到这一点)。
我实现了后台服务和一个启动服务的应用程序类,但是在后台服务中将套接字事件作为Runnable任务放在哪里以及如何放置。
我修改了下面的socket.io android chat项目示例并添加了服务和应用程序类。
ChatApplication.java
package com.github.nkzawa.socketio.androidchat;
import android.app.Application;
import android.content.Intent;
import android.content.res.Configuration;
import io.socket.client.IO;
import io.socket.client.Socket;
import java.net.URISyntaxException;
public class ChatApplication extends Application {
@Override
// called when the application is starting, before any other application objects have been created
public void onCreate() {
super.onCreate();
// represents our background service
Intent background = new Intent(this, SocketBackgroundService.class);
startService(background);
}
private Socket mSocket;
{
try {
mSocket = IO.socket(Constants.CHAT_SERVER_URL);
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
public Socket getSocket() {
return mSocket;
}
}
SocketBackgroundService.java
package com.github.nkzawa.socketio.androidchat;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class SocketBackgroundService extends Service {
private boolean isRunning;
private Thread backgroundThread;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
this.isRunning = false;
this.backgroundThread = new Thread(myTask);
}
private Runnable myTask = new Runnable() {
@Override
public void run() {
// do something in here
Log.i("INFO", "SOCKET BACKGROUND SERVICE IS RUNNING");
//TODO - how to handle socket events here?
//How do I do something like mSocket.on(Socket.EVENT_CONNECT,onConnect); here?
}
};
@Override
public void onDestroy() {
this.isRunning = false;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if( !this.isRunning) {
this.isRunning = true;
this.backgroundThread.start();
}
return START_STICKY;
}
}
答案 0 :(得分:4)
如果您的应用程序停止后仍需要套接字。将套接字移动到后台服务,然后您可以在服务中添加套接字事件。
答案 1 :(得分:3)
您在主线程上打开套接字。不要在主线程上打开套接字连接,它会给你ANR(应用程序没有响应)错误,这是由于UI线程上的大量繁重工作而发生的。它会阻止UI线程超过5秒。所以我建议你在服务中的线程上打开套接字连接 以下是使用普通套接字的示例:
为套接字通信创建单独的类
public class SocketBackgroundService extends Service {
private SocketThread mSocketThread;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
mSocketThread = SocketThread.getInstance();
}
@Override
public void onDestroy() {
//stop thread and socket connection here
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mSocketThread.startThread) {
} else {
stopSelf();
}
return START_STICKY;
}
}
public class SocketThread extends Thread {
private static SocketThread mSocketThread;
private SocketClient mSocketClient;
private SocketThread() {
}
// create single instance of socket thread class
public static SocketThread getInstance() {
if (mSocketThread == null)//you can use synchronized also
{
mSocketThread = new SocketThread();
}
return mSocketThread;
}
public boolean startThread() {
=new SocketClient();
if (socketClient.isConnected()) {
mSocketThread.start()
return true;
}
return false;
}
@Override
public void run() {
super.run();
while (mSocketClient.isConnected()) {
// continue listen
}
// otherwise remove socketClient instance and stop thread
}
public class SocketClient {
//write all code here regarding opening, closing sockets
//create constructor
public SocketClient() {
// open socket connection here
}
public boolean isConnected() {
return true;
}
}