0

I have 2 Activities, A & B. Starting B from A causes a very long (2-4 seconds) transition time, so I've decided to use an AsyncTask to load a heavy layout into a viewFlipper which is in the contentView of B in order to free up the UI thread. In other words, what I wanted to acheive is the following:

  1. User presses a button and an intent starting B is called. The UI switches to B's contentView.
  2. In the background, an AsyncTask is loading a heavy layout in a class called "welcomeToContentView ".
  3. Once finished, the layout is then added to B's viewFlipper.

Starting B from A:

Handler h = new Handler();
    h.postDelayed(new Runnable() {
        @Override
        public void run() {
            Intent intent = new Intent(getBaseContext(), B.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); 
            intent.putExtras(b);
            startActivity(intent);
            A.this.overridePendingTransition(R.anim.left_in, R.anim.left_out);
        }
    }, 200);

In B, set contentView to "content_view" during "onCreate()":

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
    }
    setContentView(R.layout.content_view);
    viewFlipper = (ViewFlipper) findViewById(R.id.view_flipper);
    new setWelcomeToLayoutTask(location, false).execute();
}

The AsyncTask class is as follows:

private class setWelcomeToLayoutTask extends AsyncTask<Void, Void, Boolean> {
        private final MyLocation location;
        private final boolean animate;

    public setWelcomeToLayoutTask(MyLocation location, boolean animate) {
        this.location = location;
        this.animate= animate;
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        Looper.prepare();
        if (welcomeToContentView == null) {
        // Heavy layout loading
            welcomeToContentView = (ViewLocationContentView.WelcomeToContentView)                        ViewLocationContentView.getContentView(B.this, "welcome_to");
            welcomeToContentView.setDescriptors(location);
            welcomeToContentView.setWelcomeToItems(location);                
        }
        return true;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        ViewLocationActivity.this.addWelcomeToLayout(animate);
    }
}

private void addWelcomeToLayout(Boolean animate) {
    viewFlipper.addView(welcomeToContentView.getContentLayout(), animate);
}

Now, when pressing the button which should cause B's contentView to appear instantaneously, while waiting for the AsyncTask to load the layout into the viewFlipper, what happens is the the UI is stuck in Activity A, and only once all layouts have been loaded into B's contentView does the UI change. How do I make the program switch to B's contentView immediately after the button is pressed and load the layout in the background?

Jimmy Lee Jones
  • 785
  • 4
  • 18
  • I don't think this is an issue, but why do you use `Looper.prepare()` inside `doInBackground`? Have you tried to remove it? – Max Zavernutiy Apr 22 '16 at 09:18
  • I'm also pretty sure it's not an issue. I'm using it because I got an error without it since there is a Handler somewhere along the way – Jimmy Lee Jones Apr 22 '16 at 09:29
  • I have an idea, that this looper actually makes your `doInBackground` to run in UI thread. – Max Zavernutiy Apr 22 '16 at 09:40
  • After reading some `Looper` in `doInBackground` issues http://stackoverflow.com/questions/4187960/asynctask-and-looper-prepare-error http://stackoverflow.com/questions/9357513/cant-create-handler-inside-thread-that-has-not-called-looper-prepare-with-asy I think that you are trying to run UI task in background, and `Looper` made it work, but it freezes the UI thread – Max Zavernutiy Apr 22 '16 at 09:46
  • Even if that's the case, I still feel like I'm missing something fundamental here: Why is there no linearity in the inflation of views? It should first of all switch to B's contentView and only then deal with the long inflation time of AsynTasks "doInBackground", but instead the UI thread waits until ALL views have finished inflating. This makes no sense to me – Jimmy Lee Jones Apr 22 '16 at 11:07

0 Answers0