实现网络类的最佳选择

时间:2013-11-12 13:02:43

标签: android multithreading android-asynctask xmpp

我正在启动一个将在后台访问Xmpp服务器的项目。 它将保持连接活动并在需要时重新连接+执行其他Xmpp操作。

我想实现一个类来完成这项工作。 该课程必须与其他ServicesLocation ...)和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);
    }
}

1 个答案:

答案 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);

    }
}