Java 在Android中进行网络呼叫以响应UI事件

Java 在Android中进行网络呼叫以响应UI事件,java,android,multithreading,networking,Java,Android,Multithreading,Networking,我正在构建一个Android应用程序,它需要对UI事件进行某些网络调用。不过,我正在努力寻找一种优雅的方式,从UI回调发送这些调用。AsyncTask并不适合,因为我只想发出调用——任何响应都将由我的接收方代码中的回调处理。同样,仅仅为了执行一个网络调用而生成一个新线程似乎是浪费和糟糕的做法,特别是考虑到在某些情况下,当用户与UI交互时,每秒会有很多很多调用 注意:我所说的“网络调用”实际上是指通过UDP DatagramSocket发送一些字节 我曾考虑过让一个网络TX线程具有一个“发送队列”

我正在构建一个Android应用程序,它需要对UI事件进行某些网络调用。不过,我正在努力寻找一种优雅的方式,从UI回调发送这些调用。AsyncTask并不适合,因为我只想发出调用——任何响应都将由我的接收方代码中的回调处理。同样,仅仅为了执行一个网络调用而生成一个新线程似乎是浪费和糟糕的做法,特别是考虑到在某些情况下,当用户与UI交互时,每秒会有很多很多调用

注意:我所说的“网络调用”实际上是指通过UDP DatagramSocket发送一些字节

我曾考虑过让一个网络TX线程具有一个“发送队列”连续循环,UI线程可以向其发送消息,但这似乎是一种难以置信的CPU周期浪费,因为在需要进行调用的时间之间可能有几秒钟的间隔


我有一种感觉,优雅的解决方案是上述“循环TX线程”思想的结合,但是使用了锁对象,因此除非有新数据要发送,否则它不会循环-但我对并发、锁等方面不是很有经验,所以我希望这里的人能给我指出正确的方向。任何帮助都将不胜感激。提前感谢:)

在后台,您可以使用这样的ThreadPoolExecutor。我用专门的课程来做这个。你把runnables贴给执行人

public class RemoteConnections {

//Variables and constants to manange the threadpool
private final int KEEP_ALIVE_TIME = 1;
private final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
private final int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
private ThreadPoolExecutor mThreadpool;

private RemoteRepository(Application application) {
    mApplication = application;
    //initialize the threadpool for networking
    final BlockingQueue<Runnable> mQueue = new LinkedBlockingQueue<Runnable>();
    mThreadpool = new ThreadPoolExecutor(NUMBER_OF_CORES, NUMBER_OF_CORES, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT.SECONDS, mQueue);
}


public void loadWhatEver() {

    mThreadpool.execute(new Whatever());
}


private class Whatever implements Runnable {
    public  Whatever(//setup whatever you need perhaps your callback listener) {
        mListener = listener;
    }

    @Override
    public void run() {
        //do your downloading here
        //make the callback to the listener
    }    
}
公共类远程连接{
//管理线程池的变量和常量
私有最终整数保持活动时间=1;
私人最终时间单位保持活动时间单位=TimeUnit.SECONDS;
私有最终整数\u OF_CORES=Runtime.getRuntime().AvailableProcessor();
私有线程池执行器mThreadpool;
专用远程存储库(应用程序){
应用=应用;
//初始化用于联网的线程池
final BlockingQueue MQUE=新的LinkedBlockingQueue();
mThreadpool=新的ThreadPoolExecutor(内核数、内核数、保持活动时间、保持活动时间单位秒、MQUE);
}
公共void loadwhere(){
执行(newwhatever());
}
实现Runnable的私有类{
public which(//设置您需要的任何内容,可能是回调侦听器){
mListener=监听器;
}
@凌驾
公开募捐{
//你在这里下载吗
//对侦听器进行回调
}    
}

在活动或片段中,只要在事件发生时调用remote.loadwhere()。

我不确定您所说的是什么类型的事件,但如果您是指单击按钮,那么它可以像onClick{sendoutcallmethod()}一样简单@如果您从UI线程执行网络I/O操作,KvdLingen Android将强制使您的应用程序崩溃,很遗憾,这无法正常工作:(答案是AsyncTask或Thread。这是唯一的答案。看起来你已经知道了,那么你为什么会在这里?如果你真的担心请求的数量(这也有序列化请求的好处),你可以将它们排队并发送到一个线程来完成所有的联网工作)或者,从您的评论中,您可能不知道如何使用请求队列。您不需要为传入的请求旋转轮询,您可以在请求到来之前一直睡眠。这是标准,如果您使用CPU周期旋转,那么您就做错了。在安卓上,它可以简单到使用HandlerThread,为您完成所有这些,然后发送消息给那个处理者打电话。