我正在启动一个将在后台访问Xmpp服务器的项目。 它将保持连接活动并在需要时重新连接+执行其他Xmpp操作。
我想实现一个类来完成这项工作。
该课程必须与其他Services
(Location
...)和BroadcastReceivers
(CONNECTIVITY_CHANGE ....)进行互动。
基本上,活动和广播接收器将要求Xmpp类开始一个动作,如:CONNECT,DISCONNECT,RECONNECT,JOIN CHAT,SEND MESSAGE等。
第一种方法是将其实现为Service
,但服务在主线程中运行,因此实现错误。
其次,我想将其设为IntentService
,因为onHandleIntent
运行异步,然后我不在主线程中。
但onHandleIntent
只运行一次以执行异步任务。所以,
如果我想要Activity
执行另一个“动作”,我只能发送一个广播事件,我将再次陷入主线程问题。
此外,IntentService
并非真正意图一直“活着”。
在Google文档中,他们说您需要为每个网络访问运行AsyncTask
...这是进行网络访问的唯一方法......这非常难过。
我看了一下GTalkSMS中的实现,他们似乎也遇到了同样的问题。实际上,他们使用Service
ServiceHandler
管理,如下所示:
// 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); } }
答案 0 :(得分:1)
嗯,似乎唯一的方法是创建一个拥有自己的线程的服务。
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);
}
}