Android 实现网络类的最佳选择
我正在启动一个在后台访问Xmpp服务器的项目。 它将保持连接处于活动状态,并在需要时重新连接+执行其他Xmpp操作 我想实现一个类来完成这项工作。 该课程必须与其他Android 实现网络类的最佳选择,android,multithreading,android-asynctask,xmpp,Android,Multithreading,Android Asynctask,Xmpp,我正在启动一个在后台访问Xmpp服务器的项目。 它将保持连接处于活动状态,并在需要时重新连接+执行其他Xmpp操作 我想实现一个类来完成这项工作。 该课程必须与其他服务(位置…)和广播接收器(连接改变…)交互。 基本上,活动和广播接收器将要求Xmpp类启动一个动作,如:连接、断开连接、重新连接、加入聊天、发送消息等 第一种方法是将其实现为服务,但服务在主线程中运行,因此实现是错误的 其次,我想把它变成一个IntentService,因为onHandleIntent是异步运行的,然后我就离开了主线
服务
(位置
…)和广播接收器
(连接改变…)交互。
基本上,活动和广播接收器将要求Xmpp类启动一个动作,如:连接、断开连接、重新连接、加入聊天、发送消息等
第一种方法是将其实现为服务
,但服务在主线程中运行,因此实现是错误的
其次,我想把它变成一个IntentService
,因为onHandleIntent
是异步运行的,然后我就离开了主线程
但是,onHandleIntent
只运行一次以执行异步任务。所以
如果我希望一个活动
执行另一个“操作”,我只能发送一个广播事件,我将再次陷入主线程问题。
此外,IntentService
并非一直都是“实时”的
在谷歌文档中,他们说你需要为每个网络访问运行AsyncTask
。。。这是进入网络的唯一方法吗。。。这真是太可悲了
我查看了GTalkSMS中的实现,他们似乎也有同样的问题。实际上,他们将服务
与服务处理程序
管理一起使用,如下所示:
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);
}
}
看来唯一的方法就是创建一个有自己线程的服务 Vogella网站介绍了在AndroidManifest中设置服务的方法:
<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);
}
}