0

I have problem with asynctasks blocking UI when task download metafile from FTP server.

[Main.class] FragmentActivity

@Override
    public void onClick(View view) {

        TestSettings(); // TODO do usunięcia z kodu
        String password = this.password.getText().toString();

        boolean isConnected = false;

        try {
            isConnected = new TaskConnect(new ProgressDialog(getActivity().getApplicationContext()), password).execute().get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        if (isConnected) {

            Toast.makeText(getActivity(), "Connected", Toast.LENGTH_LONG).show();

            try {

                boolean isListDownloaded = new TaskDownloadFilesList(new ProgressDialog(getActivity().getApplicationContext())).execute().get();

                if(isListDownloaded) {
                    getFragmentManager().beginTransaction()
                            .replace(R.id.container, new FragmentList(client.getList()))
                            .addToBackStack(this.getTag())
                            .commit();
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }


        }


    }

[TaskDownloadFilesList.class] - AsyncTask

public class TaskDownloadFilesList extends AsyncTask <Boolean, Boolean, Boolean> {

    private static final FTP CLIENT = FTP.getInstance();
    private static ProgressDialog dialog = null;
    private static boolean isDownloaded = false;

    public TaskDownloadFilesList(ProgressDialog dialog) { this.dialog = dialog; }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        dialog.setMessage("Downloading list");
        dialog.setCancelable(false);
    }

    @Override
    protected Boolean doInBackground(Boolean... booleans) {

        dialog.show();

        if(CLIENT.isConnected()) {
            try { isDownloaded = CLIENT.checkList(); }
            catch (IOException e) { e.printStackTrace(); }
        }

        return false;
    }

    @Override
    protected void onPostExecute(Boolean aBoolean) {
        super.onPostExecute(aBoolean);
        dialog.dismiss();
    }

    public boolean getResult() {
        return isDownloaded;
    }

In fact I use TaskConnect to connect to the FTP Server this task not freeze UI.

AruLNadhaN
  • 2,808
  • 5
  • 24
  • 42
Nerus
  • 167
  • 1
  • 2
  • 13

2 Answers2

1

You are calling AsyncTask's get() which blocks the calling Thread until it finishes. Remove the get() calls.

Emmanuel
  • 13,083
  • 4
  • 39
  • 53
  • I use Task to connecting and its not blocked UI, how to get information when job is done ? – Nerus Jan 26 '14 at 16:19
  • the `get()` will block the calling `Thread`. What you want to do is call `execute()`, do the long running task in `doInBackground()` and return the value that will be passed to `onPostExecute()` so you can update the UI `Thread` – Emmanuel Jan 26 '14 at 16:21
  • @Nerus information when job is done can be obtained in `onPostExecute()` method of asynctask, look at my answer. – S.Thiongane Jan 26 '14 at 16:22
  • As Emmanuel said, `.get()` blocks the `UI`. If the task is an inner-class of the `Activity` then you can call an `Activity` function, update a variable, or whatever you need in `onPostExecute()` which will be called when `doInBackground()` finishes. If the `AsyncTask` is a separate file then [see this answer about using an interface](http://stackoverflow.com/questions/18517400/inner-class-can-access-but-not-update-values-asynctask/18517648#18517648) to pass a callback from `onPostExecute()` when the task finishes – codeMagic Jan 26 '14 at 16:26
  • @Emmanuel : `onPostExecute(Result), invoked on the UI thread after the background computation finishes.` from [here](http://developer.android.com/reference/android/os/AsyncTask.html) – S.Thiongane Jan 26 '14 at 16:27
  • 1) I don't need to look at your answer to provide one which is so obvious. Look at the two answers and see if they are identicals 2) I don't need to redirect you to my answer, it's just because i gave him directly what he wanted, oppositly to you (your solution is between comments, not in your answer). – S.Thiongane Jan 26 '14 at 18:31
1

Instead of using get() method of AsyncTask, you may wait that task finish in doInBackground() method then add the code you want to execute in onPostExecute().

S.Thiongane
  • 6,883
  • 3
  • 37
  • 52