android - 实现网络类(class)的最佳选择

标签 android multithreading android-asynctask xmpp

我正在启动一个将在后台访问 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/

相关文章:

android - Google Play 服务和 Unity3D 错误

javascript - Android 开发 - 要引用一个字段,是否需要使用 "this"?

java - Android Studio 中的错误 play-services-maps :17. 0.1

java - NotifyAll,IllegalMonitorStateException

c - 使用一个信号量实现两个线程的线程同步

c++ - Ubuntu virtualbox 中的 OpenGL 多线程示例

Android - AsyncTask 未执行

java - AndroidnotifyDataSetChanged导致解析idx 1 Illegal State Exception

Android RelativeLayout 在另一个元素边框上对齐元素

android - 使用asynctask调用android中的函数