【问题标题】:Return network SQL result into main UI thread in Android将网络 SQL 结果返回到 Android 中的主 UI 线程
【发布时间】:2015-07-11 21:23:42
【问题描述】:

我正在为 Android 中的主 (UI) 线程寻找一种方法来获取我对网络 SQL 服务器运行的 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 部分不能是实际的wait(),因为这会阻塞 UI 线程并且 Android 不允许这样做,但我正在寻找的是能够只需要调用这个函数来检索结果。

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

任何想法都将不胜感激,因为我已经尝试解决这个问题一段时间了。

【问题讨论】:

  • onPostExecute 总是在主线程上运行。
  • “同时让 UI 线程等待结果”——根据定义,这会阻塞主应用程序(“UI”)线程。当然欢迎您阻塞其他等待 I/O 的线程,但不要阻塞等待 I/O 的主应用程序线程。
  • @BladeCoder 和 @Anand Singh 我非常感谢您对此的想法,但这样做的目的是专门解决在我的整个代码中添加大量 AsyncTask 的需要,这些 AsyncTask 会对网络中的网络造成影响doInBackground 然后在 postExecute 中针对 UI 进行一些处理。

标签: java android multithreading android-asynctask


【解决方案1】:

你不能在一个方法块中做到这一点。你需要某种回调机制。 AsyncTask 本身可能不是最好的框架,但假设你坚持这样做,那么它就像定义一个接口一样简单,在你的 Activity/Fragment/whatever 中实现该接口,并将 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);
        }
    }
}

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

【讨论】:

  • 我一点也不拘泥于AsyncTask。我可以使用任何其他功能,我什至实现了一个可以正常工作的callback 方法。我的目标是找到一种方法来执行这些任务,例如,初始 Activity onCreateonResume 而不必半完成 onCreate 因为我必须等待 callback 开始填充列表或放置文字或显示数字。但我非常感谢你的例子,我很高兴地说我已经有了一些看起来非常相似的东西。
  • 您正在寻找的是一种不阻塞线程(保持 UI 线程运行)同时阻塞该线程(防止 onCreate() 完成)的方法。那显然不可能存在。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-24
    • 2014-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-29
    • 2021-01-27
    • 2013-11-23
    相关资源
    最近更新 更多