开发者

AsyncTask's doInBackground method blocking UI thread

开发者 https://www.devze.com 2023-03-21 06:25 出处:网络
I am loading some JSON data in an AsyncTask, as I want to show the download progress in the UI. The download is working fine and the publishProgress method gets called regularly (every 100 JSON object

I am loading some JSON data in an AsyncTask, as I want to show the download progress in the UI. The download is working fine and the publishProgress method gets called regularly (every 100 JSON objects), but onProgressUpdate and onPostExecute do not get actually executed, until all background operations are done (i.e. all calculations which require the doInBackground result).

Log looks roughly like this:

AsyncTaskCaller.downloadWithAsyncTask: executing AsyncTask

MyAsyncTask.onPreExecute: AsyncTask started

MyAsyncTask.doInBackground: Download 0%
MyAsyncTask.doInBackground: Download 10%
...
MyAsyncTask.doInBackground: Download 90%
MyAsyncTask.doInBackground: Download 100%

AsyncTaskCaller.processResult: Results processed

// all background calculations finished

MyAsyncTask.onProgressUpdate: Download 0%
MyAsyncTask.onProgressUpdate: Download 10%
...
MyAsyncTask.onProgressUpdate: Download 90%
MyAsyncTask.onProgressUpdate: Download 100%

MyAsyncTask.onPostExecute: AsyncTask ended

MyActivity.updateUiAfterDownload

This is how my code is calling the data:

MyActivity:

final Runnable mSynchroniseContacts = new Runnable() {
    public void run() {
        /** get oAuth tokens for synchronisation */
        MyApp app = (MyApp) getApplication();
        OpenAuthTokens myTokens = app.getAccessTokens();

        // mockup code to load contacts
        MyContact[] contacts = AsyncTaskCaller.loadContacts(myTokens, MyActivity.this);
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.synchronisation_activity);

    statusText = (TextView) findViewById(R.id.synchronisation_status_text);

    mSynchroniseContacts.run();
}

AsyncTaskCaller:

private static JSONArray records = null;

public static MyContact[] loadContacts(OpenAuthTokens myTokens, Context context) {
    MyAsyncTask contactDownloader = new MyAsyncTask(context, myTokens) {
        @Override
        protected void onPostExecute(JSONArray result) {
            super.onPostExecute(result);

            records = result;开发者_开发知识库 // assigning result to static class variable, to avoid calling contactDownloader.get(), which apparently blocks the UI thread according to http://stackoverflow.com/questions/5583137/asynctask-block-ui-threat-and-show-progressbar-with-delay
        }
    };

    contactDownloader.execute(url);

    // wait until contacts are downloaded
    while(!SforceContactDownloadTask2.isFinished()) {
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            Log.e(TAG, e.getCause() + " - " + e.getMessage());
            e.printStackTrace();
        }
    }   

    // some code to convert JSONArray records into MyContact[] myContacts

    return myContacts;
}

MyAsyncTask (code to log as above was not explicitly pasted):

@Override
protected void onPreExecute() {
    finished = false;
}

@Override
protected void onPreExecute() {
    finished = false;
}

@Override
protected JSONArray doInBackground(String... url) {

    StringBuffer dataString = new StringBuffer();

    try {

        boolean isOnline = ConnectivtiyChecker.isInternetAvailable(context);

        if (isOnline) {

            /** send as http get request */
            URL urlObject = new URL(url[0]);
            HttpURLConnection conn = (HttpURLConnection) urlObject.openConnection();
            conn.addRequestProperty("Authorization", "OAuth " + myTokens.get_access_token());

            /** prepare response reader */
            JSONArray records = null;
            byte data[] = new byte[MAX_BUFFER_SIZE];
            int currentByteReadCount = 0;
            InputStream stream = null;
            BufferedInputStream input = null;

            try {
                /** get response input stream */
                stream = conn.getInputStream();
                input = new BufferedInputStream(stream);

                /** read response from input stream */
                while ((currentByteReadCount = input.read(data)) != -1) {
                    String readData = new String(data, 0, currentByteReadCount);
                    dataString.append(readData);

                    //code to figure progress out

                    // publishing the progress (every 5%)...
                    if (progress % (total / 20) == 0 ) {
                        publishProgress((int)(progress * 100 / total));
                    }
                }
            } catch (Exception e) {
                Log.e(TAG, e.getCause() + " - " + e.getMessage());
                e.printStackTrace();
            } finally {
                // close streams
                if (input != null) {
                    input.close();
                }
                if (stream != null) {
                    stream.close();                     
                }
            }

            /** transform response into JSONArray */
            String result = dataString.toString();
            JSONObject object = (JSONObject) new JSONTokener(result).nextValue();
            records = object.getJSONArray("records");

            return records;
        } else {
            return null;
        }
    } catch (Exception e) {
        Log.e(TAG, e.getCause() + " - " + e.getMessage());
        e.printStackTrace();
        return null;
    }
}

@Override
protected void onProgressUpdate(Integer... changed) {
    Log.d(TAG, "Download " + changed[0] + "%");
}

@Override
protected void onPostExecute(JSONArray result) {
    finished = true;
}

public static boolean isFinished() {
    return finished;
}

Any ideas how to de-block the UI?


You appear to be calling Thread.sleep() on the main application thread. Do not do this. Please write your application to be properly asynchronous.

0

精彩评论

暂无评论...
验证码 换一张
取 消