我正在启动一个将在后台访问 Xmpp 服务器的项目。 它将保持连接有效并在需要时重新连接 + 执行其他 Xmpp 操作。
我想实现一个类来完成这项工作。
该类必须与其他Services
(Location
...)和BroadcastReceivers
(CONNECTIVITY_CHANGE ....)进行交互。
基本上,Activity 和 Broadcast receivers 将要求 Xmpp 类开始一个 Action ,例如:CONNECT、DISCONNECT、RECONNECT、JOIN CHAT、SEND MESSAGE 等。
第一种方法是将其实现为服务
,但服务在主线程中运行,因此实现是错误的。
其次,我想将它作为一个 IntentService
,因为 onHandleIntent
是异步运行的,然后我就离开了主线程。
但是 onHandleIntent
只运行一次以执行异步任务。所以,
如果我想让一个Activity
执行另一个“ Action ”,我只能发送一个广播事件,我又会陷入主线程问题。
此外,IntentService
并不是真正旨在一直处于“实时”状态。
在 Google 文档中,他们说您需要为每次网络访问运行 AsyncTask
...这是进行网络访问的唯一方法吗...这很可悲。
我查看了 GTalkSMS 中的实现,他们似乎有同样的问题。实际上,他们使用一个带有 ServiceHandler
管理的 Service
,如下所示:
// some stuff for the async service implementation - borrowed heavily from // the standard IntentService, but that class doesn't offer fine enough // control for "foreground" services. private static volatile Looper sServiceLooper; private static volatile ServiceHandler sServiceHandler; private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { onHandleIntent((Intent) msg.obj, msg.arg1); } }
最佳答案
好吧,似乎唯一的方法就是创建一个有自己线程的服务。
Vogella 网站描述了一种在 AndroidManifest 中设置服务的方法:
"4. Services in separate processes"
<service
android:name="WordService"
android:process=":my_process"
android:icon="@drawable/icon"
android:label="@string/service_name"
>
</service>
另一种方法是像我在最初的帖子中描述的那样手动执行服务处理程序:
public class XmppService extends Service {
public final static String ACTION_CONNECT = "action.CONNECT";
public final static String ACTION_DISCONNECT = "action.DISCONNECT";
// some stuff for the async service implementation - borrowed heavily from
// the standard IntentService, but that class doesn't offer fine enough
// control for "foreground" services.
private static volatile Looper sServiceLooper;
private static volatile ServiceHandler sServiceHandler;
private long mHandlerThreadId;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(android.os.Message msg) {
onHandleIntent((Intent) msg.obj, msg.arg1);
}
}
/**
* The IntentService(-like) implementation manages taking the intents passed
* to startService and delivering them to this function which runs in its
* own thread
*
* @param intent
* @param id
*/
void onHandleIntent(final Intent intent, int id) {
// ensure XMPP manager is setup (but not yet connected)
if (Thread.currentThread().getId() != mHandlerThreadId) {
throw new IllegalThreadStateException();
}
String action = intent.getAction();
if(action.equals(XmppService.ACTION_CONNECT)){
// Do Connect
}
else if(action.equals(XmppService.ACTION_DISCONNECT)){
// Do Disconnect
}
}
@Override
public void onCreate() {
super.onCreate();
// Start a new thread for the service
HandlerThread thread = new HandlerThread(SERVICE_THREAD_NAME);
thread.start();
mHandlerThreadId = thread.getId();
sServiceLooper = thread.getLooper();
sServiceHandler = new ServiceHandler(sServiceLooper);
}
}
关于android - 实现网络类(class)的最佳选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19929952/