Java 在Android中将网络SQL结果返回到主UI线程

Java 在Android中将网络SQL结果返回到主UI线程,java,android,multithreading,android-asynctask,Java,Android,Multithreading,Android Asynctask,我正在寻找一种方法,让Android中的主(UI)线程获得针对网络SQL server运行的SQL查询的结果 我知道你的第一个答案可能是大喊“ASYNCTASK!!!”,但请耐心听我说,我会解释为什么这不是我想要的 通过使用AsyncTask,我已经可以运行查询并检索结果,而不会出现任何问题。 我所寻找的是一种能够将所有这些捆绑到一个调用中的方法,该调用将返回AsyncTask的结果。请参见下面的伪代码: public static Object returnQueryResults() {

我正在寻找一种方法,让Android中的主(UI)线程获得针对网络SQL server运行的SQL查询的结果

我知道你的第一个答案可能是大喊“ASYNCTASK!!!”,但请耐心听我说,我会解释为什么这不是我想要的

通过使用AsyncTask,我已经可以运行查询并检索结果,而不会出现任何问题。 我所寻找的是一种能够将所有这些捆绑到一个调用中的方法,该调用将返回AsyncTask的结果。请参见下面的伪代码:

public static Object returnQueryResults()
{
    // Perhaps show a "Loading" dialog

    // Start the AsyncTask that will query the SQL server

    // Here is the important part, somehow WAIT for the result 
    // to be returned or timed out or cancelled or whatever

    // return the result gotten by the AsyncTask
}
我知道并完全理解函数的等待部分不能是实际的
WAIT()
,因为这会阻塞UI线程,Android不允许这样做,但我想要的是能够只调用这个函数来检索结果


在我看来,问题似乎是如何将AsyncTask的
postExecute
的结果传递给主UI线程,同时让UI线程等待结果


如果您有任何想法,我将不胜感激,因为我已经断断续续地尝试解决这个问题一段时间了。

您不能在一个方法块中完成它。您需要某种回调机制。AsyncTask本身可能不是实现这一点的最佳框架,但假设您坚持这一点,那么它只需定义一个接口,在活动/片段/任何内容中实现该接口,并将AsyncTask的引用传递给实现者(例如在构造函数中)

AsyncTask本身可能不是最好的框架

public class MyAsyncTask extends AsyncTask<String, Void, MyQueryResult> {

    interface MyQueryResultCallback {
        void onQueryResult(MyQueryResult result);
    }

    // assuming you may implement the interface in an Activity/Fragment,
    // you probably shouldn't keep a strong reference to it because Android
    // can destroy and create new instances of those.
    private WeakReference<MyQueryResultCallback> callbackRef;

    public MyAsyncTask(MyQueryResultCallback callback) {
        callbackRef = new WeakReference<MyQueryResultCallback>(callback);
    }

    /* doInBackground omitted for brevity */

    @Override
    protected void onPostExecute(MyQueryResult result) {
        MyQueryResultCallback callback = callbackRef.get();
        if (callback != null) {
            callback.onQueryResult(result);
        }
    }
}
公共类MyAsyncTask扩展了AsyncTask{
接口MyQueryResultCallback{
查询结果无效(MyQueryResult结果);
}
//假设您可以在活动/片段中实现接口,
//您可能不应该保留对它的强烈引用,因为Android
//可以销毁并创建这些实例的新实例。
私有WeakReference callbackRef;
公共MyAsyncTask(MyQueryResultCallback){
callbackRef=新的WeakReference(回调);
}
/*为简洁起见,省略了doInBackground*/
@凌驾
受保护的void onPostExecute(MyQueryResult结果){
MyQueryResultCallback callback=callbackRef.get();
if(回调!=null){
callback.onQueryResult(结果);
}
}
}

您可以创建一个方法来显示加载指示器并启动任务,然后您的
onQueryResult()
实现将取消加载指示器并更新UI。

AsyncTask在UI线程上自动运行onPostExecute(),因此您无需做任何事情,您可以使用该方法填充UI。例如,请小心取消onDestroy()中的AsyncTask,以避免在活动结束时传递结果。

onPostExecute始终在主线程上运行。“同时让UI线程等待结果”——根据定义,这将阻止主应用程序(“UI”)线程。当然欢迎您阻止其他等待I/O的线程,但不要阻止等待I/O的主应用程序线程。@BladeCoder和@Anand Singh我非常感谢您的想法,但这一点是为了具体解决以下问题:在
doInBackground
中,我需要在整个代码中添加一些异步任务块,这些异步任务块会对网络做一些事情,然后在
postExecute
中对UI做些事情。我一点也不拘泥于
AsyncTask
。我可以使用任何其他函数,我甚至实现了一个运行良好的
回调方法。我的目标是找到一种方法来执行这些任务,例如,初始活动
onCreate
onResume
,而不必完成一半onCreate,因为我必须等待
回调
来开始填充列表、放置文本或显示数字。但是我非常欣赏你的例子,我很高兴地说,我已经有了一些非常相似的东西。你要寻找的是一种方法,既不阻止线程(保持UI线程运行),同时又阻止该线程(防止
onCreate()
完成)。这显然不可能存在。