简体   繁体   English

适用于Android的AsyncTask中的doInBackground

[英]doInBackground in AsyncTask for Android

I want to know that if a doInBackground method of a AsyncTask calls a method, for example XYZ() , Is that method also executed asynchronously? 我想知道,如果AsyncTaskdoInBackground方法调用一个方法,例如XYZ() ,那么该方法是否也异步执行?

Can we make changes to the UI in XYZ() in such a situation? 在这种情况下,我们可以在XYZ()中对UI进行更改吗? Will it make the UI unresponsive? 它会使用户界面无响应吗?

I have a method call in doInBackground which is network intensive and requires to download an image from the web. 我在doInBackground有一个方法调用,该方法doInBackground大量网络资源,并且需要从Web下载图像。 The UI becomes unresponsive as soon as the call to that method is made. 一旦对该方法进行调用,UI将变得无响应。 Why? 为什么?

protected String[] doInBackground(String... params)
        {

    String[] response = new String[2];
    Log.v("Background", "I am in background!");

    String url = params[0];
    String VoiceInput = params[1];
    IsCalledOnVoiceInput = VoiceInput;
    Log.v(url,url);
    HttpPost httppost = new HttpPost(url);
    try
    {

        HttpParams p = new BasicHttpParams();
        HttpClient httpclient = new DefaultHttpClient(p);
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        responseBody = httpclient.execute(httppost,
                responseHandler);
        Log.v("Thread", responseBody);

        //Getting background image URL
        JSONObject reader = new JSONObject(responseBody);
        JSONObject coords = reader.getJSONObject("coord");
        loc_latitude = coords.getString("lat");
        loc_longitude = coords.getString("lon");
        String imageURL="";
        /////////////////////////////////////////////////////////////////////////////////
        try
        {
            imageURL = getRandomImageURL(loc_latitude,loc_longitude);
            Log.v("Image URL as recieved from getRandomImageURL", imageURL);
            //Trying to convert Image from the above URL, get it and theh convert it to String
            URL urlOfTheImage = new URL(imageURL);

            bmp = BitmapFactory.decodeStream(urlOfTheImage.openConnection().getInputStream());
            //Image successfully converted to string, ready to pass as a parameter!
            response[0] = "";
        }
        catch(Exception e)
        {
            Toast.makeText(getApplicationContext(),"There seems to be a problem with the application. Please try again later.", Toast.LENGTH_LONG).show();
        }
        Log.v("URL of Random Image",imageURL);

    }

    catch (ClientProtocolException e)
    {
        e.printStackTrace();
    }

    catch (IOException e)
    {
        e.printStackTrace();
    }
    catch (JSONException e)
    {
        e.printStackTrace();

    }

    response[1] = responseBody;
    return response;
}

The method getRandomImageURL and all that code in the try block is network intensive. 方法getRandomImageURLtry块中的所有代码都是网络密集型的。 I can also provide its code. 我也可以提供其代码。

The code executing in the background is run in a separate thread. 在后台执行的代码在单独的线程中运行。 Anything it does, including calling other methods, happens in that thread. 它所做的任何事情(包括调用其他方法)都在该线程中发生。 Since this is not the UI thread, it's not valid to make UI calls. 由于这不是UI线程,因此进行UI调用无效。 You have to post messages to the UI thread. 您必须将消息发布到UI线程。

Yes, whatever you call within doInBackgroud will run asynchronously. 是的,您在doInBackgroud中调用的任何内容都将异步运行。 And no you shoudn't update UI from background thread for that you have CallBackDefined(onPostExecute). 而且不,您不应该从后台线程更新UI,因为您拥有CallBackDefined(onPostExecute)。 Or if UI update is require you can use runOnUIThread(...) API 或者如果需要更新UI,则可以使用runOnUIThread(...)API

You can make changes to the UI only from the UI thread. 您只能从UI线程对UI进行更改。 In general the doInBackground() is for lengthy operations that do not update the UI or access the UI toolkit. 通常,doInBackground()用于冗长的操作,这些操作不会更新UI或访问UI工具包。 You can periodically publish changes in state that need to be reflected in the UI (eg progress bar showing status of a download operation) by calling publishProgress(). 您可以通过调用publishProgress()定期发布需要反映在UI中的状态更改(例如,进度条显示下载操作的状态)。

Set time out like this... 这样设置超时时间...

HttpPost httppost = new HttpPost(url);
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpResponse response = httpClient.execute(httppost);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM