解除UI线程,同时避免NetworkOnMainThread错误

时间:2015-03-22 14:40:50

标签: java android eclipse multithreading android-studio

我有一个函数,我必须从服务器获取代码并返回其操作。

这是代码

public String getResult
{
        // Call to your backend

        try {
            String url = String.format(Constants.LOGIN_URL,
                    URLEncoder.encode(countryCode + phoneNumber, "UTF-8"),
                    URLEncoder.encode(smsCode, "UTF-8"),
                    URLEncoder.encode(Constants.WHERE_API_KEY, "UTF-8"));

            while (new LoginToServer().execute(url).get());

        }catch (Exception e)
        {}

return result; // Result will be saved to class in onPostExecute()

如果检索结果时出错,则我的LoginToServer返回true。现在,这显然会删除NetworkOnMainThread的异常,但它会阻止UI。

由于函数是由某些sdks调用的,因此我必须使httpconnection完成,然后完成传递结果。

如何在执行此代码时使UI解除阻止?

同样,我无法将整个函数称为aysnc,因为该函数将由内部的大多数sdk函数调用,并且它们将在Async中显然不会调用它

3 个答案:

答案 0 :(得分:0)

  

如何在执行此代码时使UI解除阻止?

摆脱get()并处理onPostExecute()的{​​{1}}中网址的结果。

或者,用常规线程替换AsyncTask,并在后台线程上调用AsyncTask,并在它们之间使用适当的同步逻辑。这将是浪费,因为你不应该在这里需要两个线程,但它会使主要的应用程序线程脱离混合。

你根本无法在主应用程序线程上调用getResult(),阻塞调用,并且阻塞调用不会阻塞。

答案 1 :(得分:0)

您必须使用类似AsyncTask的内容。当然,你可以通过这种方式从SDK /库的用户那里抽象出来,这样他们就可以调用一个doLogin()函数,然后在这个函数中传递一个回调接口,当登录结果返回时将调用该接口。

public void doLogin(final MyCallback callback) {

    new AsyncTask<URL, Void, Boolean> {
        protected Boolean doInBackground(URL... urls) {
            // make network calls to login in this "background" thread.
            loginSuccess = true;
            return loginSuccess;
        }

        protected void onPostExecute(Boolean loginSuccess) {
           callback.onResult(loginSuccess);
        }
    }.execute();
}

注意这个doLogin方法如何立即返回,并且仅在网络调用完成后调用callback(可能在几秒钟之后)。这就是你如何进行非阻塞工作,并保持主线程和应用程序UI响应。

答案 2 :(得分:0)

异步线程用于耗时的操作(网络可能很慢/服务器可能很慢/客户端服务器之间的跳数很多等。)

在从服务器获取数据时,不阻止UI线程运行,是异步调用的用途。

您可以从Asyctasks doInBackground()方法调用此函数。

UI线程将正常运行并在PostExecute()回调中处理结果。

您面临的挑战是什么?当然有几个函数可以在异步中调用它。要同步异步调用吗?您可以使用Executor

查看原生Android异步类或LoopJ

等库